Contents


Copyright Notice
Copyright Notice for Visual Workbench Help

Information in this document is subject to change without notice. Companies, names, and data used in examples herein are fictitious unless otherwise noted. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without express written permission of Microsoft Corporation.

© 1993 Microsoft Corporation. All rights reserved.

Microsoft is a registered trademark and Windows and Windows NT are trademarks of Microsoft Corporation.


Introduction
Programmer's Reference, Volume 1: Window Management and Graphics Device Interface

Introduction

The Microsoft® Win32 (™)  application programming interface (API) allows applications to exploit the power of 32-bits on the Microsoft® Windows (™)  family of operating systems. Applications written to the Win32 API are scalable on single and multiprocessor systems, and portable to RISC architectures. These manuals document the complete Win32 API including window management, graphics, file I/O, threading, memory management, security and networking.


  Organization of this Manual

Following are brief descriptions of the main parts of this manual.

Part 1, "Window Management," describes the portion of the Win32 API that applications use to create and manage windows. The chapters in this part provide detailed information about windows, messages, message queues, controls, dialog boxes, and other window-management topics.

Part 2, "Graphics Device Interface," describes the portion of the Win32 API that applications use for device-independent graphics. The chapters in this part provide detailed information about device contexts, transformations, metafiles, graphics primitives, bitmaps, and other graphics-related topics.

This manual is intended to describe the purpose of the Win32 API and to explain the operating system concepts behind the API. It also shows how the Win32 functions work together to carry out specific tasks. It does not show how to write, compile, and link programs containing these functions.


About the Microsoft Win32 Programmers Reference
  About the Microsoft Win32 Programmer's Reference

The Microsoft Win32 Programmer's Reference, a set of five volumes, fully describes the Win32 API, including functions and related data types, macros, structures, and messages. The Programmer's Reference is the source for specific information about programming for Windows.

Volumes 1 and 2 describe the purpose of the functions in the Win32 API and explains the concepts and principles behind the functions. These volumes are intended for programmers who are new to Windows or who are learning parts of it for the first time. These two volumes provide the basic information needed for an understanding of Windows programming.

Volumes 3 and 4 consist of an alphabetical listing of the Win32 functions. These volumes define the details of the syntax, parameters, and return values of each function. Volume 5 contains alphabetical listings of the Win32 data types, macros, messages, and structures. Volumes 3 through 5 are intended for programmers already acquainted with Windows programming and who need only specifics of particular functions.


  Microsoft Windows and the C Programming Language

The C programming language is the preferred development language for Windows-based applications. Many of the programming features of Windows were designed with C in mind. Windows-based applications can also be developed in other languages, but C is the most straightforward and easiest language to use to access Windows functions. For this reason, all syntax and program samples are written in the C programming language.

The Win32 API uses many types, macros, and structures that are not part of standard C language. These types, macros, and structures have been defined to make the task of creating Windows-based applications simpler and to make application sources clearer and easier to understand. All types, macros, and structures discussed in this manual are defined in the Win32 C-language header files.

Many chapters in Volumes 1 and 2 include code examples. These examples show how to use Win32 functions to accomplish tasks. In nearly all cases, the examples are code fragments, not complete programs. Each example is intended to show the context in which a function can be used; often, an example presumes that variables, structures, and constants used in the example have been defined or initialized, or both. An example may also use comments to describe a task, without presenting the appropriate statements.

Although the examples are not complete, you can use them in your applications by taking the following steps:

•	Include the WINDOWS.H file in your program.

•	Define the appropriate include constants for the functions, structures, and constants used in the example.

•	Define and initialize all variables.

•	Replace comments that represent tasks with appropriate statements.

•	Check return values for errors and take appropriate actions.

Some examples in this manual combine both Win32 and C run-time functions to carry out their tasks.


  Document Conventions

The following conventions are used throughout this manual to define syntax.

Convention	Meaning
Bold text	Denotes a term or character to be typed literally, such as a predefined data type or function name (HWND or CreateWindowEx), a command, or a command-line option (/x). You must type these terms exactly as shown.
Italic text	Denotes a placeholder or variable: You must provide the actual value. For example, the statement SetCursorPos(X,Y) requires you to substitute values for the X and Y parameters.
[ ]	Enclose optional parameters.
|	Separates an either/or choice.
...	Specifies that the preceding item may be repeated.
.	Represents an omitted portion of a sample application.
.
.
In addition, certain text conventions are used to help you understand this material.

Convention	Meaning
SMALL CAPITALS	Indicate the names of keys, key sequences, and key combinations — for example, ALT+SPACEBAR.
FULL CAPITALS	Indicate filenames and paths, most type and structure names (which are also bold), and constants.
monospace	Sets off code examples and shows syntax spacing.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


1.1  About Windows
  Chapter 1    Windows

1.1  About Windows

A window in an application written for Microsoft® Windows (™)  is a rectangular area of the screen where the application displays output and receives input from the user. A window shares the screen with other windows, including those from other applications. Only one window at a time can receive input from the user. The user can use the mouse, keyboard, or other input device to interact with this window and the application that owns it.

Windows are the only means a Windows-based application has to interact with the user and accomplish tasks, so one of the first tasks of a Windows-based application is to create a window. This chapter describes the application programming interface (API) elements of Windows that applications use to create and use windows; manage relationships between windows; and size, move, and display windows.


  1.1.1  Desktop Window

When Windows starts, it automatically creates the desktop window. The desktop window is a system-defined window that paints the background of the screen and serves as the base for all windows displayed by all Windows-based applications.

The desktop window uses a bitmap stored in a bitmap file (with the .BMP filename extension) to paint the background of the screen. The pattern created by the bitmap is called the desktop wallpaper. By default, the desktop window uses the bitmap from the file specified in the following key of the registry as the desktop wallpaper:

HKEY_CURRENT_USER\Control Panel\Desktop\Wallpaper

A system configuration application, such as Windows Control Panel, can change the desktop wallpaper by using the SetDeskWallpaper function to specify a different bitmap filename. SetDeskWallpaper loads the bitmap from the specified file, uses the bitmap to paint the background of the screen, and enters the new filename in the Wallpaper key of the registry. For more information about bitmaps, see Chapter 29, »Bitmaps«. For more information about the registry, see Chapter 52, "Registry and Initialization Files" in Microsoft Win32 Programmer's Reference, Volume 2.


  1.1.2  Application Windows

Every Windows-based application creates at least one window, called the main window that serves as the main window for the application. This window, serves as the primary interface between the user and the application. Most applications also create many other windows, either directly or indirectly, to carry out tasks related to the main window. Each window plays a part in displaying output and receiving input from the user.


  1.1.2.1  Components of an Application Window

An application window can include a title bar, a menu bar, a System menu (also called the Control menu), a minimize box, a maximize box, a sizing border, a client area, a horizontal scroll bar, and a vertical scroll bar. An application's main window typically includes all of these components. »This illustration« shows these components in a typical main window.

The title bar displays an application-defined line of text; typically, the text specifies the name of the application or indicates the purpose of the window. An application specifies the text when creating the window. The title bar also makes it possible for the user to move the window by using a mouse or other pointing device.

Most applications include a menu that lists the commands supported by the application. Items in the menu bar represent the main categories of commands. Choosing an item from the menu bar typically opens a pop-up menu whose items correspond to the tasks within a given category. By selecting a command, the user directs the application to carry out a task.

The System-menu box is a bitmap that, when clicked, displays the System menu. The System menu is a menu created and managed by Windows. It contains a standard set of menu items that, when chosen by the user, set a window's size or position, close the application, or open the Windows Task List. For more information about menus and the System menu, see Chapter 16, »Menus«.

The maximize and minimize boxes are bitmaps that, when clicked, affect a window's size and position. When the user clicks the maximize box, Windows enlarges the window to the size of the screen and positions the window, so it covers the entire screen. At the same time, Windows replaces the maximize box with the restore box. The restore box is a bitmap that, when clicked, restores the window to its previous size and position.

When the user clicks the minimize box, Windows reduces the window to the size of an icon, positions the window at the bottom of the screen, and displays the window's icon at the position of the window. An icon is a 32- by 32-pixel bitmap that represents a window. For more information about icons, see Chapter 23, »Icons«.

The sizing border is an area around the perimeter of the window that enables the user to size the window by using a mouse or other pointing device.

The client area is the part of a window where the application displays output, such as text or graphics. For example, a desktop publishing application displays the current page of a document in the client area. The application must provide a function, called a window procedure, to process input to the window and display output in the client area. For more information about window procedures, see Chapter 4, »Window Procedures«.

The horizontal and vertical scroll bars convert mouse or keyboard input into values that an application uses to shift the contents of the client area either horizontally or vertically. For example, a word processing application that displays a lengthy document typically provides a vertical scroll bar to enable the user to page up and down through the document.

The title bar, menu bar, System menu, minimize and maximize boxes, sizing border, and scroll bars are referred to collectively as the window's nonclient area. Windows manages most aspects of the nonclient area; the application manages everything else about the window. In particular, the application manages the appearance and behavior of the client area.


  1.1.2.2  Controls, Dialog Boxes, and Message Boxes

An application uses several types of windows in addition to its main window, including controls, dialog boxes, and message boxes.

A control is a window that an application uses to obtain a specific piece of information from the user, such as the name of a file to open or the desired point size of a text selection. Applications also use controls to obtain information needed to control a particular feature of an application. For example, a word processing application typically provides a control to let the user turn wordwrapping on and off. For more information about controls, see Chapter 9, »Controls«, Chapter 10, »Buttons«, Chapter 11, »List Boxes«, Chapter 12, »Edit Controls«, Chapter 13, »Combo Boxes«, Chapter 14, »Scroll Bars«, and Chapter 15, »Static Controls«.

Controls are always used in conjunction with another window — typically, a dialog box. A dialog box is a window that contains one or more controls. An application uses a dialog box to prompt the user for input needed to complete a command. For example, an application that includes a command to open a file would display a dialog box that includes controls in which the user specifies a path and filename. »This illustration« shows the Open dialog box and its associated controls file.

A message box is a window that displays a note, caution, or warning to the user. For example, a message box can inform the user of a problem the application has encountered while carrying out a task. »This illustration« shows a message box that explains why the application, Microsoft® Word for Windows (™)  cannot complete a file-save operation.

Dialog boxes and message boxes do not typically use the same set of window components as does a main window. Most have a title bar, a System menu, a border (non-sizing), and a client area, but they typically do not have a menu bar, minimize and maximize buttons, or scroll bars. For more information about dialog boxes and message boxes, see Chapter 18, »Dialog Boxes«."


  1.1.3  Window Creation

An application creates it main window by using the CreateWindow or CreateWindowEx function and providing information Windows needs to define the attributes of the window. The CreateWindowEx function has a parameter, dwExStyle, that the CreateWindow function does not have; otherwise, the functions are identical. In fact, CreateWindow simply calls CreateWindowEx, setting the dwExStyle parameter to zero. For this reason, the remainder of this chapter refers only to the CreateWindowEx function.

Windows provides additional functions — including DialogBox, CreateDialog, and MessageBox — for creating special-purpose windows such as dialog boxes and message boxes. For more information about these functions, see Chapter 18, »Dialog Boxes«.


  1.1.3.1  Window Attributes

An application must provide the following information when creating a window:

•	Window class

•	Window name

•	Window style

•	Parent or owner window

•	Size

•	Location

•	Position

•	Child-window identifier or menu handle

•	Instance handle

•	Creation data

These attributes are described in the following sections.

Window Class

Every window belongs to a window class. An application must register a window class before creating any windows of that class. The window class defines most aspects of a window's appearance and behavior. The chief component of a window class is the window procedure, a function that receives and processes all input and requests sent to the window. Windows provides the input and requests in the form of messages. For more information about window classes, window procedures, or messages, see Chapter 3, »Window Classes«, Chapter 4, »Window Procedures«, or Chapter 2, »Messages and Message Queues«.

Window Name

A window can have a name. A window name (also called window text) is a text string that identifies a window for the user. A main window, dialog box, or message box typically displays its window name in its title bar, if present. For a control, the appearance of the window name depends on the control's class. A button, edit control, or static control displays its window name within the rectangle occupied by the control. A list box, combo box, or static control does not display its window name.

An application uses the SetWindowText function to change the window name after creating the window. It uses the GetWindowTextLength and GetWindowText functions to retrieve the current window-name text from a window.

Window Style

Every window has one or more window styles. A window style is a named constant that defines an aspect of the window's appearance and behavior that is not specified by the window's class. For example, the SCROLLBAR class creates a scroll bar control, but the SBS_HORZ and SBS_VERT styles determine whether a horizontal or vertical scroll bar control is created. A few window styles apply to all windows, but most apply to windows of specific window classes. Windows and, to some extent, the window procedure for the class, interpret the styles.

Parent or Owner Window

A window can have a parent window. A window that has a parent is called a child window. The parent window provides the coordinate system used for positioning a child window. Having a parent window affects aspects of a window's appearance; for example, a child window is clipped so that no part of the child window can appear outside the borders of its parent window. A window that has no parent, or whose parent is the desktop window, is called a top-level window. An application uses the EnumWindows function to obtain the handle of each of its top-level windows. EnumWindows passes the handle of each top-level window, in turn, to an application-defined callback function (a function called by Windows).

A window can own, or be owned by, another window. An owned window always appears in front of its owner window, is hidden when its owner window is minimized, and is destroyed when its owner window is destroyed.

Location, Size, and Position in the Z Order

Every window has a location, size, and position in the Z order. The location is the coordinates of the window's upper-left corner, relative to the upper-left corner of the screen or, in the case of a child window, the upper-left corner of the parent's client area. A window's size is its width and height measured in pixels. A window's position in the Z order is the position of the window in a stack of overlapping windows.

Child-Window Identifier or Menu Handle

A child window can have a child-window identifier, a unique application-defined value associated with the child window. Child-window identifiers are especially useful in applications that create multiple child windows. When creating a child window, an application specifies the identifier of the child window. After creating the window, the application can change the window's identifier by using the SetWindowLong function, or it can retrieve the identifier by using the GetWindowLong function.

Every window, except a child window, can have a menu. An application can include a menu by providing a menu handle either when registering the window's class or when creating the window.

Instance Handle

Every Windows-based application has an instance handle associated with it. Windows provides the instance handle to an application when the application starts. Because it can run multiple copies of the same application, Windows uses instance handles internally to distinguish one instance of an application from another. The application must specify the instance handle in many different windows, including those that create windows.

Creation Data

Every window can have application-defined creation data associated with it. When the window is first created, Windows passes a pointer to the data on to the window procedure of the window being created. The window procedure uses the data to initialize application-defined variables.


  1.1.3.2  Main Window Creation

Every Windows-based application must have a WinMain function as its entry point. The WinMain function performs a number of tasks, including registering the window class for the main window and creating the main window. WinMain registers the main window class by calling the RegisterClass function, and it creates the main window by calling the CreateWindowEx function.

Portability Issue   In Windows NT, the entry point can have a name other than WinMain. In Windows version 3.x, the entry point must be named WinMain.

Windows does not automatically display the main window after creating it; the application must use the ShowWindow function to display the main window. Typically, the application's WinMain function calls ShowWindow immediately after creating the main window. WinMain passes two parameters to ShowWindow: the handle of the main window and a flag specifying whether the main window should be minimized or maximized when it is first displayed. Normally, the flag can be set to any of the constants beginning with the SW_ prefix that are defined in the Windows header files. However, when ShowWindow is called to display the application's main window, the flag must be set to SW_SHOWDEFAULT. This flag tells Windows to display the window as directed by the program that launched the application.


  1.1.3.3  Window-Creation Messages

When creating any window, Windows sends messages to the window procedure for the window. Windows sends the WM_NCCREATE message after creating the window's nonclient area and the WM_CREATE message after creating the client area. The window procedure receives both messages before Windows displays the window. Both messages include a pointer to a CREATESTRUCT structure that contains all the information specified in the CreateWindowEx function. Typically, the window procedure performs initialization tasks upon receiving these messages.

When creating a child window, Windows sends the WM_PARENTNOTIFY message to the parent window after sending the WM_NCCREATE and WM_CREATE messages. It also sends other messages while creating a window. The number and order of these messages depend on the window class and style and on the function used to create the window. These messages are described in the remaining sections of this chapter and in other chapters of this book.


  1.1.3.4  Multithread Applications

A Windows NT application can have multiple threads of execution, and each thread can create windows. An application can use the EnumThreadWindows function to enumerate the windows created by a particular thread. This function passes the handle of each thread window, in turn, to an application-defined callback function. The GetWindowThreadProcessId function returns the identifier of the thread that created a particular window.


  1.1.4  Window Handles

After creating a window, the creation function returns a window handle that uniquely identifies the window. An application uses this handle in other functions to direct their actions to the window. A window handle has the HWND data type; an application must use this type when declaring a variable that holds a window handle.

Windows includes several special constants that can replace a window handle in certain functions. These constants begin with the HWND_ prefix. For example, an application can use the HWND_TOP or HWND_BOTTOM constant in the SetWindowPos function to move a window to the top or bottom of the Z order.

Although the NULL constant is not a window handle, an application can use it in some functions to specify that no window is affected. For example, specifying NULL for the CreateWindowEx function's hwndParent parameter creates a window that has no parent or owner. Some functions may return NULL instead of a handle, indicating that the given action applies to no window.

An application can use the FindWindow function to discover whether a window with the specified class name or window name exists in the system. If such a window exists, FindWindow returns the handle of the window. The IsWindow function determines whether a window handle identifies a valid, existing window.


  1.1.5  Window Styles

Windows provides general window styles and class-specific window styles. The general windows styles are constants that begin with the WS_ prefix; they can be combined to form different types of windows, including main windows, dialog boxes, and child windows. The class-specific window styles define the appearance and behavior of windows belonging to the predefined control classes such as edit controls and list boxes. This section describes the general window styles. For information about class-specific window styles, see Chapter 10, »Buttons«, Chapter 11, »List Boxes«, Chapter 18, »Edit Controls«, Chapter 13, »Combo Boxes«, Chapter 14, »Scroll Bars«, and Chapter 15, »Static Controls«.

An application usually sets a window's styles when creating the window. It can also set the styles after creating the window by using the SetWindowLong function.


  1.1.5.1  Overlapped Window

An overlapped window is a top-level window that has a title bar, border, and client area; it is meant to serve as an application's main window. It can also have a System menu, minimize and maximize boxes, and scroll bars. An overlapped window used as a main window typically includes all of these components.

An application creates an overlapped window by specifying the WS_OVERLAPPED or WS_OVERLAPPEDWINDOW style in the CreateWindowEx function. An overlapped window created with the WS_OVERLAPPED style has a title bar and border. The WS_OVERLAPPEDWINDOW style creates an overlapped window with a title bar, sizing border, System menu, and minimize and maximize boxes.


  1.1.5.2  Pop-up Window

A pop-up window is a special type of overlapped window typically used for dialog boxes, message boxes, and other temporary windows that appear outside an application's main window. A title bar is optional for a pop-up window; otherwise, a pop-up window is the same as an overlapped window created with the WS_OVERLAPPED style.

An application creates a pop-up window by specifying the WS_POPUP style in the CreateWindowEx function. To include a title bar, the WS_CAPTION style must also be specified. An application can use the WS_POPUPWINDOW style to create a pop-up window that has a border and a System menu. The WS_CAPTION style must be combined with the WS_POPUPWINDOW style to make the System menu visible.


  1.1.5.3  Child Window

A child window has the WS_CHILD style and is confined to the client area of its parent window. An application typically uses child windows to divide the client area of a parent window into functional areas. An application creates a child window by specifying the WS_CHILD style in the CreateWindowEx function.

A child window must have a parent window. The parent window can be an overlapped window, a pop-up window, or even another child window. An application specifies the parent window when it calls the CreateWindowEx function. If the application specifies the WS_CHILD style in the CreateWindowEx function but does not specify a parent window, Windows does not create the window.

A child window has a client area, but it does not have any other features unless they are explicitly requested. An application can request a title bar, a System menu, minimize and maximize boxes, a border, and scroll bars for a child window, but a child window cannot have a menu. If the application specifies a menu handle, either when it registers the child's window class or creates the child window, the menu handle is ignored.

Positioning

Windows always positions the child window relative to the upper-left corner of the parent window's client area. No part of a child window ever appears outside the borders of its parent window. If an application creates a child window that is larger than the parent window or positions a child window so that some or all of the child window extends beyond the borders of the parent, Windows clips the child window; that is, the portion outside the parent window's client area is not displayed. Actions that affect the parent window can also affect the child window, as follows.

Parent window	Child window
Destroyed	Destroyed before the parent window is destroyed.
Hidden	Hidden before the parent window is hidden. A child window is visible only when the parent window is visible.
Moved	Moved with the parent window's client area. The child window is responsible for painting its client area after the move.
Shown	Shown after the parent window is shown.
Clipping

Windows does not automatically clip a child window from the parent window's client area. This means the parent window draws over the child window if it carries out any drawing in the same location as the child window. Windows does, however, clip the child window from the parent window's client area if the parent window has the WS_CLIPCHILDREN style. If the child window is clipped, the parent window cannot draw over it.

A child window can overlap other child windows in the same client area. A child window that shares the same parent window as one or more other child windows is called a sibling window. Sibling windows can draw in each other's client area, unless one of the child windows has the WS_CLIPSIBLINGS style. If the application specifies this style for a child window, any portion of the child's sibling window that lies within this window is clipped.

If a window has either the WS_CLIPCHILDREN or WS_CLIPSIBLINGS style, a slight loss in performance occurs. Each window takes up system resources, so an application should not use child windows indiscriminately. For optimum performance, an application that needs to logically divide its main window should do so in the window procedure of the main window rather than by using child windows.

Relationship to Parent Window

An application can change the parent window of an existing child window by calling the SetParent function. In this case, Windows removes the child window from the client area of the old parent window and moves it to the client area of the new parent window. If SetParent specifies a NULL handle, the desktop window becomes the new parent window. In this case, the child window is drawn on the desktop, outside the borders of any other window. The GetParent function retrieves the handle of a child window's parent window.

The parent window relinquishes a portion of its client area to a child window, and the child window receives all input from this area. The window class need not be the same for each of the child windows of the parent window. This means that an application can fill a parent window with child windows that look different and carry out different tasks. For example, a dialog box can contain many types of controls; each control is a child window that accepts a different type of data from the user.

A child window has only one parent window, but a parent can have any number of child windows. Each child window, in turn, can have child windows. In this chain of windows, each child window is called a descendant window of the original parent window. An application uses the IsChild function to discover whether a given window is a child window or a descendant window of a given parent window.

The EnumChildWindows function enumerates the child windows of a parent window. Then EnumChildWindows passes the handle of each child window to an application-defined callback function. Descendant windows of the given parent window are also enumerated.

Messages

Windows passes a child window's input messages directly to the child window; the messages are not passed through the parent window. The only exception is if the child window has been disabled by the EnableWindow function. In this case, Windows passes any input messages that would have gone to the child window to the parent window instead. This permits the parent window to examine the input messages and enable the child window, if necessary.

A child window can have a unique integer identifier. Child window identifiers are important when working with control windows. An application directs a control's activity by sending it messages. The application uses the control's child window identifier to direct the messages to the control. In addition, a control sends notification messages to its parent window. A notification message includes the control's child window identifier, the parent window used by to identify the source of the message. An application specifies the child-window identifier for other types of child windows by setting the hmenu parameter of the CreateWindowEx function to a value rather than a menu handle.


  1.1.5.4  Window Border

Windows provides the following border style.

Style	Description
WS_BORDER	Creates a window with a thin-line border.
WS_DLGFRAME	Creates a window with a double border, a style typically used with dialog boxes. A window with this style cannot have a title bar.
WS_EX_DLGMODALFRAME	Creates a window with a double border. Unlike the WS_DLGFRAME style, an application can also specify the WS_CAPTION style to create a title bar for the window.
WS_THICKFRAME	Creates a window with a sizing border.
A window with the WS_OVERLAPPED or WS_POPUPWINDOW style has the WS_BORDER style by default. One of the other border styles must be combined with the WS_OVERLAPPED or WS_POPUPWINDOW style to give an overlapped window a different border style.

If no border style is specified for a window with the WS_POPUP or WS_CHILD style, the system creates a borderless window. An application can use borderless child windows to divide the parent window's client area while keeping the divisions invisible to the user.


  1.1.5.5  Nonclient-Area Components

The nonclient area of a window can include a title bar, System menu, minimize and maximize boxes, sizing border, and horizontal and vertical scroll bars. An application can create a window with one or more of these components by specifying the following styles in the CreateWindowEx function.

Style	Description
WS_CAPTION	Creates a window that has a title bar (includes the WS_BORDER style).
WS_HSCROLL	Creates a window that has a horizontal scroll bar.
WS_MAXIMIZEBOX	Creates a window that has a maximize box.
WS_MINIMIZEBOX	Creates a window that has a minimize box.
WS_SYSMENU	Creates a window that has a System-menu box in its title bar. The WS_CAPTION style must also be specified.
WS_VSCROLL	Creates a window that has a vertical scroll bar.


  1.1.5.6  Initial State

The following styles determine whether a window is enabled or disabled, visible or invisible, and minimized or maximized.

Style	Description
WS_DISABLED	Creates a window that is initially disabled. A disabled window cannot receive input from the user.
WS_MAXIMIZE	Creates a window that is initially maximized.
WS_MINIMIZE	Creates a window that is initially minimized.
WS_VISIBLE	Creates a window that is initially visible.


  1.1.5.7  Parent and Child Styles

The following styles affect the clipping relationship between a parent window and its child windows and between a child window and its sibling windows.

Style	Description
WS_CLIPCHILDREN	Excludes the area occupied by child windows when drawing within the parent window. Use this style when creating the parent window.
WS_CLIPSIBLINGS	Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of one child window, to draw within the client area of another neighboring child window. Use this style with the WS_CHILD style only.


  1.1.5.8  Dialog Box Styles

A dialog box includes a built-in keyboard interface that processes the direction and TAB keys. The user can use these keys instead of the mouse to navigate among the controls in the dialog box. The following styles affect how the built-in keyboard interface processes the direction and TAB keys.

Style	Description
WS_GROUP	Specifies the first control of a group of controls. The user can change the keyboard focus from one control in the group to the next by using the direction keys. All controls defined with the WS_GROUP style after the first control belong to the same group. The next control with the WS_GROUP style ends the group and starts the next group.
WS_TABSTOP	Specifies a control that can receive the keyboard focus when the user presses the TAB key. Pressing the TAB key changes the keyboard focus to the next control that has the WS_TABSTOP style.


  1.1.5.9  Extended Styles

The following styles can be specified in the dwExStyle parameter of the CreateWindowEx function.

Style	Description
WS_EX_ACCEPTFILES	Specifies that a window created with this style accepts drag-drop files. For more information about drag-drop files, see Chapter 78, "Shell Library" in Microsoft Win32 Programmer's Reference, Volume 2
WS_EX_DLGMODALFRAME	Creates a window with a double border. Unlike the WS_DLGFRAME style, an application can also specify the WS_CAPTION style to create a title bar for the window.
WS_EX_NOPARENTNOTIFY	Specifies that a child window created with this style will not send the WM_PARENTNOTIFY message to its parent window when either created or destroyed.
WS_EX_TOPMOST	Specifies that a window created with this style should be placed above all non-topmost windows and stay above them even when the window is deactivated.


  1.1.6  Owned Windows

An overlapped or pop-up window can be owned by another overlapped or pop-up window. Being owned places several constraints on a window.

•	An owned window is always above its owner in the Z order.

•	Windows automatically destroys an owned window when its owner is destroyed.

•	An owned window is hidden when its owner is minimized.

Only an overlapped or pop-up window can be an owner window; a child window cannot be one. An application creates an owned window by specifying the owner's window handle as the hwndParent parameter of the CreateWindowEx function when it creates a window with the WS_OVERLAPPED or WS_POPUP style. The hwndParent parameter must identify an overlapped or pop-up window. If hwndParent identifies a child window, Windows assigns ownership to the top-level parent window of the child window. After creating an owned window, an application cannot transfer ownership of the window to another window.

Dialog boxes and message boxes are owned windows by default. An application specifies the owner window when calling a function that creates a dialog box or message box.

An application can use the GetWindow function with the GW_OWNER flag to retrieve the handle of a window's owner.


  1.1.7  Disabled Windows

A window can be disabled. A disabled window receives no keyboard or mouse input, but it can receive messages from other windows, from other applications, and from Windows. An application typically disables a window to prevent the user from using the window. For example, an application may disable a push button in a dialog box to prevent the user from choosing it. An application can enable a disabled window at any time; enabling a window restores normal input.

By default, a window is enabled when created. An application can specify the WS_DISABLED style, however, to disable a new window. An application enables or disables an existing window by using the EnableWindow function. Windows sends a WM_ENABLE message to a window when its enabled state is about to change. An application can determine whether a window is enabled by using the IsWindowEnabled function.

When a child window is disabled, Windows passes the child's mouse input messages to the parent window. The parent uses the messages to determine whether to enable the child window. For more information about mouse input, see Chapter 6, »Mouse Input«.

Only one window at a time can receive keyboard input; that window is said to have the keyboard focus. If an application uses the EnableWindow function to disable a keyboard-focus window, the window loses the keyboard focus in addition to being disabled. EnableWindow then sets the keyboard focus to NULL, meaning no window has the focus. If a child window or other descendant window has the keyboard focus, the descendant window loses the focus when the parent window is disabled. For more information about the keyboard focus, see Chapter 5, »Keyboard Input«.


  1.1.8  Foreground and Background Windows

In Windows NT, each process can have multiple threads of execution, and each thread can create windows. The thread that created the window with which the user is currently working is called the foreground thread, and the window is called the foreground window. All other threads are background threads, and the windows created by background threads are called background windows.

Each thread has a priority level that determines the amount of CPU time the thread receives. Although an application can set the priority level of its threads, normally the foreground thread has a slightly higher priority level than the background threads. Because it has a higher priority, the foreground thread receives more CPU time than the background threads. The foreground thread has a normal base priority of 9; a background thread has a normal base priority of 7.

The user sets the foreground window by clicking a window or by using the ALT+TAB or ALT+ESC key combination. An application sets the foreground window by using the SetForegroundWindow function. If the new foreground window is a top-level window, Windows activates it; otherwise, Windows activates the associated top-level window. An application retrieves the handle of the foreground window by using the GetForegroundWindow function.


  1.1.9  Show State

At any one given time, a window may be active or inactive; hidden or visible; and minimized, maximized, or restored. These qualities are referred to collectively as the window's show state.


  1.1.9.1  Active Window

An active window is the top-level window of the application with which the user is currently working. To allow the user to easily identify the active window, Windows places it at the top of the Z order and changes the color of its title bar and border to the system-defined active window colors. Only a top-level window can be an active window. When the user is working with a child window, Windows activates the top-level parent window associated with the child window.

Only one top-level window in the system is active at any particular time. The user activates a top-level window by clicking it (or one of its child windows) or by using the ALT+ESC or ALT+TAB key combination. An application activates a top-level window by calling the SetActiveWindow function. A number of other functions can cause Windows to activate a different top-level window, including SetWindowPos, DeferWindowPos, SetWindowPlacement, and DestroyWindow. Although an application can activate a different top-level window at any time, to avoid confusing the user, it should do so only in response to a user action. An application uses the GetActiveWindow function to retrieve the handle of the active window.

When the activation changes from a top-level window of one application to the top-level window of another, Windows sends both applications the WM_ACTIVATEAPP message notifying them of the change. When the activation changes to a different top-level window in the same application, Windows sends the WM_ACTIVE message to both windows.


  1.1.9.2  Visibility

A window can be either visible or hidden. Windows displays a visible window on the screen. It hides a hidden window by not drawing it. If a window is visible, the user can supply input to the window and view the window's output. If a window is hidden, it is effectively disabled. A hidden window can process messages from Windows or from other windows, but it cannot process input from the user or display output. An application sets a window's visibility state when creating the window. Later, the application can change the visibility state.

A window is visible when the WS_VISIBLE style is set for the window. By default, the CreateWindowEx function creates a hidden window unless the application specifies the WS_VISIBLE style. Typically, an application sets the WS_VISIBLE style after it has created a window to keep details of the creation process hidden from the user. For example, an application may keep a new window hidden while it customizes the window's appearance. If the WS_VISIBLE style is specified in the CreateWindowEx function, Windows sends the WM_SHOWWINDOW message to the window after creating the window, but before displaying it.

An application can determine whether a window is visible by using the IsWindowVisible function. An application can show (make visible) or hide a window by using the ShowWindow, SetWindowPos, DeferWindowPos, or SetWindowPosition function. These functions show or hide a window by setting or removing the WS_VISIBLE style for the window. They also send the WM_SHOWWINDOW message to the window before showing or hiding it.

When an owner window is minimized, Windows automatically hides the associated owned windows. Likewise, when an owner window is restored, Window automatically shows the associated owned windows. In both cases, Windows sends the WM_SHOWWINDOW message to the owned windows before hiding or showing them. Occasionally, an application may need to hide the owned windows without having to minimize or hide the owner. In this case, the application uses the ShowOwnedPopups function. This function sets or removes the WS_VISIBLE style for all owned windows and sends the WM_SHOWWINDOW message to the owned windows before hiding or showing them. Hiding an owner window has no effect on the visibility state of the owned windows.

When a parent window is visible, its associated child windows are also visible. Likewise, when the parent window is hidden, its child windows are also hidden. Minimizing the parent window has no effect on the visibility state of the child windows; that is, the child windows are minimized along with the parent, but the WS_VISIBLE style is not changed.

Even if a window has the WS_VISIBLE style, the user may not be able to see the window on the screen; other windows may completely overlap it or it may have been moved beyond the edge of the screen. Also, a visible child window is subject to the clipping rules established by its parent-child relationship. If the window's parent window is not visible, it will also not be visible. Because a child window is drawn relative to the parent's upper-left corner, if the parent window moves beyond the edge of the screen, the child window also moves. For example, a user may move the parent window containing the child window far enough off the edge of the screen that the user may not be able to see the child window, even though the child window and its parent window both have the WS_VISIBLE style.


  1.1.9.3  Minimized, Maximized, and Restored Windows

A maximized window is a window that has the WS_MAXIMIZED style. By default, Windows enlarges a maximized window so that it fills the screen or, in the case of a child window, the parent window's client area. Although a window's size can be set to the same size of a maximized window, a maximized window is slightly different. Windows automatically moves the window's title bar to the top of the screen or to the top of the parent window's client area. Also, Windows disables the window's sizing border and the window-positioning capability of the title bar (so that the user can not move the window by dragging the title bar).

A minimized window is a window that has the WS_MINIMIZED style. By default, Windows reduces a minimized window to the size of an icon and moves the minimized window to the lower part of the screen or the lower part of the parent window's client area. The lower part of the screen or client area is sometimes called the icon area. Windows moves a minimized window into the first available position in the icon area, unless the application specifies another position. A restored window is a window that has been returned to its pre-minimized or pre-maximized size and position.

If an application specifies the WS_MAXIMIZED or WS_MINIMIZED style in the CreateWindowEx function, the window is initially maximized or minimized. After creating a window, an application can use the CloseWindow function to minimize the window. The ArrangeIconicWindows function arranges the application's minimized top-level windows along the bottom of the screen, or it arranges a parent window's minimized child windows along the bottom of the parent window.

The ShowWindow function can minimize, maximize, or restore a window. At the same time it can set the window's visibility and activation states. The SetWindowPlacement function includes the same functionality as ShowWindow, but it can also override the window's default minimized, maximized, and restored positions.

The IsZoomed function determines whether a given window is maximized, and the IsIconic function determines whether a given window is minimized. The GetWindowPlacement function retrieves the minimized, maximized, and restored positions for the window, and it also determines the window's show state.

When Windows receives a command to maximize or restore a minimized window, Windows sends the window a WM_QUERYOPEN message. If the window procedure returns FALSE, Windows ignores the maximize or restore command.

Windows automatically sets the size and position of a maximized window to the system-defined defaults for a maximized window. An application can override these defaults by using the SetWindowPlacement function or by processing the WM_GETMINMAXINFO message that is received by a window when Windows is about to maximize the window. The message includes a pointer to a MINMAXINFO structure containing values Windows uses to set the maximized size and position. Replacing these values overrides the defaults.


  1.1.10  Size and Position

A window's size and position are expressed as a bounding rectangle, given in coordinates relative to the screen or the parent window. The coordinates of a top-level window are relative to the upper-left corner of the screen; the coordinates of a child window are relative to the upper-left corner of the parent window. An application specifies a window's initial size and position when it creates the window, but it can change the window's size and position at any time.


  1.1.10.1  Size

A window's size (width and height) is given in pixels. A window can have zero width or height. If an application sets a window's width and height to zero, Windows sets the size to the default minimum window size. To discover the default minimum window size, an application uses the GetSystemMetrics function with the SM_CXMIN and SM_CYMIN flags.

An application may need to create a window with a client area of a particular size. The AdjustWindowRect and AdjustWindowRectEx functions calculate the required size of a window based on the desired size of the client area. The application can pass the resulting size values to the CreateWindowEx function.

An application can size a window so that it is extremely large; however, it should not size a window so that it is larger than the screen. Before setting a window's size, the application should check the width and height of the screen by using the GetSystemMetrics function with the SM_CXSCREEN and SM_CYSCREEN flags.


  1.1.10.2  Position

A window's position is defined as the coordinates of its upper-left corner. These coordinates, sometimes called window coordinates, are always relative to the upper-left corner of the screen or, for a child window, the upper-left corner of the parent window's client area. For example, a top-level window having the coordinates (10,10) is placed 10 pixels to the right of the upper-left corner of the screen and 10 pixels down from it. A child window having the coordinates (10,10) is placed 10 pixels to the right of the upper-left corner of its parent window's client area and 10 pixels down from it.

The WindowFromPoint function retrieves the handle of the window occupying a particular point on the screen. The ChildWindowFromPoint function retrieves the handle of the child window occupying a particular point in the parent window's client area.


  1.1.10.3  Default Size and Position

An application can allow Windows to calculate the initial size or position of a top-level window by specifying the CW_USEDEFAULT constant in the CreateWindowEx function. If the application sets the window's coordinates to CW_USEDEFAULT and the application has created no other top-level windows, Windows sets the new window's position relative to the upper-left corner of the screen; otherwise, Windows sets the position relative to the position of the top-level window that the application created most recently. Similarly, if the width and height parameters are set to CW_USEDEFAULT, Windows calculates the size of the new window. If the application has created other top-level windows, Windows bases the size of the new window on the size of the application's most recently created top-level window. Specifying CW_USEDEFAULT when creating a child or pop-up window causes Windows to set the window's size to the default minimum window size.


  1.1.10.4  Tracking Size

Windows maintains a minimum and maximum tracking size for a window of the WS_THICKFRAME style; a window with this style has a sizing border. The minimum tracking size is the smallest window size the user can produce by dragging the window's sizing border. Likewise, the maximum tracking size is the largest window size the user can produce by dragging the sizing border.

A window's minimum and maximum tracking sizes are set to system-defined default values when Windows creates the window. An application can discover the defaults and override them by processing the WM_GETMINMAXINFO message. For more information about this message, see Section 1.1.10.8, »Size and Position Messages«.


  1.1.10.5  System Commands

An application that has a window with a System menu can change the size and position of that window by sending system commands. System commands are generated when the user chooses commands from the System menu. An application can emulate the user action by sending a WM_SYSCOMMAND message to the window. The following system commands affect the size and position of a window.

Command	Description
SC_CLOSE	Closes the window. This command sends a WM_CLOSE message to the window. The window carries out any steps needed to clean up and destroy itself.
SC_MAXIMIZE	Maximizes the window.
SC_MINIMIZE	Minimizes the window.
SC_RESTORE	Restores a minimized or maximized window to its previous size and position.
SC_SIZE	Starts a size command. The user can change the size of the window by using the mouse or keyboard.


  1.1.10.6  Z Order

The Z order of a window indicates the window's position in a stack of overlapping windows. This window stack is oriented along an imaginary axis, the z-axis, extending outward from the screen. The window at the top of the Z order overlaps all other windows. The window at the bottom of the Z order is overlapped by all other windows. An application sets a window's position in the Z order by placing it behind a given window, or at the top or bottom of the stack.

Windows maintains three separate Z orders — one for top-level windows, one for sibling windows, and one for topmost windows. A topmost window overlaps all other non-topmost windows, regardless of whether it is the active or foreground window. An application creates a topmost window by assigning it the WS_EX_TOPMOST style.

By default, Windows puts a window at the top of the Z order when creating the window. The user changes the Z order by activating a different window; Windows always positions the active window at the top of the Z order. An application uses the BringWindowToTop function to bring a window to the top of the Z order. It can rearrange the Z order by using the SetWindowPos or DeferWindowPos function.


  1.1.10.7  Size and Position Functions

After creating a window, an application can set the window's size or position by calling one of a several different functions, including MoveWindow, SetWindowPos, DeferWindowPos, and SetWindowPlacement. The MoveWindow and SetWindowPos functions are similar; both set the size or position of a single application window. The SetWindowPos function includes a set of flags that affect the window's show state; MoveWindow does not include these flags. The BeginDeferWindowPos, DeferWindowPos, and EndDeferWindowPos functions are used together to set the size, position, position in the Z order, and show state of a number of windows simultaneously. The SetWindowPlacement function sets a window's minimized position, maximized position, restored size and position, and show state.

An application can retrieve the coordinates of a window's bounding rectangle by using the GetWindowRect function. GetWindowRect fills a RECT structure with the coordinates of the window's upper-left and lower-right corners. The coordinates are relative to the upper-left corner of the screen, even for a child window. The ScreenToClient or MapWindowPoints function maps the screen coordinates of a child window's bounding rectangle to coordinates relative to the parent window's client area.

The GetClientRect function retrieves the coordinates of a window's client area. GetClientRect fills a RECT structure with the coordinates of the upper-left and lower-right corners of the client area, but the coordinates are relative to the client area itself. This means the coordinates of a client area's upper-left corner are always (0,0), and the coordinates of the lower-right corner are the width and height of the client area.


  1.1.10.8  Size and Position Messages

Windows sends the WM_GETMINMAXINFO message to a window whose size or position is about to change. For example, WM_GETMINMAXINFO is sent when the user chooses the Move or Size command from the System menu or clicks the sizing border or title bar, or when an application calls the SetWindowPos function to move or size the window. The WM_GETMINMAXINFO message includes a pointer to a MINMAXINFO structure containing the default maximized size and position for the window, and the default minimum and maximum tracking sizes for the window. An application can override these defaults by processing the WM_GETMINMAX message and setting the appropriate members of the MINMAXINFO structure. A window must have the WS_THICKFRAME or WS_CAPTION style to receive the WM_GETMINMAXINFO message. A window with the WS_THICKFRAME style receives this message during the window-creation process, as well as when it is being moved or sized.

Windows sends the WM_WINDOWPOSCHANGING message to a window whose size, position, position in the Z order, or show state is about to change. This message includes a pointer to a WINDOWPOS structure that specifies the window's new size, position, position in the Z order, and show state. By setting the members of the WINDOWPOS structure, an application can affect the window's new size, position, and appearance.

After changing a window's size, position, position in the Z order, or show state, Windows sends the WM_WINDOWPOSCHANGED message to the window. This message includes a pointer to a WINDOWPOS structure that informs the window of its new size, position, position in the Z order, and show state. Setting the members of the WINDOWPOS structure that is passed with the WM_WINDOWPOSCHANGED message has no effect on the window. A window that must process WM_SIZE and WM_MOVE messages must pass the WM_WINDOWPOSCHANGED message to the DefWindowProc function; otherwise, Windows does not send WM_SIZE and WM_MOVE messages to the window.

Windows sends the WM_NCCALCSIZE message to a window when the window is created or sized. Windows uses the message to calculate the size of a window's client area and the position of the client area relative to the upper-left corner of the window. A window typically passes this message to the default window procedure; however, this message can be useful in applications that customize a window's nonclient area or preserve portions of the client area when the window is sized. For more information, see Chapter 20, »Painting and Drawing«.


  1.1.11  Window Destruction

In general, an application must destroy all the windows it creates. It does this by using the DestroyWindow function. When a window is destroyed, the system hides the window, if it is visible, and then it removes any internal data associated with the window. This invalidates the window handle; it can no longer be used by the application.

An application destroys many of the windows it creates soon after creating them. For example, an application usually destroys a dialog box window as soon as the application has sufficient input from the user to continue its task. An application eventually destroys the main window of the application (before terminating).

Before destroying a window, an application should save or remove any data associated with the window, and it should release any system resources allocated for the window. If the application does not release the resources, Windows will free any resources not freed by the application.

Destroying a window does not affect the window class from which the window is created. New windows can still be created using that class, and any existing windows of that class continue to operate.

Destroying a window also destroys the window's descendant windows. The DestroyWindow function sends a WM_DESTROY message first to the window, then to its child windows and descendant window. In this way, all descendant windows of the window being destroyed are also destroyed.

A window with a System menu receives a WM_CLOSE message when the user chooses Close from the System menu. By processing this message, an application can prompt the user for confirmation before destroying the window. If the user confirms that the window should be destroyed, the application can call the DestroyWindow function to destroy the window.

If the window being destroyed is the active window, both the active and focus states are transferred to another window. The window that becomes the active window is the next window, as determined by the ALT+ESC key combination. The new active window then determines which window receives the keyboard focus.


  1.2  Using Windows

The following sections explain how to create and use windows in an application, how to manage parent-child window relationships, and how to move and size windows.


  1.2.1  Creating a Main Window

The first window an application creates is typically the main window. You create the main window by using the CreateWindowEx function, specifying the window class, window name, window styles, size, position, menu handle, instance handle, and creation data. A main window belongs to an application-defined window class, so you must register the window class and provide a window procedure for the class before creating the main window.

Most applications typically use the WS_OVERLAPPEDWINDOW style to create the main window. This style gives the window a title bar, a System menu, a sizing border, and minimize and maximize boxes. The CreateWindowEx function returns a handle that uniquely identifies the window.

The following example creates a main window belonging to an application-defined window class. The window name, "Main Window", will appear in the window's title bar. By combining the WS_VSCROLL and WS_HSCROLL styles with the WS_OVERLAPPEDWINDOW style, the application creates a main window with horizontal and vertical scroll bars in addition to the components provided by the WS_OVERLAPPED WINDOW style. The four occurrences of the CW_USEDEFAULT constant set the initial size and position of the window to the system-defined default values. Specifying NULL instead of a menu handle means the window will have the menu defined for the window class.

HINSTANCE hinst;

HWND hwndMain;

.

. /* Register the window class for the main window. */

.

/* Create the main window. */

hwndMain = CreateWindowEx(

    0,                      /* no extended styles          */

    "MainWClass",           /* class name                  */

    "Main Window",          /* window name                 */

    WS_OVERLAPPEDWINDOW |   /* overlapped window           */

        WS_HSCROLL |        /* horizontal scroll bar       */

        WS_VSCROLL,         /* vertical scroll bar         */

    CW_USEDEFAULT,          /* default horizontal position */

    CW_USEDEFAULT,          /* default vertical position   */

    CW_USEDEFAULT,          /* default width               */

    CW_USEDEFAULT,          /* default height              */

    (HWND) NULL,            /* no parent or owner window   */

    (HMENU) NULL,           /* class menu used             */

    hinstance,              /* instance handle             */

    NULL);                  /* no window creation data     */

if (!hwndMain)

    return FALSE;

/*

 * Show the window using the flag specified by the program

 * that launched the application, and send the application

 * a WM_PAINT message.

 */

ShowWindow(hwndMain, SW_SHOWDEFAULT);

UpdateWindow(hwndMain);

.

. /* Start the message loop for the application. */

.

Notice that the preceding example calls the ShowWindow function after creating the main window. This is done because Windows does not automatically display the main window after creating it. By passing the SW_SHOWDEFAULT flag to ShowWindow, the application allows the program that launched the application to set the initial show state of the main window. The UpdateWindow function sends the window its first WM_PAINT message.


  1.2.2  Creating, Enumerating, and Sizing Child Windows

You can divide a window's client area into different functional areas by using child windows. Creating a child window is like creating a main window — you use the CreateWindowEx function. To create a window of an application-defined window class, you must register the window class and provide a window procedure before creating the child window. You must give the child window the WS_CHILD style and specify a parent window for the child window when you create it.

The following example divides the client area of an application's main window into three functional areas by creating three child windows of equal size. Each child window is the same height as the main window's client area, but is each one-third its width. The main window creates the child windows in response to the WM_CREATE message, which the main window receives during its own window-creation process. Because each child window has the WS_BORDER style, each has a thin line border. Also, because the WS_VISIBLE style is not specified, each child window is initially hidden. Notice also that each child window is assigned a child-window identifier.

The main window sizes and positions the child windows in response to the WM_SIZE message, which the main window receives when its size changes. In response to WM_SIZE, the main window retrieves the dimensions of its client area by using the GetWindowRect function and then passes the dimensions to the EnumChildWindows function. EnumChildWindows passes the handle of each child window, in turn, to the application-defined EnumChildProc callback function. This function sizes and positions each child window by calling the MoveWindow function; the size and position are based on the dimensions of the main window's client area and the identifier of the child window. Afterward, EnumChildProc calls the ShowWindow function to make the window visible.

#define ID_FIRSTCHILD  100

#define ID_SECONDCHILD 101

#define ID_THIRDCHILD  102

LONG APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

UINT wParam;

LONG lParam;

{

    RECT rcClient;

    int i;

    switch(uMsg) {

        case WM_CREATE: /* creating main window */

            /* Create three invisible child windows. */

            for (i = 0; i < 3; i++)

                CreateWindowEx(

                    0,

                    "ChildWClass",

                    (LPCTSTR) NULL,

                    WS_CHILD | WS_BORDER,

                    0,0,0,0,

                    hwnd,

                    (HMENU) (int) (ID_FIRSTCHILD + i),

                    hinst,

                    NULL);

            return 0;

        case WM_SIZE: /* main window changed size */

            /*

             * Get the dimensions of the main window's client

             * area, and enumerate the child windows. Pass the

             * dimensions to the child windows during enumeration.

             */

            GetClientRect(hwnd, &rcClient);

            EnumChildWindows(hwnd, EnumChildProc,

                (LPARAM) &rcClient);

            return 0;

        .

        . /* Process other messages. */

        .

    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

BOOL CALLBACK EnumChildProc(hwndChild, lParam)

HWND hwndChild;

LPARAM lParam;

{

    LPRECT rcParent;

    int i, idChild;

    /*

     * Retrieve the child-window identifier. Use it to set the

     * position of the child window.

     */

    idChild = GetWindowLong(hwndChild, GWL_ID);

    if (idChild == ID_FIRSTCHILD)

        i = 0;

    else if (idChild == ID_SECONDCHILD)

        i = 1;

    else

        i = 2;

    /* Size and position the child window. */

    rcParent = (LPRECT) lParam;

    MoveWindow(hwndChild,

        (rcParent->right / 3) * i,

        0,

        rcParent->right / 3,

        rcParent->bottom,

        TRUE);

    /* Make sure the child window is visible. */

    ShowWindow(hwndChild, SW_SHOW);

    return TRUE;

}


  1.2.3  Destroying a Window

You can use the DestroyWindow function to destroy a window. Typically, an application sends the WM_CLOSE message before destroying a window, giving the window the opportunity to prompt the user for confirmation before the window is destroyed. A window that includes a System menu automatically receives the WM_CLOSE message when the user chooses the Close command from the menu. If the user confirms that the window should be destroyed, the application calls DestroyWindow. Windows sends the WM_DESTROY message to the window after removing it from the screen. In response to WM_DESTROY, the window saves its data and frees any resources it allocated. A main window concludes its processing of WM_DESTROY by calling the PostQuitMessage function to quit the application.

The following example shows how to prompt for user confirmation before destroying a window. In response to WM_CLOSE, the example displays a dialog box that contains Yes, OK, and Cancel buttons. If the user clicks the Yes button, DestroyWindow is called; otherwise, the window is not destroyed. Because the window being destroyed is a main window, the example calls PostQuitMessage in response to WM_DESTROY.

case WM_CLOSE:

    /*

     * Create the message box. If the user clicks

     * the Yes button, destroy the main window.

     */

    if (MessageBox(hwnd, szConfirm, szAppName,

            MB_YESNOCANCEL) == IDYES)

        DestroyWindow(hwndMain);

    else

        return 0;

case WM_DESTROY:

    /*

     * Post the WM_QUIT message to

     * quit the application terminate.

     */

    PostQuitMessage(0);

    return 0;


  1.3  Functions and Messages

Following are the functions and messages to create and manage windows.


  Functions

AdjustWindowRect
AdjustWindowRectEx
AnyPopup
ArrangeIconicWindows
BeginDeferWindowPos
BringWindowToTop
ChildWindowFromPoint
CloseWindow
CreateWindow
CreateWindowEx
DeferWindowPos
DestroyWindow
EndDeferWindowPos
EnumChildProc
EnumChildWindows
EnumTaskWindows (Obsolete)
EnumThreadWindows
EnumThreadWndProc
EnumWindows
EnumWindowsProc
FindWindow
GetClientRect
GetDesktopWindow
GetForegroundWindow
GetLastActivePopup
GetNextWindow
GetParent
GetTopWindow
GetWindow
GetWindowPlacement
GetWindowRect
GetWindowTask (Obsolete)
GetWindowText
GetWindowTextLength
GetWindowThreadProcessId
IsChild
IsIconic
IsWindow
IsWindowUnicode
IsWindowVisible
IsZoomed
MoveWindow
OpenIcon
SetDeskWallpaper
SetForegroundWindow
SetParent
SetWindowPlacement
SetWindowPos
SetWindowText
ShowOwnedPopups
ShowWindow
WindowFromPoint
WinMain


  Messages

WM_ACTIVATE
WM_ACTIVATEAPP
WM_CANCELMODE
WM_CHILDACTIVATE
WM_CLOSE
WM_COPYDATA
WM_CREATE
WM_DESTROY
WM_ENABLE
WM_ENDSESSION
WM_GETMINMAXINFO
WM_GETTEXT
WM_MOVE
WM_NCACTIVATE
WM_NCCALCSIZE
WM_NCCREATE
WM_NCDESTROY
WM_OPENICON
WM_PARENTNOTIFY
WM_POWER
WM_QUERYENDSESSION
WM_QUERYOPEN
WM_QUIT
WM_SETTEXT
WM_SHOWWINDOW
WM_SIZE
WM_WINDOWPOSCHANGED
WM_WINDOWPOSCHANGING


2.1  About Messages and Message Queues
  Chapter 2    Messages and Message Queues

2.1  About Messages and Message Queues

Unlike traditional applications, applications written for Microsoft® Windows (™)  do not make explicit function calls (such as to getchar) to obtain input. Instead, they wait for Windows to pass input to them.

Windows passes all input for an application to the various windows in the application. Each window has a function, called a window procedure, that Windows calls whenever it has input for the window. The window procedure processes the input and returns control to Windows. For more information about window procedures, see Chapter 4, »Window Procedures«.

This chapter describes messages and message queues and explains how to use them in your application.


  2.1.1  Messages

Windows passes input to a window procedure in the form of messages. Messages are generated by Windows and by applications. Windows generates a message at each input event — for example, when the user types, moves the mouse, or clicks a control such as a scroll bar. Windows also generates messages in response to changes in the system brought about by an application, such as when an application changes the pool of system font resources or resizes one of its windows. An application can generate messages to direct its own windows to carry out tasks or to communicate with windows in other applications.

Windows sends a message to a window procedure with a set of four parameters: a window handle, a message identifier, and two 32-bit values called message parameters. The window handle identifies the window for which the message is intended. Windows uses it to determine which window procedure to send the message to.

A message identifier is a named constant that identifies the purpose of a message. When a window procedure receives a message, it uses a message identifier to determine how to process the message. For example, the message identifier WM_PAINT tells the window procedure that the window's client area has changed and must be repainted.

Message parameters specify data or the location of data used by a window procedure when processing a message. The meaning and value of the message parameters depend on the message. A message parameter can contain an integer, packed bit flags, a pointer to a structure containing additional data, and so on. When a message does not use message parameters, it typically sets them to NULL. A window procedure must check the message identifier to determine how to interpret the message parameters.


  2.1.2  Message Routing

Windows uses two methods to route messages to a window procedure: posting messages to a first-in, first-out queue called a message queue, a system-defined memory object that temporarily stores messages, and sending messages directly to a window procedure.

Messages posted to a message queue are called queued messages. They are primarily the result of user input entered through the mouse or keyboard, such as WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, and WM_CHAR messages. Other queued messages include the timer, paint, and quit messages: WM_TIMER, WM_PAINT, and WM_QUIT. Most other messages, which are sent directly to a window procedure, are called nonqueued messages.


  2.1.2.1  Queued Messages

Windows can display any number of windows at a time. To route mouse and keyboard input to the appropriate window, Windows uses message queues. It maintains a single system message queue and any number of thread message queues, one for each thread.

Whenever the user moves the mouse, clicks the mouse buttons, or types at the keyboard, the device driver for the mouse or keyboard converts the input into messages and places them in the system message queue. Windows removes the messages, one at a time, from the system message queue, examines them to determine the destination window, and then posts them to the message queue of the thread that created the destination window. A thread's message queue receives all mouse and keyboard messages for the windows created by the thread. The thread removes messages from its queue and directs Windows to send them to the appropriate window procedure for processing. For more information about threads, see Chapter 43, "Processes and Threads," in Microsoft Win32 Programmer's Reference, Volume 2.

With the exception of the WM_PAINT message, Windows always posts messages at the end of a message queue. This ensures that a window receives its input messages in the proper first-in, first-out sequence. The WM_PAINT message, however, is kept in the queue and is forwarded to the window procedure only when the queue contains no other messages. Multiple WM_PAINT messages for the same window are combined into a single WM_PAINT message, consolidating all invalid parts of the client area into a single area. Combining WM_PAINT messages reduces the number of times a window must redraw the contents of its client area.

The system posts a message to a thread's message queue by filling an MSG structure and then copying it to the message queue. Information in the MSG structure includes the handle of the window for which the message is intended, the message identifier, the two message parameters, the message time, and the mouse cursor position. A thread can post a message to its own message queue or to the queue of another thread by using the PostMessage or PostThreadMessage function.

An application can remove a message from its queue by using the GetMessage function. To examine a message without removing it from its queue, an application can use the PeekMessage function. This function fills an MSG structure with information about the message.

After removing a message from its queue, an application can use the DispatchMessage function to direct Windows to send the message to a window procedure for processing. DispatchMessage takes a pointer to the MSG structure that was filled by a previous call to the GetMessage or PeekMessage function. DispatchMessage passes the window handle, the message identifier, and the two message parameters to the window procedure, but it does not pass the time or mouse cursor position. An application can retrieve this information by calling the GetMessageTime and GetMessagePos functions while processing a message.


  2.1.2.2  Nonqueued Messages

Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue. Windows typically sends nonqueued messages to notify a window of events that affect it. For example, when the user activates a new application window, Windows sends the window a series of messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR. These messages notify the window that it has been activated, that keyboard input is being directed to the window, and that the mouse cursor has been moved within the borders of the window. Nonqueued messages can also result when an application calls certain Windows functions. For example, Windows sends the WM_WINDOWPOSCHANGED message after an application uses the SetWindowPos function to move a window.

An application can send a message by calling the SendMessage, SendNotifyMessage, or SendDlgItemMessage function. For more information about sending messages, see Section 2.2.4, »Sending a Message«.


  2.1.3  Message Handling

An application must remove and process messages posted to the message queues of its threads. A single-threaded application usually uses a message loop in its WinMain function to remove and send messages to the appropriate window procedures for processing. Applications with multiple threads can include a message loop in each thread that creates a window. The following sections describe how a message loop works and explain the role of a window procedure.


  2.1.3.1  Message Loop

A simple message loop consists of one function call to each of these functions: GetMessage, TranslateMessage, and DispatchMessage. The GetMessage function retrieves a message from the queue and copies it to an MSG structure. GetMessage returns TRUE unless it encounters the WM_QUIT message, in which case it returns FALSE and ends the loop. In a single-threaded application, ending the message loop is often the first step in closing the application. An application can end its own loop by using the PostQuitMessage function, typically in response to the WM_DESTROY message in the window procedure of the application's main window.

If you specify a window handle in GetMessage, only messages for the specified window are retrieved from the queue. GetMessage can also filter messages in the queue, retrieving only those messages that fall within a specified range. For more information about filtering messages, see Section 2.1.6, »Message Filtering«.

A thread's message loop must include TranslateMessage if the thread is to receive character input from the keyboard. Windows generates virtual-key messages (WM_KEYDOWN and WM_KEYUP) each time the user presses a key. A virtual-key message contains a virtual-key code that identifies which key was pressed, but not its character value. To retrieve this value, the message loop must contain TranslateMessage, which translates the virtual-key message into a character message (WM_CHAR) and places it back into the application message queue. The character message can then be removed on a subsequent iteration of the message loop and dispatched to a window procedure.

The DispatchMessage function sends a message to the window procedure associated with the window handle specified in the MSG structure. If the window handle is HWND_TOPMOST, DispatchMessage sends the message to the window procedures of all top-level windows in the system. If the window handle is NULL, DispatchMessage does nothing with the message.

An application's main thread starts its message loop after initializing the application and creating at least one window. Once started, the message loop continues to retrieve messages from the thread's message queue and to dispatch them to the appropriate windows. The message loop ends when the GetMessage function removes the WM_QUIT message from the message queue.

Only one message loop is needed for a message queue, even if an application contains many windows. Because each message in the queue is an MSG structure that contains the handle of the window to which the message belongs, DispatchMessage always dispatches the message to the proper window.

An application can modify its message loop in a variety of ways. For example, it can retrieve messages from the queue without dispatching them to a window. This is useful for applications that post messages not specifying a window. (These messages apply to the application rather than to a specific window, because they have NULL window handles.) An application can also direct GetMessage to search for specific messages, leaving other messages in the queue. This is useful for applications that must temporarily bypass the usual first-in, first-out order of the message queue.

An application that uses accelerator keys must be able to translate keyboard messages into command messages. To do this, the application's message loop must include a call to the TranslateAccelerator function. For more information about accelerator keys, see Chapter 17, »Keyboard Accelerators«.


  2.1.3.2  Window Procedure

A window procedure is a function that receives and processes all messages sent to the window. Every window class has a window procedure, and every window created with that class uses that same window procedure to respond to messages.

The system sends a message to a window procedure by passing the message data as arguments to the procedure. The window procedure then carries out an appropriate action for the message; it checks the message identifier and, while processing the message, uses the information specified by the message parameters.

A window procedure does not usually ignore a message. If it does not process a message, it must send the message back to the system for default processing. The window procedure does this by calling the DefWindowProc function, which carries out a default action and returns a message result. The window procedure must then return this value as its own message result. Most window procedures process just a few types of messages and pass the others on to the system by calling DefWindowProc.

Because a window procedure is shared by all windows belonging to the same class, it can process messages for several different windows. To identify the specific window affected by the message, a window procedure can examine the window handle passed with a message. For more information about window procedures, see Chapter 4, »Window Procedures«.


  2.1.4  Posting and Sending Messages

Any application can post and send messages. Like the system, an application posts a message by copying it to a message queue and sends a message by passing the message data as arguments to a window procedure. To post and send messages, an application uses the PostMessage and SendMessage functions.

An application typically posts a message to notify a specific window to carry out a task. PostMessage creates an MSG structure for the message and copies the message to the message queue. The application's message loop eventually retrieves the message and dispatches it to the appropriate window procedure.

An application typically sends a message to notify a window procedure to carry out a task immediately. The SendMessage function sends the message to the window procedure corresponding to the given window. The function waits until the window procedure completes processing and then returns the message result. Parent and child windows often communicate by sending messages to each other. For example, a parent window that has an edit control as its child window can set the text of the control by sending a message to it. The control can notify the parent window of changes to the text that are carried out by the user by sending messages back to the parent.

Occasionally, an application may be required to send or post a message to all top-level windows in the system. For example, if the application changes the system time, it must notify all top-level windows about the change by sending a WM_TIMECHANGE message. An application can send or post a message to all top-level windows by calling the SendMessage or PostMessage function and specifying HWND_TOPMOST in the hwnd parameter.

An application can post a message without specifying a window. If the application supplies a NULL window handle when calling PostMessage, the message is posted to the queue associated with the current thread. Because no window handle is specified, the application must process the message in the message loop. This is one way to create a message that applies to the entire application instead of to a specific window.

By using the InSendMessage function, a window procedure can determine whether it is processing a message sent by another thread. This capability is useful when message processing depends on the origin of the message.

A common programming error is to assume that the PostMessage function always posts a message. This is not true when the message queue is full. An application should check the return value of the PostMessage function to determine whether the message has been posted and, if it has not been, repost it.


  2.1.5  Message Types

This section describes the two types of Windows messages: system defined and application defined.


  2.1.5.1  System-Defined Messages

The system uses system-defined messages to control the operations of applications and to provide input and other information for applications to process. The system sends or posts a system-defined message when it communicates with an application. An application can also send or post system-defined messages. Applications usually use these messages to control the operation of control windows created by using preregistered window classes.

Each system message has a unique message identifier and a corresponding symbolic constant (defined in the Windows header files) that states the purpose of the message. For example, the WM_PAINT constant requests that a window paint its contents.

Symbolic constants specify the category to which system-defined messages belong. The prefix of the constant identifies the type of window that can interpret and process the message. Following are the prefixes and their related message categories.

Prefix	Message category
BM	Button control
CB	Combo box control
DM	Default push button control
EM	Edit control
LB	List box control
SBM	Scroll bar control
WM	General window
General window messages cover a wide range of information and requests, including messages for mouse and keyboard input, menu and dialog box input, window creation and management, and dynamic data exchange (DDE).


  2.1.5.2  Application-Defined Messages

An application can create messages to use in its own windows or to communicate with windows in other processes. If an application creates its own messages, the window procedure that receives them must interpret the messages and provide appropriate processing.

Windows reserves message-identifier values in the range 0x0000 through 0x03FF (the value of WM_USER − 1) and 0x8000 through 0xBFFF for system-defined messages. Applications cannot use these values for private messages.

Values in the range 0x0400 (the value of WM_USER) through 0x7FFF are available for message identifiers defined by an application for its own use. Values in the range 0xC000 through 0xFFFF are available for message identifiers defined by an application for use in communicating with windows in other applications.

Windows returns a message identifier in the range 0xC000 through 0xFFFF when an application calls the RegisterWindowMessage function to register a message. The message identifier returned by this function is guaranteed to be unique throughout the system. If your application creates messages to communicate with windows in other applications, it should use RegisterWindowMessage to register the message. Use of this function prevents conflicts that can arise if other applications use the same message identifier for different purposes.


  2.1.6  Message Filtering

An application can choose specific messages to retrieve from the message queue (while ignoring other messages) by using the GetMessage or PeekMessage function to specify a message filter. This is a range of message identifiers (specified by a first and last identifier), a window handle, or both. GetMessage and PeekMessage use a message filter to select which messages to retrieve from the queue. Message filtering is useful if an application must search the message queue for messages that have arrived later in the queue.

Any application that filters messages must ensure that a message satisfying the message filter can be posted. For example, if an application filters for a WM_CHAR message in a window that does not receive keyboard input, the GetMessage function does not return. This effectively "hangs" the application.

To filter for keyboard, mouse, and DDE messages, an application can use the WM_KEYFIRST and WM_KEYLAST, WM_MOUSEFIRST and WM_MOUSELAST, and WM_DDE_FIRST and WM_DDE_LAST constants.


  2.1.7  Message Deadlocks

A thread that calls the SendMessage function to send a message to another thread cannot continue executing until the window procedure that receives the message returns. If the receiving thread yields control while processing the message, the sending thread cannot continue executing, because it is waiting for SendMessage to return. This situation is called a deadlock. The receiving thread need not yield explicitly; calling any of the following functions can cause a thread to yield control.

DialogBox
DialogBoxIndirect
DialogBoxIndirectParam
DialogBoxParam
GetMessage
MessageBox
PeekMessage

A window procedure can determine whether a message it has received was sent by another thread by calling the InSendMessage function. Before calling any of the functions in the preceding list while processing a message, the window procedure should first call InSendMessage. If this function returns TRUE, the window procedure must call the ReplyMessage function before any function that causes the thread to yield control.


  2.2  Using Messages and Message Queues

This section explains how to perform the following tasks:

•	Create a message loop

•	Examine a message queue

•	Post a message

•	Send a message


  2.2.1  Creating a Message Loop

Windows automatically creates a message queue for each thread. If the thread creates one or more windows, a message loop that retrieves messages from the thread's message queue and dispatches them to the appropriate window procedures must be provided.

Because Windows directs messages to individual windows in an application, a thread must create at least one window before starting its message loop. Most Windows-based applications contain a single thread that creates windows. A typical application registers the window class for its main window, creates and shows the main window, and then starts its message loop — all in the WinMain function.

You create a message loop by using the GetMessage and DispatchMessage functions. If your application must obtain character input from the user, include the TranslateMessage function in the loop. TranslateMessage translates virtual-key messages into character messages. The following example shows the message loop in the WinMain function of a simple Windows-based application.

HINSTANCE hinst;

HWND hwndMain;

int APIENTRY WinMain(hInstance, hPrevInstance, lpszCmdLine,

    nCmdShow)

HINSTANCE hInstance;

HINSTANCE hPrevInstance;

LPSTR lpszCmdLine;

int nCmdShow;

{

    MSG msg;

    WNDCLASS wc;

    UNREFERENCED_PARAMETER(lpszCmdLine);

    /* Register the window class for the main window. */

    if (!hPrevInstance) {

        wc.style = 0;

        wc.lpfnWndProc = (WNDPROC) WndProc;

        wc.cbClsExtra = 0;

        wc.cbWndExtra = 0;

        wc.hInstance = hInstance;

        wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION);

        wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);

        wc.hbrBackground = GetStockObject(WHITE_BRUSH);

        wc.lpszMenuName =  "MainMenu";

        wc.lpszClassName = "MainWndClass";

        if (!RegisterClass(&wc))

            return FALSE;

    }

    hinst = hInstance;  /* saves handle of application instance */

    /* Create the main window. */

    hwndMain = CreateWindow("MainWndClass", "Sample",

        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,

        CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,

        (HMENU) NULL, hinst, (LPVOID) NULL);

    /*

     * If the main window cannot be created, terminate

     * the application.

     */

    if (!hwndMain)

        return FALSE;

    /* Show the window and paint its contents. */

    ShowWindow(hwndMain, nCmdShow);

    UpdateWindow(hwndMain);

    /* Start the message loop. */

    while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    /* Return the exit code to Windows. */

    return msg.wParam;

}

The GetMessage, TranslateMessage, and DispatchMessage functions take a pointer to an MSG structure as a parameter. If a message is available, GetMessage copies it to the MSG structure. If the message is a virtual-key message (such as WM_KEYDOWN or WM_SYSKEYDOWN), TranslateMessage generates a character message (WM_CHAR or WM_SYSCHAR) and places it in the message queue. DispatchMessage uses the members of the MSG structure as arguments for the window procedure but does not return until the window procedure finishes processing the message.

If a thread supports accelerators, its message loop must include the TranslateAccelerator function. This function checks for key combinations that match an entry in the thread's accelerator table. When it finds a match, TranslateAccelerator translates the key combination into a WM_COMMAND message and dispatches it to the window procedure. For more information about accelerators, see Chapter 17, »Keyboard Accelerators«.

If a thread uses a modeless dialog box, the message loop must include the IsDialogMessage function so that the dialog box can receive keyboard input. For more information about dialog boxes, see Chapter 18, »Dialog Boxes«.

The following example shows a message loop for a thread that uses accelerators and displays a modeless dialog box. When TranslateAccelerator or IsDialogMessage returns TRUE (indicating that the message has been processed), TranslateMessage and DispatchMessage are not called. The reason for this is that TranslateAccelerator and IsDialogMessage perform all necessary translating and dispatching of messages.

HWND hwndMain;

HWND hwndDlgModeless = NULL;

MSG msg;

HACCEL haccel;

.

. /* Perform initialization and create a main window. */

.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

    if (hwndDlgModeless == (HWND) NULL ||

            !IsDialogMessage(hwndDlgModeless, &msg) &&

            !TranslateAccelerator(hwndMain, haccel, &msg)) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

}


  2.2.2  Examining a Message Queue

Occasionally, an application needs to examine the contents of a thread's message queue from outside the thread's message loop. For example, if an application's window procedure performs a lengthy drawing operation, you may want the user to be able to interrupt the operation. Unless your application periodically examines the message queue during the operation for mouse and keyboard messages, it will not respond to user input until after the operation has completed. The reason for this is that the DispatchMessage function in the thread's message loop does not return until the window procedure finishes processing a message.

You can use the PeekMessage function to examine a message queue during a lengthy operation. PeekMessage is similar to the GetMessage function; both check a message queue for a message that matches the filter criteria and then copy the message to an MSG structure. The main difference between them is that GetMessage does not return until a message matching the filter criteria is placed in the queue, whereas PeekMessage returns immediately regardless of whether a message is in the queue.

The following example shows how to use PeekMessage to examine a message queue for mouse clicks and keyboard input during a lengthy operation.

HWND hwnd;

BOOL fDone;

MSG msg;

/*

 * Begin the operation and continue until it is complete

 * or until the user clicks the mouse or presses a key.

 */

fDone = FALSE;

while (!fDone) {

    fDone = DoLengthyOperation(); /* application-defined */

    /*

     * Remove any messages that may be in the queue. If the

     * queue contains any mouse or keyboard

     * messages, end the operation.

     */

    while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) {

        switch(msg.message) {

            case WM_LBUTTONDOWN:

            case WM_RBUTTONDOWN:

            case WM_KEYDOWN:

                .

                . /* Perform any required cleanup. */

                .

                fDone = TRUE;

        }

    }

}

Other functions, including GetQueueStatus and GetInputState, also allow you to examine the contents of a thread's message queue. GetQueueStatus returns an array of flags that indicates the types of messages in the queue; using it is the fastest way to discover whether the queue contains any messages. GetInputState returns TRUE if the queue contains mouse or keyboard messages. Both of these functions can be used to determine whether the queue contains messages that need to be processed.


  2.2.3  Posting a Message

You can post a message to a message queue by using the PostMessage function. PostMessage places a message at the end of a thread's message queue and returns immediately, without waiting for the thread to process the message. The function's parameters include a window handle, a message identifier, and two message parameters. Windows copies these parameters to an MSG structure, fills the time and pt members of the structure, and places the structure in the message queue.

Windows uses the window handle passed with the PostMessage function to determine which thread message queue should receive the message. If the handle is HWND_TOPMOST, Windows posts the message to the thread message queues of all top-level windows.

You can use the PostThreadMessage function to post a message to a specific thread message queue. PostThreadMessage is similar to PostMessage, except the first parameter is a thread identifier rather than a window handle. You can retrieve the thread identifier by calling the GetCurrentThreadId function.

Use the PostQuitMessage function to exit a message loop. PostQuitMessage posts the WM_QUIT message to the currently executing thread. The thread's message loop terminates and returns control to Windows when it encounters the WM_QUIT message. An application usually calls PostQuitMessage in response to the WM_DESTROY message, as shown in the following example.

case WM_DESTROY:

    .

    . /* Perform cleanup tasks. */

    .

    PostQuitMessage(0);

    break;


  2.2.4  Sending a Message

The SendMessage function is used to send a message directly to a window procedure. SendMessage calls a window procedure and waits for that procedure to process the message and return a result.

A message can be sent to any window in the system; all that is required is a window handle. Windows uses the handle to determine which window procedure should receive the message.

If a window procedure yields control when processing a message sent by another thread, a message deadlock may result (For more information about message deadlocks, see Section 2.1.7, »Message Deadlocks«.) Before processing a message that may have been sent from another thread, a window procedure should first call the InSendMessage function. If this function returns TRUE, the window procedure should call ReplyMessage before any function that causes the thread to yield control, as shown in the following example.

case WM_USER + 5:

    if (InSendMessage())

        ReplyMessage(TRUE);

    DialogBox(hInst, "MyDialogBox", hwndMain, (DLGPROC) MyDlgProc);

    break;

A number of messages can be sent to controls in a dialog box. These control messages set the appearance, behavior, and content of controls or retrieve information about controls. For example, the CB_ADDSTRING message can add a string to a combo box, and the BM_SETCHECK message can set the check state of a check box or radio button.

Use the SendDlgItemMessage function to send a message to a control, specifying the identifier of the control and the handle of the dialog box window that contains the control. The following example, taken from a dialog box procedure, copies a string from a combo box's edit control into its list box. The example uses SendDlgItemMessage to send a CB_ADDSTRING message to the combo box.

HWND hwndCombo;

int cTxtLen;

PSTR pszMem;

switch (uMsg) {

    case WM_COMMAND:

        switch (LOWORD(wParam)) {

            case IDD_ADDCBITEM:

                /*

                 * Get the handle of the combo box and the

                 * length of the string in the edit control of

                 * the combo box.

                 */

                hwndCombo = GetDlgItem(hwndDlg, IDD_COMBO);

                cTxtLen = GetWindowTextLength(hwndCombo);

                /*

                 * Allocate memory for the string and copy

                 * the string into the memory.

                 */

                pszMem = (PSTR) VirtualAlloc((LPVOID) NULL,

                    (DWORD) (cTxtLen + 1), MEM_COMMIT,

                    PAGE_READWRITE);

                GetWindowText(hwndCombo, pszMem, cTxtLen + 1);

                /*

                 * Add the string to the list box of the

                 * combo box and remove the string from the

                 * edit control of the combo box.

                 */

                if (*pszMem != NULL) {

                    SendDlgItemMessage(hwndDlg, IDD_COMBO,

                        CB_ADDSTRING, 0,

                        (DWORD) ((LPSTR) pszMem));

                    SetWindowText(hwndCombo, (LPSTR) NULL);

                }

                /* Free the memory and return. */

                VirtualFree(pszMem, 0, MEM_RELEASE);

                return TRUE;

            .

            . /* Process other dialog box commands. */

            .

        }

    .

    . /* Process other dialog box messages. */

    .

}


  2.3  Functions

Following are the functions used with messages and message queues.

CallWndProc
DefWindowProc
DispatchMessage
GetInputState
GetMessage
GetMessageExtraInfo
GetMessagePos
GetMessageTime
GetMsgProc
GetQueueStatus
InSendMessage
IsDialogMessage
IsWindowUnicode
PeekMessage
PostMessage
PostQuitMessage
PostThreadMessage
RegisterWindowMessage
ReplyMessage
SendDlgItemMessage
SendMessage
SendNotifyMessage
TranslateAccelerator
TranslateMessage
WaitMessage


3.1  About Window Classes
  Chapter 3    Window Classes

3.1  About Window Classes

Every window is a member of a window class. A window class is a set of attributes that Microsoft® Windows (™)  uses as a template to create a window in an application. Each window class has an associated window procedure shared by all windows of the same class. The window procedure processes messages for all windows of that class and therefore controls their behavior and appearance. For more information about window procedures, see Chapter 4, »Window Procedures«.

An application must register a window class before it can create a window of that class. Registering a window class associates a window procedure, class styles, and other class attributes with a class name. When an application specifies a class name in the CreateWindow or CreateWindowEx function, the operating system creates a window with the window procedure, styles, and other attributes associated with that class name.


  3.1.1  Types of Window Classes

There are three types of window classes: system global, application global, and application local. These types differ in scope and in when and how they are registered and destroyed.


  3.1.1.1  System Global Classes

When Windows starts, it registers a set of system global classes for controls, including buttons, combo boxes, list boxes, scroll bars, edit controls, and static controls. For more information about controls, see Chapter 9, »Controls«, through Chapter 15, »Static Controls«. Any application can use a system global class at any time. Because Windows registers system global classes on behalf of all applications, an application cannot destroy any of these classes.


  3.1.1.2  Application Global Classes

An application global class is a window class registered by a dynamic-link library (DLL) and available to all applications in the system. For example, you can register a window class that defines a custom control as an application global class so that all applications can create instances of the custom control.

In Windows, all window classes are process specific. An application can create a global class by creating the window class in a DLL and listing the name of the DLL in the registration database under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\
    CurrentVersion\Windows\APPINIT_DLLS

Whenever a process starts, the system loads the specified DLL in the context of the newly started process before calling the main function in that process. The DLL must register the class during its initialization procedure and must specify the CS_GLOBALCLASS style. For more information about class styles, see Section 3.1.4.8, »Class Styles«. After a class has been registered, any application can use it to create any number of windows belonging to that class.

Windows destroys an application global class when the DLL that registered it is unloaded. For this reason, all applications must destroy all windows that belong to an application global class before unloading that DLL. Use the UnregisterClass function to remove an application global class and free the storage associated with it.


  3.1.1.3  Application Local Classes

An application local class is any window class that an application registers for its exclusive use. Although an application can register any number of local classes, most applications register only one. This window class supports the window procedure of the application's main window.

Registering a local class is similar to registering an application global class, except that the CS_GLOBALCLASS style is not specified in the style member of the WNDCLASS structure.

Windows destroys a local class when the application that registered it closes. An application can also use the UnregisterClass function to remove a local class and free the storage associated with it.


  3.1.2  How Windows Locates a Class

Windows maintains a list of WNDCLASS structures for each of the three types of window classes. When an application calls the CreateWindow or CreateWindowEx function to create a window with a specified class, Windows uses the following procedure to locate the class:

1.	Windows searches the list of application local classes for a class with the specified name.

2.	If the name is not in the application local class list, Windows searches the list of application global classes.

3.	If the name is not in the application global class list, Windows searches the list of system global classes.

All windows created by the application use this procedure, including windows created by Windows on the application's behalf, such as dialog boxes. It is possible to override system global classes without affecting other applications. That is, an application can register an application local class having the same name as a system global class. This replaces the system global class in the context of the application but does not prevent other applications from using the system global class.


  3.1.3  Class Ownership

The owner of a class is the application or DLL that registered the class. Windows determines class ownership from the hInstance member of the WNDCLASS structure passed to the RegisterClass function when the class is registered. For Windows DLLs, the hInstance member must be the instance handle of the DLL. The class is destroyed when the owner closes or is unloaded. For this reason, the application must destroy all windows using the class before it closes or the DLL is unloaded.


  3.1.4  Elements of a Window Class

The elements of a window class define the default behavior of windows belonging to the class. The application that registers a window class assigns elements to the class by setting appropriate members in a WNDCLASS structure and passing the structure to the RegisterClass function. The GetClassInfo and GetClassLong functions retrieve information about a given window class. The SetClassLong function changes elements of a local or global class that the application has already registered.

Although a complete window class consists of many elements, Windows requires only that an application supply a class name, the window-procedure address, and an instance handle. Use the other elements to define default attributes for windows of the class, such as the shape of the cursor and the content of the menu for the window. The window class elements are as follows.

Element	Purpose
Class name	Distinguishes the class from other registered classes.
Window-procedure address	Points to the function that processes all messages sent to windows in the class and defines the behavior of the window.
Instance handle	Identifies the application or DLL that registered the class.
Class cursor	Defines the shape of the cursor in a window of the class.
Class icon	Defines the shape of the icon when a window belonging to the class is minimized.
Class background brush	Defines the color and pattern that fill the client area when the window is opened or painted.
Class menu	Specifies the default menu for windows that do not explicitly define a menu.
Class styles	Defines how to update the window after moving or resizing it, how to process double-clicks of the mouse, how to allocate space for the device context, and other aspects of the window.
Extra class memory	Specifies the amount of extra memory, in bytes, that Windows should reserve for the class. All windows in the class share the extra memory and can use it for any application-defined purpose. Windows initializes this memory to zero.
Extra window memory	Specifies the amount of extra memory, in bytes, that Windows should reserve for each window belonging to the class. The extra memory can be used for any application-defined purpose. Windows initializes this memory to zero.


  3.1.4.1  Class Name

Every window class needs a class name to distinguish one class from another. Assign a class name by setting the lpszClassName member of the WNDCLASS structure to the address of a null-terminated string that specifies the name. Because window classes are process specific in Windows, window class names need to be unique only within the same process.

The GetClassName function retrieves the name of the class to which a given window belongs.


  3.1.4.2  Window-Procedure Address

Every class needs a window-procedure address to define the entry point of the window procedure used to process all messages for windows in the class. Windows passes messages to the procedure when it requires the window to carry out tasks, such as painting its client area or responding to input from the user. An application assigns a window procedure to a class by copying its address to the lpfnWndProc member of the WNDCLASS structure. The window procedure must be exported in the module-definition (.DEF) file. For more information about window procedures, see Chapter 4, »Window Procedures«.


  3.1.4.3  Instance Handle

Every window class requires an instance handle to identify the application or DLL that registered the class. As a multitasking system, Windows lets several applications or DLLs run at the same time, so it requires instance handles to keep track of all of them. Windows assigns a handle to each copy of a running application or DLL.

Multiple instances of the same application or DLL all use the same code segment, but each has its own data segment. Windows uses an instance handle to identify the data segment that corresponds to a particular instance of an application or DLL.

Windows passes an instance handle to an application or DLL when the application starts. The application or DLL assigns this instance handle to the class by copying it to the hInstance member of the WNDCLASS structure.


  3.1.4.4  Class Cursor

The class cursor defines the shape of the cursor when it is in the client area of a window in the class. Windows automatically sets the cursor to the given shape when the cursor enters the window's client area and ensures it keeps that shape while it remains in the client area. To assign a cursor shape to a window class, load a predefined cursor shape by using the LoadCursor function and then assign the returned cursor handle to the hCursor member of the WNDCLASS structure. Alternatively, provide a custom cursor resource and use the LoadCursor function to load it from the application's resources.

Windows does not require a class cursor. If an application sets the hCursor member of the WNDCLASS structure to NULL, a class cursor is not defined. Windows assumes the window sets the cursor shape each time the cursor moves into the window. A window can set the cursor shape by calling the SetCursor function whenever the window receives the WM_MOUSEMOVE message. For more information about cursors, see Chapter 21, »Cursors«.


  3.1.4.5  Class Icon

The class icon defines the shape of the icon used when the window of the given class is minimized. To assign an icon to a window class, load the icon from the application's resources by using the LoadIcon function and then assign the returned icon handle to the hIcon member of the WNDCLASS structure. For more information about icons, see Chapter 23, »Icons«.

Windows does not require that a window class have a class icon. If an application sets the hIcon member of the WNDCLASS structure to NULL, a class icon is not defined. In this case, Windows sends the WM_ICONERASEBKGND message to a window of the class whenever it must paint the background of the icon. If the window does not process the WM_ICONERASEBKGND message, Windows draws an image of the contents of the window's client area onto the icon when it is minimized.


  3.1.4.6  Class Background Brush

A class background brush prepares the client area of a window for subsequent drawing by the application. Windows uses the brush to fill the client area with a solid color or pattern, thereby removing all previous images from that location whether they belonged to the window or not. Windows notifies a window that its background should be painted by sending the WM_ERASEBKGND message to the window. For more information about brushes, see Chapter 30, »Brushes«.

To assign a background brush to a class, create a brush by using the appropriate functions from the graphics device interface (GDI) and assign the returned brush handle to the hbrBackground member of the WNDCLASS structure.

Instead of creating a brush, an application can set the hbrBackground member to one of the standard system color values. For a list of the standard system color values, see the description of the SetSysColors function in the Microsoft Win32 Programmer's Reference, Volume 4.

To use a standard system color, the application must increase the background-color value by one. For example, COLOR_BACKGROUND + 1 is the system background color.

Windows does not require that a window class have a class background brush. If this parameter is set to NULL, the window must paint its own background whenever it receives the WM_ERASEBKGND message.


  3.1.4.7  Class Menu

A class menu defines the default menu to be used by the windows in the class if no explicit menu is given when the windows are created. A menu is a list of commands from which a user can choose actions for the application to carry out.

To assign a menu to a class, set the lpszMenuName member of the WNDCLASS structure to the address of a null-terminated string that specifies the resource name of the menu. The menu is assumed to be a resource in the given application. Windows automatically loads the menu when it is needed. Note that if the menu resource is identified by an integer and not by a name, the application can set the lpszMenuName member to that integer by applying the MAKEINTRESOURCE macro before assigning the value.

Windows does not require a class menu. If an application sets the lpszMenuName member of the WNDCLASS structure to NULL, Windows assumes the windows in the class have no menu bars. Even if no class menu is given, an application can still define a menu bar for a window when it creates the window.

Windows does not allow menu bars with child windows. If a menu is given for a class and a child window of that class is created, the menu is ignored. For more information about menus, see Chapter 16, »Menus«.


  3.1.4.8  Class Styles

The class styles define additional elements of the window class. Two or more styles can be combined by using the bitwise OR (|) operator. To assign a style to a window class, assign the style to the style member of the WNDCLASS structure. The class styles are as follows.

Style	Action
CS_BYTEALIGNCLIENT	Aligns the window's client area on a byte boundary (in the x direction) to enhance performance during drawing operations. This style affects the width of the window and its horizontal placement on the display.
CS_BYTEALIGNWINDOW	Aligns the window on a byte boundary (in the x direction) to enhance performance during operations that involve moving or sizing the window. This style affects the width of the window and its horizontal placement on the display.
CS_CLASSDC	Allocates one device context to be shared by all windows in the class. For more information about device contexts, see Section 3.1.5, »Class and Private Device Contexts«, and Chapter 28, »Device Contexts«.
CS_DBLCLKS	Instructs Windows to send a double-click message to the window procedure when the user double-clicks the mouse while the cursor is within a window belonging to the class. For more information about double-clicks, see Chapter 6, »Mouse Input«.
CS_GLOBALCLASS	Specifies that the window class is an application global class. For more information, see Section 3.1.1.2, »Application Global Classes«.
CS_HREDRAW	Specifies that the entire window is to be redrawn if a movement or size adjustment changes the width of the client area.
CS_NOCLOSE	Disables the Close command on the System menu.
CS_OWNDC	Allocates a unique device context for each window in the class. For more information about device contexts, see Section 3.1.5, »Class and Private Device Contexts«, and Chapter 28, »Device Contexts«.
CS_PARENTDC	Gives the parent window's device context to the child windows. For more information about device contexts, see Section 3.1.5, »Class and Private Device Contexts«, and Chapter 28, »Device Contexts«.
CS_SAVEBITS	Saves, as a bitmap, the portion of the screen image obscured by a window. Windows uses the saved bitmap to re-create the screen image when the window is removed. Windows displays the bitmap at its original location and does not send WM_PAINT messages to windows obscured by the window if other screen actions have not invalidated the stored image. Use this style for small windows that are displayed briefly and then removed before other screen activity takes place (for example, menus or dialog boxes). This style increases the time required to display the window, because the operating system must first allocate memory to store the bitmap.
CS_VREDRAW	Specifies that the entire window is to be redrawn if a movement or size adjustment changes the height of the client area.


  3.1.4.9  Extra Class Memory

Windows maintains a WNDCLASS structure internally for each window class in the system. When an application registers a window class, it can direct Windows to allocate and append a number of additional bytes of memory to the end of the WNDCLASS structure. This memory is called extra class memory and is shared by all windows belonging to the class. Use the extra class memory to store any information pertaining to the class.

The SetClassWord and SetClassLong functions copy a value to the extra class memory. To retrieve a value from the extra class memory, use the GetClassWord and GetClassLong functions. The cbClsExtra member of the WNDCLASS structure specifies the amount of extra class memory to allocate. An application that doesn't use extra class memory must initialize the cbClsExtra member to zero.


  3.1.4.10  Extra Window Memory

Windows maintains an internal data structure for each window. When registering a window class, an application can specify a number of additional bytes of memory, called extra window memory. When creating a window of the class, Windows allocates and appends the specified amount of extra window memory to the end of the window's structure. An application can use this memory to store window-specific data.

The SetWindowWord and SetWindowLong functions copy a value to the extra memory. The GetWindowWord and GetWindowLong functions retrieve a value from the extra window memory. The cbWndExtra member of the WNDCLASS structure specifies the amount of extra window memory to allocate. An application that doesn't use extra window memory must initialize the cbWndExtra member to zero.


  3.1.5  Class and Private Device Contexts

A device context is a special set of values that applications use for drawing in the client area of their windows. Windows requires a device context for each window on the display but allows some flexibility in how the operating system stores and treats that device context.

If no device-context style is explicitly given, Windows assumes each window uses a device context retrieved from a pool of contexts maintained by Windows. In such cases, each window must retrieve and initialize the device context before painting and free it after painting.

To avoid retrieving a device context each time it needs to paint inside a window, an application can specify the CS_OWNDC style for the window class. This class style directs Windows to create a private device context — that is, to allocate a unique device context for each window in the class. The application need retrieve the context only once and then use it for all subsequent painting. Although the CS_OWNDC style is convenient, use it carefully, because each device context uses a significant portion of system resources.

By specifying the CS_CLASSDC style, an application can create a class device context. A class device context is a rarely used feature that allows multiple windows created from the same window class within a process to use exactly the same device context for drawing.

An application can specify the CS_PARENTDC style to create child windows that inherit the device context of their parent window. This style allows a child window to draw in the client area of its parent.

For more information about device contexts, see Chapter 28, »Device Contexts«. For more information about painting, see Chapter 20, »Painting and Drawing«.


  3.2  Using Window Classes

In Windows, each application must register its own window classes. Your application can register an application local class at any time by using the RegisterClass function. You must define the window procedure in the application, fill the members of the WNDCLASS structure, and then pass a pointer to the structure to the RegisterClass function.

The following example shows how to register a local window class and use it to create your application's main window.

#include <windows.h>

/* Global variable */

HINSTANCE hinst;

/* Function prototypes */

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);

InitApplication(HINSTANCE);

InitInstance(HINSTANCE, int);

LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

/* Application entry point */

int WINAPI WinMain(hinstance, hPrevInstance, lpCmdLine, nCmdShow)

HINSTANCE hinstance;

HINSTANCE hPrevInstance;

LPSTR lpCmdLine;

int nCmdShow;

{

    MSG msg;

    if (!InitApplication(hinstance))

        return FALSE;

    if (!InitInstance(hinstance, nCmdShow))

        return FALSE;

    while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return msg.wParam;

        UNREFERENCED_PARAMETER(lpCmdLine);

}

BOOL InitApplication(hinstance)

HINSTANCE hinstance;

{

    WNDCLASS wc;

    /*

     * Fill in the window class structure with parameters

     * that describe the main window.

     */

    wc.style = CS_HREDRAW |

        CS_VREDRAW;                    /* redraw if size changes */

    wc.lpfnWndProc = MainWndProc;      /* points to window proc. */

    wc.cbClsExtra = 0;                 /* no extra class memory  */

    wc.cbWndExtra = 0;                 /* no extra window memory */

    wc.hInstance = hinstance;          /* handle of instance     */

    wc.hIcon = LoadIcon(NULL,

        IDI_APPLICATION);              /* predefined app. icon   */

    wc.hCursor = LoadCursor(NULL,

        IDC_ARROW);                    /* predefined arrow       */

    wc.hbrBackground = GetStockObject(

        WHITE_BRUSH);                  /* white background brush */

    wc.lpszMenuName =  "MainMenu";     /* name of menu resource  */

    wc.lpszClassName = "MainWClass";   /* name of window class   */

    /* Register the window class. */

    return RegisterClass(&wc);

}

BOOL InitInstance(hinstance, nCmdShow)

HINSTANCE hinstance;

int nCmdShow;

{

    HWND hwnd;

    /* Save the application-instance handle. */

    hinst = hinstance;

    /* Create the main window. */

    hwnd = CreateWindow(

        "MainWClass",        /* name of window class        */

        "Sample",            /* title-bar string            */

        WS_OVERLAPPEDWINDOW, /* top-level window            */

        CW_USEDEFAULT,       /* default horizontal position */

        CW_USEDEFAULT,       /* default vertical position   */

        CW_USEDEFAULT,       /* default width               */

        CW_USEDEFAULT,       /* default height              */

        (HWND) NULL,         /* no owner window             */

        (HMENU) NULL,        /* use class menu              */

        hinstance,           /* handle of app. instance     */

        (LPVOID) NULL);      /* no window-creation data     */

    if (!hwnd)

        return FALSE;

     /*

      * Show the window and send a WM_PAINT message to the window

      * procedure.

      */

    ShowWindow(hwnd, nCmdShow);

    UpdateWindow(hwnd);

    return TRUE;

}

Registering an application global class is similar to registering an application local class, with the following exceptions:

•	The style parameter of the WNDCLASS structure must specify the CS_GLOBALCLASS style.

•	The class can be registered in the context of either an application or a DLL.

•	The application or DLL need not check for a previous instance of the application or DLL before registering the class.


  3.3  Functions

Following are the functions used with window classes.

GetClassInfo
GetClassLong
GetClassName
GetClassWord
GetWindowLong
GetWindowWord
RegisterClass
SetClassLong
SetClassWord
SetWindowLong
SetWindowWord
UnregisterClass


4.1  About Window Procedures
  Chapter 4    Window Procedures

4.1  About Window Procedures

In Microsoft® Windows (™) , every window has an associated window procedure — a function that processes all messages sent or posted to all windows of the class. All aspects of a window's appearance and behavior depend on the window procedure's response to these messages.

Each window is a member of a particular window class. The window class determines the window procedure that an individual window uses to process its messages. All windows belonging to the same class use the same window procedure. For example, the system defines a window procedure for the combo box class (COMBOBOX), and all combo boxes use that window procedure.

An application typically registers at least one new window class and an associated window procedure. After registering a class, the application can create many windows of that class, all of which use the same window procedure. Because this means several sources could simultaneously call the same piece of code, the developer must be careful when modifying shared resources from a window procedure. For more information about window classes, see Chapter 3, »Window Classes«.

Dialog box procedures have the same structure and function as window procedures. All points referring to window procedures in this section also apply to dialog box procedures. For more information about dialog boxes, see Chapter 18, »Dialog Boxes«.


  4.1.1  Structure of a Window Procedure

A window procedure is a function that has four parameters and returns a 32-bit signed value. The parameters consist of a window handle, a UINT message identifier, and two message parameters declared with the WPARAM and LPARAM data types. The operating system defines a WPARAM value as a 32-bit unsigned integer and an LPARAM value as a 32-bit signed integer.

The window procedure parameters are described in the following table.

Parameter	Description
hwnd	Handle of the window receiving the message.
uMsg	Message identifier. The identifier corresponds to one of the predefined constants (for example, WM_CREATE) defined in the system header files or to an application-defined message identifier.
wParam, lParam	Message parameters. Their interpretation depends on the value of the uMsg parameter.
Message parameters often contain information in both their low-order and high-order words. The Win32 application programming interface (API) includes several macros an application can use to extract information from the message parameters. The LOWORD macro, for example, extracts the low-order word (bits 0 through 15) from a message parameter. Other macros include HIWORD, LOBYTE, and HIBYTE.

The return value of a window procedure is declared as an LRESULT data type, which is defined as a 32-bit signed value. The interpretation of the return value depends on the particular message. Consult the description of each message to determine the appropriate return value.

Because it is possible to call a window procedure recursively, it is important to minimize the number of local variables that it uses. When processing individual messages, an application should call functions outside the window procedure to avoid excessive use of local variables, possibly causing the stack to overflow during deep recursion.


  4.1.2  Default Window Procedure

The default window procedure function DefWindowProc defines certain fundamental behavior shared by all windows. The default window procedure provides the minimal functionality for a window. An application-defined window procedure should pass any messages that it does not process to the DefWindowProc function for default processing.


  4.1.3  Window Procedure Subclassing

When an application creates a window, the operating system allocates a block of memory for storing information specific to the window, including the address of the window procedure that processes messages for the window. When Windows needs to pass a message to the window, it searches the window-specific information for the address of the window procedure and passes the message to that procedure.

Subclassing is a technique that allows an application to intercept and process messages sent or posted to a particular window before the window has a chance to process them. By subclassing a window, an application can augment, modify, or monitor the behavior of the window. An application can subclass any window, including those belonging to a system global class, such as an edit control or a list box. For example, an application could subclass an edit control to prevent the control from accepting certain characters.

An application subclasses a window by replacing the address of the window's original window procedure with the address of a new window procedure, called the subclass procedure. Thereafter, the subclass procedure receives any messages sent or posted to the window.

The subclass procedure can take three actions when it receives a message: it can pass the message to the original window procedure, modify the message and pass it to the original window procedure, or process the message and not pass it to the original window procedure. If the subclass procedure processes a message, it can do so before, after, or both before and after it passes the message to the original window procedure.

Windows provides two types of subclassing: instance and global. In instance subclassing, an application replaces the window procedure address of a single instance of a window. An application must use instance subclassing to subclass an existing window. In global subclassing, an application replaces the address of the window procedure in the WNDCLASS structure of a window class. All subsequent windows created with the class have the address of the subclass procedure, but existing windows of the class are not affected.


  4.1.3.1  Instance Subclassing

An application subclasses an instance of a window by using the SetWindowLong function. The application passes the GWL_WNDPROC flag, the handle of the window to subclass, and the address of the subclass procedure to SetWindowLong. The subclass procedure can reside in either the application's module or a dynamic-link library (DLL). An application must list the name of the subclass procedure in the EXPORTS statement of the application's or DLL's module-definition (.DEF) file.

SetWindowLong returns the address of the window's original window procedure. The application must save the address, using it in subsequent calls to the CallWindowProc function, to pass intercepted messages to the original window procedure. The application also needs the original window procedure address to remove the subclass from the window. To do so, the application calls SetWindowLong again, passing the address of the original window procedure with the GWL_WNDPROC flag and the handle of the window.

An application can subclass any window in the system; however, when subclassing a window it does not own, the application must ensure the subclass procedure does not destroy the original behavior of the window. Because the application does not control the window, it must not depend on information about the window that the owner might change in the future.

An application should not use the extra window bytes or the class bytes for a window without knowing exactly what the bytes mean and how the original window procedure uses them. Even so, the application should not use them unless it owns the window. If the application uses the extra window bytes of a window that another application owns and the owner changes some aspect of the extra bytes, the subclass procedure may fail. For this reason, an application should not subclass a window that belongs to a system global control class. Windows owns the system global classes, and aspects of the controls might change from one version of Windows to the next. If the application must subclass a window that belongs to a system global class, the developer may need to update the application when a new version of Windows is released.

Because instance subclassing occurs after a window is created, the application subclassing the window cannot add any extra bytes to the window. Applications that subclass a window should use the window's property list to store any data needed for an instance of the subclassed window. For more information about window properties, see Chapter 24, »Window Properties«.

When an application subclasses a subclassed window, it must remove the subclasses in the reverse order they were performed. If the removal order is not reversed, an unrecoverable system error may occur.


  4.1.3.2  Global Subclassing

To globally subclass a window class, the application must have a handle of a window of the class. The application also needs the handle to remove the subclass. To get the handle, an application typically creates a hidden window of the class to be subclassed. After obtaining the handle, the application calls the SetClassLong function, specifying the handle, the GCL_WNDPROC flag, and the address of the subclass procedure. SetClassLong returns the address of the original window procedure for the class.

The original window procedure address is used in global subclassing in the same way it is used in instance subclassing. The subclass procedure passes messages to the original window procedure by calling the CallWindowProc function. The application removes the subclass from the window class by calling SetClassLong again, specifying the address of the original window procedure, the GCL_WNDPROC flag, and the handle of a window of the class being subclassed. An application that globally subclasses a control class must remove the subclass when the application terminates; otherwise, an unrecoverable system error may occur.

Global subclassing has the same limitations as instance subclassing, plus some additional restrictions. An application should not use the extra bytes for either the class or the window instance without knowing exactly how the original window procedure uses them. If the application must associate data with a window, it should use window properties.

An application must not globally subclass a system global class. An unrecoverable system error may occur if more than one application globally subclasses a control class. If the application could benefit from globally subclassing a control class, use the technique called superclassing, described in the following section.


  4.1.4  Window Procedure Superclassing

Superclassing is a technique that allows an application to create a new window class with the basic functionality of the existing class, plus enhancements provided by the application. A superclass is based on an existing window class called the base class. Frequently, the base class is a system global window class such as an edit control, but it can be any window class.

Note   An application must not superclass the system global SCROLLBAR class.

A superclass has its own window procedure, called the superclass procedure. The superclass procedure can take three actions with a message: it can pass the message to the original window procedure, modify the message and pass it to the original window procedure, or process the message and not pass it to the original window procedure. If the superclass procedure processes a message, it can do so before, after, or both before and after it passes the message to the original window procedure.

Unlike a subclass procedure, a superclass procedure can process window creation messages (WM_NCCREATE, WM_CREATE, and so on), but it must also pass them to the original base-class window procedure so that the base-class window procedure can perform its initialization procedure.

To superclass a window class, an application first calls the GetClassInfo function to retrieve information about the base class. GetClassInfo fills a WNDCLASS structure with the values from the WNDCLASS structure of the base class. Next, the application copies its own instance handle into the hInstance member of the WNDCLASS structure and copies the name of the superclass into the lpszClassName member. If the base class has a menu, the application must provide a new menu with the same menu identifiers and copy the menu name into the lpszMenuName member. If the superclass procedure processes the WM_COMMAND message and does not pass it to the window procedure of the base class, the menu does not need to have corresponding identifiers. The GetClassInfo function does not return the lpszMenuName, lpszClassName, or hInstance member of the WNDCLASS structure.

An application must also set the lpfnWndProc member of the WNDCLASS structure. The GetClassInfo function fills this member with the address of the original window procedure for the class. The application must save this address, to pass messages to the original window procedure, and then copy the address of the superclass procedure into the lpfnWndProc member. The application can, if necessary, modify any other members of the WNDCLASS structure. After it fills the WNDCLASS structure, the application registers the superclass by passing the address of the structure to the RegisterClass function. The superclass can then be used to create windows.

Because superclassing registers a new window class, an application can add to both the extra class bytes and the extra window bytes. The superclass must not use the original extra bytes for the base class or the window for the same reasons that an instance subclass or a global subclass should not use them. Also, if the application adds extra bytes for its use to either the class or the window instance, it must reference the extra bytes relative to the number of extra bytes used by the original base class. Because the number of bytes used by the base class may vary from one version of the base class to the next, the starting offset for the superclass's own extra bytes may also vary from one version of the base class to the next.


  4.2  Using Window Procedures

This section explains how to perform the following tasks:

•	Design a window procedure

•	Associate a window procedure with a window class

•	Subclass a window


  4.2.1  Designing a Window Procedure

The following example shows the structure of a typical window procedure. The window procedure uses the message argument in a switch statement with individual messages handled by separate case statements. Notice that each case returns a specific value for each message. For messages that it does not process, the window procedure calls the DefWindowProc function.

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;      /* handle of the window     */

UINT uMsg;      /* message identifier       */

WPARAM wParam;  /* first message parameter  */

LPARAM lParam;  /* second message parameter */

{

    switch (uMsg) {

        case WM_CREATE:

            /* Initialize the window. */

            return 0;

        case WM_PAINT:

            /* Paint the window's client area. */

            return 0;

        case WM_SIZE:

            /* Set the size and position of the window. */

            return 0;

        case WM_DESTROY:

            /* Clean up window-specific data objects. */

            return 0;

        .

        . /* Process other messages. */

        .

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return 0;

}

At the very least, a window procedure should process the WM_PAINT message to draw itself. Typically, it should handle mouse and keyboard messages as well. Consult the descriptions of individual messages to determine whether your window procedure should handle them.

Your application can call the DefWindowProc function as part of the processing of a message. In such a case, the application can modify the message parameters before passing the message to DefWindowProc, or it can continue with the default processing after performing its own operations.

A dialog box procedure receives a WM_INITDIALOG message instead of a WM_CREATE message and does not pass unprocessed messages to the DefDlgProc function. Otherwise, a dialog box procedure is exactly the same as a window procedure. For more information about dialog box procedures, see Chapter 18, »Dialog Boxes«.


  4.2.2  Associating a Window Procedure with a Window Class

You associate a window procedure with a window class when registering the class. You must fill a WNDCLASS structure with information about the class, and the lpfnWndProc member must specify the address of the window procedure. To register the class, pass the address of WNDCLASS structure to the RegisterClass function. Once the window class is registered, the window procedure is automatically associated with each new window created with that class.

The following example shows how to associate the window procedure in the previous example with a window class.

int APIENTRY WinMain(hinstance, hinstPrev, lpCmdLine, nCmdShow)

HINSTANCE hinstance;  /* handle of current instance     */

HINSTANCE hinstPrev;  /* handle of previous instance    */

LPSTR lpCmdLine;      /* address of command-line string */

int nCmdShow;         /* show-window type               */

{

    WNDCLASS wc;

    /* Register the main window class. */

    wc.style = CS_HREDRAW | CS_VREDRAW;

    wc.lpfnWndProc = (WNDPROC) MainWndProc;

    wc.cbClsExtra = 0;

    wc.cbWndExtra = 0;

    wc.hInstance = hinstance;

    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground = GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName =  "MainMenu";

    wc.lpszClassName = "MainWindowClass";

    if (!RegisterClass(&wc))

       return FALSE;

    .

    . /* Process other messages. */

    .

}


  4.2.3  Subclassing a Window

To subclass an instance of a window, call the SetWindowLong function and specify the GWL_WNDPROC flag, the handle of the window to subclass, and a pointer to the subclass procedure. The SetWindowLong function returns a pointer to the original window procedure; use this pointer to pass messages to the original procedure.

The following example shows how to subclass an instance of an edit control in a dialog box. The subclass window procedure allows the edit control to receive all keyboard input, including the ENTER and TAB keys, whenever the control has the input focus.

WNDPROC wpOrigEditProc;

LRESULT APIENTRY EditBoxProc(hwndDlg, uMsg, wParam, lParam)

HWND hwndDlg;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    HWND hwndEdit;

    switch(uMsg) {

        case WM_INITDIALOG:

            /* Retrieve the handle of the edit control. */

            hwndEdit = GetDlgItem(hwndDlg, ID_EDIT);

            /* Subclass the edit control. */

            wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit,

                GWL_WNDPROC, (LONG) EditSubclassProc);

            .

            . /* Continue the initialization procedure. */

            .

            return TRUE;

        case WM_DESTROY:

            /* Remove the subclass from the edit control. */

            SetWindowLong(hwndEdit, GWL_WNDPROC,

                (LONG) wpOrigEditProc);

            .

            . /* Continue the cleanup procedure. */

            .

            break;

    }

    return FALSE;

        UNREFERENCED_PARAMETER(lParam);

}

/*

 * Subclass procedure

 */

LRESULT APIENTRY EditSubclassProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    if (uMsg == WM_GETDLGCODE)

        return DLGC_WANTALLKEYS;

    return CallWindowProc(wpOrigEditProc, hwnd, uMsg,

        wParam, lParam);

}


  4.3  Functions

Following are the functions used with window classes.

CallWindowProc
DefWindowProc
WindowProc


5.1  About Keyboard Input
  Chapter 5    Keyboard Input

5.1  About Keyboard Input

All applications written for Microsoft® Windows (™)  should accept user input from the keyboard as well as from the mouse. A Windows-based application receives keyboard input in the form of messages posted to its windows. This chapter describes how Windows generates keyboard input and how an application receives and processes that input.


  5.1.1  Keyboard Input Model

Windows provides device-independent keyboard support for applications by installing a keyboard device driver appropriate for the current keyboard. Windows provides language-independent keyboard support by using the language-specific keyboard layout currently selected by the user or the application. The keyboard device driver receives scan codes from the keyboard, which are sent to the keyboard layout where they are translated into messages and posted to the appropriate windows in your application.

Assigned to each key on a keyboard is a unique value called a scan code, a device-dependent identifier for the key on the keyboard. A keyboard generates two scan codes when the user types a key — one when the user presses the key and another when the user releases the key.

The keyboard device driver interprets a scan code and translates (maps) it to a virtual-key code, a device-independent value defined by Windows that identifies the purpose of a key. After translating a scan code, the keyboard layout creates a message that includes the scan code, the virtual-key code, and other information about the keystroke, and then places the message in the system message queue. Windows removes the message from the system message queue and posts it to the message queue of the appropriate thread. Eventually, the thread's message loop removes the message and passes it to the appropriate window procedure for processing. »This figure« illustrates the keyboard input model for Windows.


  5.1.2  Keyboard Focus and Activation

Windows posts keyboard messages to the message queue of the thread that created the window with the keyboard focus. The keyboard focus is a temporary property of a window. Windows shares the keyboard among all windows on the display by shifting the keyboard focus, at the user's direction, from one window to another. The window that has the keyboard focus receives (from the message queue of the thread that created it) all keyboard messages until the focus changes to a different window.

A thread can call the GetFocus function to determine which of its windows (if any) currently has the keyboard focus. A thread can give the keyboard focus to one of its windows by calling the SetFocus function. When the keyboard focus changes from one window to another, the system sends a WM_KILLFOCUS message to the window that has lost the focus, and then sends a WM_SETFOCUS message to the window that has gained the focus.

The concept of keyboard focus is related to that of the active window. The active window is the top-level window the user is currently working with. The window with the keyboard focus is either the active window itself, or a child window of the active window. So the user can easily identify the active window, the system places it at the top of the Z order and highlights its title bar (if it has one) and border.

The user can activate a top-level window by clicking it, by selecting it using the ALT+TAB or ALT+ESC key combination, or by selecting if from Task List. A thread can activate a top-level window by using the SetActiveWindow function. It can determine whether a top-level window it created is active by using the GetActiveWindow function.

When one window is deactivated and another activated, Windows sends the WM_ACTIVATE message first to the window being deactivated, then to the window being activated. The low-order word of the wParam parameter is zero if the window is being deactivated and nonzero if it is being activated. When the default window procedure receives the WM_ACTIVATE message, it sets the keyboard focus to the active window.


  5.1.3  Keystroke Messages

Pressing a key results in a WM_KEYDOWN or WM_SYSKEYDOWN message being placed in the thread message queue associated with the window that has the keyboard focus. Releasing a key results in a WM_KEYUP or WM_SYSKEYUP message being placed in the queue.

Key-up and key-down messages typically occur in pairs, but if the user holds down a key long enough to start the keyboard's automatic repeat feature, the system generates a number of WM_KEYDOWN or WM_SYSKEYDOWN messages in a row, then a single WM_KEYUP or WM_SYSKEYUP message when the user releases the key.


  5.1.3.1  System and Nonsystem Keystrokes

Windows makes a distinction between system keystrokes and nonsystem keystrokes. System keystrokes produce system keystroke messages: WM_SYSKEYDOWN and WM_SYSKEYUP. Nonsystem keystrokes produce nonsystem keystroke messages: WM_KEYDOWN and WM_KEYUP.

If your window procedure must process a system keystroke message, make sure that after processing the message the procedure passes it to the DefWindowProc function. Otherwise, all system operations involving the ALT key will be disabled whenever the window has the keyboard focus. That is, the user won't be able to access the window's menus or System menu, or use the ALT+ESC or ALT+TAB key combination to activate a different window.

System keystroke messages are primarily for use by Windows rather than by an application. Windows uses them to provide its built-in keyboard interface to menus and to allow the user to control which window is active. System keystroke messages are generated when the user types a key in combination with the ALT key, or when the user types and no window has the keyboard focus (for example, when the active application is minimized). In this case, the messages are posted to the message queue associated with the active window.

Nonsystem keystroke messages are for use by application windows; the DefWindowProc function does nothing with them. A window procedure can discard any nonsystem keystroke messages that it does not need.


  5.1.3.2  Virtual-Key Codes

The wParam parameter of a keystroke message contains the virtual-key code of the key that was pressed or released. A window procedure processes or ignores a keystroke message, depending on the value of the virtual-key code. For a list of virtual-key codes, see Appendix B, "Virtual Key Codes," in Microsoft Win32 Programmer's Reference, Volume 2.

A typical window procedure processes only a small subset of the keystroke messages that it receives and ignores the rest. For example, a window procedure might process only WM_KEYDOWN keystroke messages, and only those that contain virtual-key codes for the cursor movement keys, shift keys (also called control keys), and function keys. A typical window procedure does not process keystroke messages from character keys. Instead, it uses the TranslateMessage function to convert the message into character messages. For more information about TranslateMessage and character messages, see Section 5.1.4, »Character Messages«.


  5.1.3.3  Keystroke Message Flags

The lParam parameter of a keystroke message contains additional information about the keystroke that generated the message. This information includes the repeat count, the scan code, the extended-key flag, the context code, the previous key-state flag, and the transition-state flag. »This illustration« shows the locations of these flags and values in the lParam parameter:

Repeat Count

You can check the repeat count to determine whether a keystroke message represents more than one keystroke. The system increments the count when the keyboard generates WM_KEYDOWN or WM_SYSKEYDOWN messages faster than an application can process them. This often occurs when the user holds down a key long enough to start the keyboard's automatic repeat feature. Instead of filling the system message queue with the resulting key-down messages, the system combines the messages into a single key down message and increments the repeat count. Releasing a key cannot start the automatic repeat feature, so the repeat count for WM_KEYUP and WM_SYSKEYUP messages is always set to 1.

Scan Code

The scan code is the value that the keyboard hardware generates when the user presses a key. It is a device-dependent value that identifies the key pressed, as opposed to the character represented by the key. An application typically ignores scan codes. Instead, it uses the device-independent virtual-key codes to interpret keystroke messages.

Extended-Key Flag

The extended-key flag indicates whether the keystroke message originated from one of the additional keys on the enhanced keyboard. The extended keys consist of the ALT and CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; the NUM LOCK key; the BREAK (CTRL+PAUSE) key; the PRINT SCRN key; and the divide (/) and ENTER keys in the numeric keypad. The extended-key flag is set if the key is an extended key.

Context Code

The context code indicates whether the ALT key was down when the keystroke message was generated. The code is 1 if the ALT key was down and 0 if it was up.

Previous Key-State Flag

The previous key-state flag indicates whether the key that generated the keystroke message was previously up or down. It is 1 if the key was previously down and 0 if the key was previously up. You can use this flag to identify keystroke messages generated by the keyboard's automatic repeat feature. This flag is set to 1 for WM_KEYDOWN and WM_SYSKEYDOWN keystroke messages generated by the automatic repeat feature. It is always set to 0 for WM_KEYUP and WM_SYSKEYUP messages.

Transition-State Flag

The transition-state flag indicates whether pressing a key or releasing a key generated the keystroke message. This flag is always set to 0 for WM_KEYDOWN and WM_SYSKEYDOWN messages; it is always set to 1 for WM_KEYUP and WM_SYSKEYUP messages.


  5.1.4  Character Messages

Keystroke messages provide a lot of information about keystrokes, but they don't provide character codes for character keystrokes. To retrieve character codes, an application must include the TranslateMessage function in its thread message loop. TranslateMessage passes a WM_KEYDOWN or WM_SYSKEYDOWN message to the keyboard layout. The layout examines the message's virtual-key code and, if it corresponds to a character key, provides the character code equivalent (taking into account the state of the SHIFT and CAPS LOCK keys). It then generates a character message that includes the character code and places the message at the top of the message queue. The next iteration of the message loop removes the character message from the queue and dispatches the message to the appropriate window procedure.


  5.1.4.1  System and  Nonsystem Character Messages

A window procedure can receive four different character messages, including WM_CHAR, WM_DEADCHAR, WM_SYSCHAR, and WM_SYSDEADCHAR. The TranslateMessage function generates a WM_CHAR or WM_DEADCHAR message when it processes a WM_KEYDOWN message. Similarly, it generates a WM_SYSCHAR or WM_SYSDEADCHAR message when it processes a WM_SYSKEYDOWN message.

An application that processes keyboard input typically ignores all but the WM_CHAR message, passing any other messages to the DefWindowProc function. Windows uses the WM_SYSCHAR and WM_SYSDEADCHAR messages to implement menu mnemonics.

The wParam parameter of all character messages contains the character code of the character key that was pressed. The value of the character code depends on the window class of the window receiving the message. If the Unicode (™)  version of the RegisterWindowClass function was used to register the window class, the system provides Unicode characters to all windows of that class. Otherwise, the system provides ASCII character codes from the Windows character set. For more information about Unicode, see Chapter 53, "String Manipulation and Unicode" in Microsoft Win32 Programmer's Reference, Volume 2.

The contents of the lParam parameter of a character message are identical to the contents of the lParam parameter of the key-down message that was translated to produce the character message. For information about the contents of the lParam parameter, see Section 5.1.3.3, »Keystroke Message Flags«.


  5.1.4.2  Dead-Character Messages

Some non-English keyboards contain character keys that are not expected to produce characters by themselves. Instead, they are used to add a diacritic to the character produced by the subsequent keystroke. These keys are called dead keys. The circumflex key on a German keyboard is an example of a dead key. To enter the character consisting of an o with an circumflex, a German user would type the circumflex key followed by the o key. The window with the keyboard focus would receive the following sequence of messages:

WM_KEYDOWN
WM_DEADCHAR
WM_KEYUP
WM_KEYDOWN
WM_CHAR
WM_KEYUP

TranslateMessage generates the WM_DEADCHAR message when it processes the WM_KEYDOWN message from a dead key. Although the wParam parameter of the WM_DEADCHAR message contains the character code of the diacritic for the dead key, an application typically ignores the message. Instead, it processes the WM_CHAR message generated by the subsequent keystroke. The wParam parameter of the WM_CHAR message contains the character code of the letter with the diacritic. If the subsequent keystroke generates a character that cannot be combined with a diacritic, Windows generates two WM_CHAR messages. The wParam parameter of the first contains the character code of the diacritic; the wParam parameter of the second contains the character code of the subsequent character key.

The TranslateMessage function generates the WM_SYSDEADCHAR message when it processes the WM_SYSKEYDOWN message from a system dead key (a dead key that is pressed in combination with the ALT key). An application typically ignores the WM_SYSDEADCHAR message.


  5.1.5  Key Status

While processing a keyboard message, an application may need to determine the status of another key besides the one that generated the current message. For example, a word processing application that allows the user to press SHIFT+END to highlight a block of text must check the status of the SHIFT key whenever it receives a keystroke message from the END key. The application can use the GetKeyState function to determine the status of a virtual key at the time the current message was generated, and it can use the GetAsyncKeyState function to retrieve the current status of a virtual key.

The keyboard layout maintains a list of names. The name of a key that produces a single character is the same as the character produced by the key. The name of a noncharacter key such as TAB and ENTER is stored as a character string. An application can retrieve the name of any key from the device driver by calling GetKeyNameText.


  5.1.6  Keystroke and Character Translations

Windows includes several special purpose functions that translate scan codes, character codes, and virtual-key codes provided by various keystroke messages. These functions include MapVirtualKey, ToAscii, ToUnicode, and VkKeyScan.


  5.1.7  Hot Key Support

Windows provides a set of functions that applications can use to define hot keys. A hotkey for your application. A hot key is a key combination that generates a WM_HOTKEY message, a message the system places at the top of a thread's message queue, bypassing any existing messages in the queue. Applications use hot keys to obtain high-priority keyboard input from the user. For example, by defining a hot key consisting of the CTRL+C key combination, an application can allow the user to cancel a lengthy operation.

To define a hot key, an application calls the RegisterHotKey function, specifying the combination of keys that generates the WM_HOTKEY message, the handle of the window to receive the message, and the identifier of the hot key. When the user presses the hot key, a WM_HOTKEY message is placed in the message queue of the thread that created the given window. The wParam parameter of the message contains the identifier of the hot key. The application can define multiple hot keys for a thread, but each hot key in the thread must have a unique identifier.

Before the application terminates, it should use the Unregister Hot Key function to destroy the hot key.


  5.2  Using Keyboard Input

A window receives keyboard input in the form of keystroke messages and character messages. The message loop associated with the window must include code to translate keystroke messages into the corresponding character messages. If the window displays keyboard input in its client area, it should create and display a caret to indicate the position where the next character will be entered. The following sections describe the code involved in receiving, processing, and displaying keyboard input.


  5.2.1  Processing Keystroke Messages

The window procedure of the window that has the keyboard focus receives keystroke messages when the user types at the keyboard. The keystroke messages are WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, and WM_SYSKEYUP. A typical window procedure ignores all keystroke messages except WM_KEYDOWN. Windows posts the WM_KEYDOWN message when the user presses a key.

When the window procedure receives the WM_KEYDOWN message, it should examine the virtual-key code that accompanies the message to determine how to process the keystroke. The virtual-key code is in the message's wParam parameter. Typically, an application processes only keystrokes generated by noncharacter keys, including the function keys, the cursor movement keys, and the special-purpose keys such as INS, DEL, HOME and END.

The following example shows the window procedure framework that a typical application uses to receive and process keystroke messages

case WM_KEYDOWN:

    switch (wParam) {

        case VK_LEFT:

            .

            . /* Process the LEFT ARROW key. */

            .

            break;

        case VK_RIGHT:

            .

            . /* Process the RIGHT ARROW key. */

            .

            break;

        case VK_UP:

            .

            . /* Process the UP ARROW key. */

            .

            break;

        case VK_DOWN:

            .

            . /* Process the DOWN ARROW key. */

            .

            break;

        case VK_HOME:

            .

            . /* Process the HOME key. */

            .

            break;

        case VK_END:

            .

            . /* Process the END key. */

            .

            break;

        case VK_INSERT:

            .

            . /* Process the INS key. */

            .

            break;

        case VK_DELETE:

            .

            . /* Process the DEL key. */

            .

            break;

        case VK_F2:

            .

            . /* Process the F2 key. */

            .

            break;

        .

        . /* Process other noncharacter keystrokes. */

        .

        default:

            break;

    }


  5.2.2  Translating Character Messages

Any thread that receives character input from the user must include the TranslateMessage function in its message loop. This function examines the virtual-key code of a keystroke message and, if the code corresponds to a character, places a character message into the message queue. The character message is removed and dispatched on the next iteration of the message loop; the wParam parameter of the message contains the character code.

In general, a thread's message loop should use the TranslateMessage function to translate every message, not just virtual-key messages. Although TranslateMessage has no effect on other types of messages, it guarantees that keyboard input is translated correctly. The following example shows how to include the TranslateMessage function in a typical thread message loop.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

    if (TranslateAccelerator(hwndMain, haccl, &msg) == 0) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

}


  5.2.3  Processing Character Messages

A window procedure receives a character message when the TranslateMessage function translates a virtual-key code corresponding to a character key. The character messages are WM_CHAR, WM_DEADKEY, WM_SYSCHAR, and WM_SYSDEADKEY. A typical window procedure ignores all character messages except WM_CHAR. The TranslateMessage function generates a WM_CHAR message when the user presses any of the following keys:

Any character key
BACKSPACE
ENTER (carriage return)
ESC
SHIFT+ENTER (linefeed)
TAB

When a window procedure receives the WM_CHAR message, it should examine the character code that accompanies the message to determine how to process the character. The character code is in the message's wParam parameter.

The following example shows the window procedure framework that a typical application uses to receive and process character messages.

case WM_CHAR:

    switch (wParam) {

        case 0x08:

            .

            . /* Process a backspace. */

            .

            break;

        case 0x0A:

            .

            . /* Process a linefeed. */

            .

            break;

        case 0x1B:

            .

            . /* Process an escape. */

            .

            break;

        case 0x09:

            .

            . /* Process a tab. */

            .

            break;

        case 0x0D:

            .

            . /* Process a carriage return. */

            .

            break;

        default:

            .

            . /* Process displayable characters. */

            .

            break;

    }


  5.2.4  Using the Caret

A window that receives keyboard input typically displays the characters the user types in the window's client area. A window should use a caret to indicate the position in the client area where the next character will appear. The window should also create and display the caret when it receives the keyboard focus, and hide and destroy the caret when it loses the focus. A window can perform these operations in the processing of the WM_SETFOCUS and WM_KILLFOCUS messages. For more information about carets, see Chapter 22, »Carets«.


  5.2.5  Displaying Keyboard Input

The example in this section shows how an application can receive characters from the keyboard, display them in the client area of a window, and update the position of the caret with each character typed. It also demonstrates how to move the caret in response to the LEFT ARROW, RIGHT ARROW, HOME and END keystrokes, and shows how to highlight selected text in response to the SHIFT+RIGHT ARROW key combination.

During processing of the WM_CREATE message, the window procedure shown in the example allocates a 64K buffer for storing keyboard input. It also retrieves the metrics of the currently loaded font, saving the height and average width of characters in the font. The height and width are used in processing the WM_SIZE message to calculate the line length and maximum number of lines, based on the size of the client area.

The window procedure creates and displays the caret when processing the WM_SETFOCUS message. It hides and deletes the caret when processing the WM_KILLFOCUS message.

When processing the WM_CHAR message, the window procedure displays characters, stores them in the input buffer, and updates the caret position. The window procedure also converts tab characters to four consecutive space characters. Backspace, linefeed, and escape characters generate a beep but are not otherwise processed.

The window procedure performs the left, right, end, and home caret movements when processing the WM_KEYDOWN message. While processing the action of the RIGHT ARROW key, the window procedure checks the state of the SHIFT key and, if it is down, highlights the character to the right of the caret as the caret is moved.

Note that the following code is written so that it can be compiled either as Unicode or as ANSI. If the source code defines Unicode, strings are handled as Unicode characters; otherwise, they are handled as ANSI characters.

#define BUFSIZE 65535

#define SHIFTED 0x8000

LONG APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)

HWND hwndMain;

UINT uMsg;

UINT wParam;

LONG lParam;

{

    HDC hdc;                   /* handle of device context      */

    TEXTMETRIC tm;             /* structure for text metrics    */

    static DWORD dwCharX;      /* average width of characters   */

    static DWORD dwCharY;      /* height of characters          */

    static DWORD dwClientX;    /* width of client area          */

    static DWORD dwClientY;    /* height of client area         */

    static DWORD dwLineLen;    /* line length                   */

    static DWORD dwLines;      /* text lines in client area     */

    static int nCaretPosX = 0; /* horizontal position of caret  */

    static int nCaretPosY = 0; /* vertical position of caret    */

    static int nCharWidth = 0; /* width of a character          */

    static int cch = 0;        /* characters in buffer          */

    static int nCurChar = 0;   /* index of current character    */

    static PTCHAR pchInputBuf; /* address of input buffer       */

    int i, j;                  /* loop counters                 */

    int cCR = 0;               /* count of carriage returns     */

    int nCRIndex = 0;          /* index of last carriage return */

    int nVirtKey;              /* virtual-key code              */

    TCHAR szBuf[128];          /* temporary buffer              */

    TCHAR ch;                  /* current character             */

    PAINTSTRUCT ps;            /* required by BeginPaint        */

    RECT rc;                   /* output rectangle for DrawText */

    SIZE sz;                   /* string dimensions             */

    COLORREF crPrevText;       /* previous text color           */

    COLORREF crPrevBk;         /* previous background color     */

    switch (uMsg) {

        case WM_CREATE:

            /* Get the metrics of the current font. */

            hdc = GetDC(hwndMain);

            GetTextMetrics(hdc, &tm);

            ReleaseDC(hwndMain, hdc);

            /* Save the average character width and height. */

            dwCharX = tm.tmAveCharWidth;

            dwCharY = tm.tmHeight;

            /* Allocate a buffer to store keyboard input. */

            pchInputBuf = (LPTSTR) GlobalAlloc(GPTR,

                BUFSIZE * sizeof(TCHAR));

            return 0;

        case WM_SIZE:

            /* Save the new width and height of the client area. */

            dwClientX = LOWORD(lParam);

            dwClientY = HIWORD(lParam);

            /*

             * Calculate the maximum width of a line and the

             * maximum number of lines in the client area.

             */

            dwLineLen = dwClientX - dwCharX;

            dwLines = dwClientY / dwCharY;

            break;

        case WM_SETFOCUS:

            /*

             * Create, position, and display the caret when the

             * window receives the keyboard focus.

             */

            CreateCaret(hwndMain, (HBITMAP) 1, 0, dwCharY);

            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);

            ShowCaret(hwndMain);

            break;

        case WM_KILLFOCUS:

            /*

             * Hide and destroy the caret when the window loses the

             * keyboard focus.

             */

            HideCaret(hwndMain);

            DestroyCaret();

            break;

        case WM_CHAR:

            switch (wParam) {

                case 0x08: /* backspace */

                case 0x0A: /* linefeed */

                case 0x1B: /* escape */

                    MessageBeep(0xFFFFFFFF);

                    return 0;

                case 0x09: /* tab */

                    /* Convert tabs to four consecutive spaces. */

                    for (i = 0; i < 4; i++)

                        SendMessage(hwndMain, WM_CHAR, 0x20, 0);

                    return 0;

                case 0x0D: /* carriage return */

                    /*

                     * Record the carriage return and position the

                     * caret at the beginning of the new line.

                     */

                    pchInputBuf[cch++] = 0x0D;

                    nCaretPosX = 0;

                    nCaretPosY += 1;

                    break;

                default: /* displayable character */

                    ch = (TCHAR) wParam;

                    HideCaret(hwndMain);

                     /*

                      * Retrieve the character's width and output

                      * the character.

                      */

                    hdc = GetDC(hwndMain);

                    GetCharWidth(hdc, (UINT) wParam, (UINT) wParam,

                        &nCharWidth);

                    TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY,

                        &ch, 1);

                    ReleaseDC(hwndMain, hdc);

                    /* Store the character in the buffer. */

                    pchInputBuf[cch++] = ch;

                    /*

                     * Calculate the new horizontal position of the

                     * caret. If the position exceeds the maximum,

                     * insert a carriage return and move the caret

                     * to the beginning of the next line.

                     */

                    nCaretPosX += nCharWidth;

                    if ((DWORD) nCaretPosX > dwLineLen) {

                        nCaretPosX = 0;

                        pchInputBuf[cch++] = 0x0D;

                        ++nCaretPosY;

                    }

                    nCurChar = cch;

                    ShowCaret(hwndMain);

                    break;

            }

            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);

            break;

        case WM_KEYDOWN:

            switch (wParam) {

                case VK_LEFT: /* LEFT ARROW */

                    /*

                     * The caret can move only to the beginning of

                     * the current line.

                     */

                    if (nCaretPosX > 0) {

                        HideCaret(hwndMain);

                        /*

                         * Retrieve the character to the left of

                         * the caret, calculate the character's

                         * width, then subtract the width from the

                         * current horizontal position of the caret

                         * to obtain the new position.

                         */

                        ch = pchInputBuf[--nCurChar];

                        hdc = GetDC(hwndMain);

                        GetCharWidth(hdc, ch, ch, &nCharWidth);

                        ReleaseDC(hwndMain, hdc);

                        nCaretPosX = max(nCaretPosX - nCharWidth,

                            0);

                        ShowCaret(hwndMain);

                    }

                    break;

                case VK_RIGHT: /* RIGHT ARROW */

                    /*

                     * Caret moves to the right or, when a carriage

                     * return is encountered, to the beginning of

                     * the next line.

                     */

                    if (nCurChar < cch) {

                        HideCaret(hwndMain);

                        /*

                         * Retrieve the character to the right of

                         * the caret. If it's a carriage return,

                         * position the caret at the beginning of

                         * the next line.

                         */

                        ch = pchInputBuf[nCurChar];

                        if (ch == 0x0D) {

                            nCaretPosX = 0;

                            nCaretPosY++;

                        }

                        /*

                         * If the character isn't a carriage

                         * return, check to see whether the SHIFT

                         * key is down. If it is, invert the text

                         * colors and output the character.

                         */

                        else {

                            hdc = GetDC(hwndMain);

                            nVirtKey = GetKeyState(VK_SHIFT);

                            if (nVirtKey & SHIFTED) {

                                crPrevText = SetTextColor(hdc,

                                    RGB(255, 255, 255));

                                crPrevBk = SetBkColor(hdc,

                                    RGB(0,0,0));

                                TextOut(hdc, nCaretPosX,

                                    nCaretPosY * dwCharY,

                                    &ch, 1);

                                SetTextColor(hdc, crPrevText);

                                SetBkColor(hdc, crPrevBk);

                            }

                            /*

                             * Get the width of the character and

                             * calculate the new horizontal

                             * position of the caret.

                             */

                            GetCharWidth(hdc, ch, ch, &nCharWidth);

                            ReleaseDC(hwndMain, hdc);

                            nCaretPosX = nCaretPosX + nCharWidth;

                        }

                        nCurChar++;

                        ShowCaret(hwndMain);

                        break;

                    }

                    break;

                case VK_UP: /* UP ARROW   */

                case VK_DOWN: /* DOWN ARROW */

                    MessageBeep(0xFFFFFFFF);

                    return 0;

                case VK_HOME: /* HOME */

                    /*

                     * Set the caret's position to the upper left

                     * corner of the client area.

                     */

                    nCaretPosX = nCaretPosY = 0;

                    nCurChar = 0;

                    break;

                case VK_END: /* END */

                    /* Move the caret to the end of the text. */

                    for (i=0; i < cch; i++) {

                        /*

                         * Count the carriage returns and save the

                         * index of the last one.

                         */

                        if (pchInputBuf[i] == 0x0D) {

                            cCR++;

                            nCRIndex = i + 1;

                        }

                    }

                    nCaretPosY = cCR;

                    /*

                     * Copy all text between the last carriage

                     * return and the end of the keyboard input

                     * buffer to a temporary buffer.

                     */

                    for (i = nCRIndex, j = 0; i < cch; i++, j++)

                        szBuf[j] = pchInputBuf[i];

                    szBuf[j] = TEXT('\0');

                    /*

                     * Retrieve the text extent and use it

                     * to set the horizontal position of the

                     * caret.

                     */

                    hdc = GetDC(hwndMain);

                    GetTextExtentPoint(hdc, szBuf, lstrlen(szBuf),

                        &sz);

                    nCaretPosX = sz.cx;

                    ReleaseDC(hwndMain, hdc);

                    nCurChar = cch;

                    break;

                default:

                    break;

            }

            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);

            break;

        case WM_PAINT:

            if (cch == 0)       /* nothing in input buffer */

                break;

            hdc = BeginPaint(hwndMain, &ps);

            HideCaret(hwndMain);

            /*

             * Set the clipping rectangle, and then draw the text

             * into it.

             */

            SetRect(&rc, 0, 0, dwLineLen, dwClientY);

            DrawText(hdc, pchInputBuf, -1, &rc, DT_LEFT);

            ShowCaret(hwndMain);

            EndPaint(hwndMain, &ps);

            break;

        .

        . /* Process other messages. */

        .

        case WM_DESTROY:

            PostQuitMessage(0);

            /* Free the input buffer. */

            GlobalFree((HGLOBAL) pchInputBuf);

            break;

        default:

            return DefWindowProc(hwndMain, uMsg, wParam, lParam);

    }

    return NULL;

}


  5.3  Functions and Messages

Following are the functions and messages used to receive and process keyboard input:


  Functions

EnableWindow
GetActiveWindow
GetAsyncKeyState
GetFocus
GetKeyboardState
GetKeyNameText
GetKeyState
IsWindowEnabled
keybd_event
MapVirtualKey
RegisterHotKey
SetActiveWindow
SetFocus
SetKeyboardState
ToAscii
ToUnicode
UnregisterHotKey
VkKeyScan


  Messages

WM_ACTIVATE
WM_CHAR
WM_DEADCHAR
WM_HOTKEY
WM_KEYDOWN
WM_KEYUP
WM_KILLFOCUS
WM_SETFOCUS
WM_SYSCHAR
WM_SYSDEADCHAR
WM_SYSKEYDOWN
WM_SYSKEYUP


6.1  About Mouse Input
  Chapter 6    Mouse Input

6.1  About Mouse Input

The mouse is an important, but optional, user-input device for applications written for Microsoft® Windows (™) . A well-written Windows-based application should include a mouse interface, but it should not depend on the mouse as the sole means of acquiring user input. The application should provide full keyboard support as well.

A Windows-based application receives mouse input in the form of messages that are sent or posted to its windows. This chapter describes how Windows generates mouse input and explains how an application receives and processes that input.


  6.1.1  Mouse Cursor

When the user moves the mouse, the system moves a bitmap on the screen called the mouse cursor. The mouse cursor contains a single-pixel point called the hot spot, a point that the system tracks and recognizes as the position of the cursor. When a mouse event occurs, the window that contains the hot spot typically receives the mouse message resulting from the event. The window need not be active or have the keyboard focus to receive a mouse message.

The system maintains a variable that controls the mouse speed — that is, the distance the cursor moves when the user moves the mouse. You can use the SystemParametersInfo function with the SPI_GETMOUSE or SPI_SETMOUSE flag to retrieve or set the mouse speed. For more information about mouse cursors, see Chapter 21, »Cursors«.


  6.1.2  Mouse Capture

The system typically posts a mouse message to the window that contains the cursor hot spot at the time a mouse event occurs. An application can change this behavior by using the SetCapture function to route mouse messages to a specific window. The window receives all mouse messages until the application calls the ReleaseCapture function or specifies another capture window, or until the user clicks a window created by another thread.

Only the foreground window can capture mouse input. When a background window attempts to capture mouse input, it receives messages only for mouse events that occur when the cursor hot spot is within the visible portion of the window.

Capturing mouse input is useful if a window must receive all mouse input, even when the cursor moves outside the window. For example, an application typically tracks the cursor position after a mouse "button down" event, following the cursor until a "button up" event occurs. If an application has not captured mouse input and the user releases the mouse button outside the window, the window does not receive the button up message.

A thread can use the GetCapture function to determine whether one of its windows has captured the mouse. If one of the thread's windows has captured the mouse, GetCapture retrieves the handle of the window.


  6.1.3  Mouse Configuration

Although the mouse is an important input device for Windows-based applications, not every user necessarily has a mouse. An application can determine whether the system includes a mouse by passing the SM_MOUSEPRESENT value to the GetSystemMetrics function.

Windows supports a mouse having up to three buttons. On a three-button mouse, the buttons are designated as the left, middle, and right buttons. Windows messages and named constants related to the mouse buttons use the letters L, M, and R to identify the buttons. The button on a single-button mouse is considered to be the left button. Although Windows supports a mouse with multiple buttons, most applications use the left button primarily and use the others little, if at all.

An application can determine the number of buttons on the mouse by passing the SM_CMOUSEBUTTONS value to the GetSystemMetrics function. To configure the mouse for a left-handed user, the application can use the SwapMouseButton function to reverse the meaning of the left and right mouse buttons. Passing the SPI_SETMOUSEBUTTONSWAP value to the SystemParametersInfo function is another way to reverse the meaning of the buttons. Note, however, that the mouse is a shared resource, so reversing the meaning of the buttons affects all applications.


  6.1.4  Mouse Messages

The mouse generates an input event whenever the user moves the mouse, or presses or releases a mouse button. Windows converts mouse input events into messages and posts them to the appropriate thread's message queue. When mouse messages are posted faster than a thread can process them, Windows discards all but the most recent mouse message.

A window receives a mouse message when a mouse event occurs while the cursor is within the borders of the window, or when the window has captured the mouse. Mouse messages are divided into two groups: client area messages and nonclient area messages. Typically, an application processes client area messages and ignores nonclient area messages.


  6.1.4.1  Client Area Mouse Messages

A window receives a client area mouse message when a mouse event occurs within the window's client area. The system posts the WM_MOUSEMOVE message to the window when the user moves the cursor within the client area. It posts one of the following messages when the user presses or releases a mouse button while the cursor is within the client area.

Message	Meaning
WM_LBUTTONDBLCLK	The left mouse button was double-clicked.
WM_LBUTTONDOWN	The left mouse button was pressed.
WM_LBUTTONUP	The left mouse button was released.
WM_MBUTTONDBLCLK	The middle mouse button was double-clicked.
WM_MBUTTONDOWN	The middle mouse button was pressed.
WM_MBUTTONUP	The middle mouse button was released.
WM_RBUTTONDBLCLK	The right mouse button was double-clicked.
WM_RBUTTONDOWN	The right mouse button was pressed.
WM_RBUTTONUP	The right mouse button was released.
Message Parameters

The lParam parameter of a client area mouse message indicates the position of the cursor hot spot. The low-order word indicates the x-coordinate of the hot spot, and the high-order word indicates the y-coordinate. The coordinates are given in client coordinates. In the client coordinate system, all points on the screen are given relative to the coordinates (0,0) of the upper-left corner of the client area.

The wParam parameter contains flags that indicate the status of the other mouse buttons and the CTRL and SHIFT keys at the time of the mouse event. You can check for these flags when mouse-message processing depends on the state of another mouse button or of the CTRL or SHIFT key. The lParam parameter can be a combination of the following values.

Value	Meaning
MK_CONTROL	The CTRL key is down.
MK_LBUTTON	The left mouse button is down.
MK_MBUTTON	The middle mouse button is down.
MK_RBUTTON	The right mouse button is down.
MK_SHIFT	The SHIFT key is down.
Double-Click Messages

The system generates a double-click message when the user clicks a mouse button twice in quick succession. When the user clicks a button, the system establishes a rectangle centered around the cursor hot spot. It also marks the time at which the click occurred. When the user clicks the same button a second time, the system determines whether the hot spot is still within the rectangle and calculates the time elapsed since the first click. If the hot spot is still within the rectangle and the elapsed time does not exceeded the double-click time-out value, the system generates a double-click message.

An application can get and set double-click time-out values by using the GetDoubleClickTime and SetDoubleClickTime functions, respectively. Alternatively, the application can set the double-click time-out value by using the SPI_SETDOUBLECLICKTIME flag with the SystemParametersInfo function. It can also set the size of the rectangle that Windows uses to detect double-clicks by passing the SPI_SETDOUBLECLKWIDTH and SPI_SETDOUBLECLKHEIGHT flags to SystemParametersInfo. Note, however, that setting the double-click time-out value and rectangle affects all applications.

An application-defined window does not, by default, receive double-click messages. Because of the system overhead involved in generating double-click messages, these messages are generated only for windows belonging to classes that have the CS_DBLCLKS class style. Your application must set this style when registering the window class. For more information about window classes, see Chapter 3, »Window Classes«.

A double-click message is always the third message in a four-message series. The first two messages are the button down and button up messages generated by the first click. The second click generates the double-click message followed by another button up message. For example, double-clicking the left mouse button generates the following message sequence:

WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
WM_LBUTTONUP

Because a window always receives a button down message before receiving a double-click message, an application typically uses a double-click message to extend a task it began during a button down message. For example, when the user clicks a color in the color palette of Windows PaintBrush, PaintBrush displays the selected color next to the palette. When the user double-clicks a color, PaintBrush displays the color and opens the Edit Colors dialog box.


  6.1.4.2  Nonclient Area Mouse Messages

A window receives a nonclient area mouse message when a mouse event occurs in any part of a window except the client area. A window's nonclient area consists of its border, menu bar, title bar, scroll bar, System menu, Minimize button, and Maximize button.

Windows generates nonclient area messages primarily for its own use. For example, Windows uses nonclient area messages to change the cursor to a two-headed arrow when the cursor hot spot moves into a window's border. A window must pass nonclient area mouse messages to the DefWindowProc function to take advantage of the built-in mouse interface found in Windows.

There is a corresponding nonclient area mouse message for each client area mouse message. The names of these messages are similar except that the named constants for the nonclient area messages include the letters "NC". For example, moving the cursor in the nonclient area generates a WM_NCMOUSEMOVE message, and pressing the left mouse button while the cursor is in the nonclient area generates a WM_NCLBUTTONDOWN message.

The lParam parameter of a nonclient area mouse message is a POINTS structure that contains the x- and y-coordinates of the cursor hot spot. Unlike coordinates of client area mouse messages, the coordinates are given in screen coordinates rather than client coordinates. In the screen coordinate system, all points on the screen are relative to the coordinates (0,0) of the upper-left corner of the screen.

The wParam parameter contains a hit-test code, a value that indicates where in the nonclient area the mouse event occurred. The following section explains the purpose of hit-test codes.


  6.1.5  The WM_NCHITTEST Message

Whenever a mouse event occurs, the system sends a WM_NCHITTEST message to either the window that contains the cursor hot spot or the window that has captured the mouse. Windows uses this message to determine whether to send a client area or nonclient area mouse message. An application that must receive mouse movement and mouse button messages must pass the WM_NCHITTEST message to the DefWindowProc function.

The lParam parameter of the WM_NCHITTEST message contains the screen coordinates of the cursor hot spot. The DefWindowProc function examines the coordinates and returns a hit-test code that identifies the location of the hot spot. The hit-test code can be one of the following values.

Value	Location of hot spot
HTBORDER	In the border of a window that does not have a sizing border
HTBOTTOM	In the lower horizontal border of a window
HTBOTTOMLEFT	In the lower left corner of a window border
HTBOTTOMRIGHT	In the lower right corner of a window border
HTCAPTION	In a title bar
HTCLIENT	In a client area
HTERROR	On the screen background or on a dividing line between windows (same as HTNOWHERE, except that the DefWindowProc function produces a system beep to indicate an error)
HTGROWBOX	In a size box (same as HTSIZE)
HTHSCROLL	In a horizontal scroll bar
HTLEFT	In the left border of a window
HTMENU	In a menu
HTNOWHERE	On the screen background or on a dividing line between windows
HTREDUCE	In a Minimize button
HTRIGHT	In the right border of a window
HTSIZE	In a size box (same as HTGROWBOX)
HTSYSMENU	In a System menu or in a Close button in a child window
HTTOP	In the upper horizontal border of a window
HTTOPLEFT	In the upper left corner of a window border
HTTOPRIGHT	In the upper right corner of a window border
HTTRANSPARENT	In a window currently covered by another window
HTVSCROLL	In the vertical scroll bar
HTZOOM	In a Maximize button
If the cursor is in the client area of a window, DefWindowProc returns the HTCLIENT hit-test code to the window procedure. When the window procedure returns this code to the system, Windows converts the screen coordinates of the cursor hot spot to client coordinates, and then posts the appropriate client area mouse message.

The DefWindowProc function returns one of the other hit-test codes when the cursor hot spot is in a window's nonclient area. When the window procedure returns one of these hit-test codes, Windows posts a nonclient area mouse message, placing the hit-test code in the message's wParam parameter and the cursor coordinates in the lParam parameter.


  6.1.6  Window Activation

When the user clicks an inactive top-level window or the child window of a inactive top-level window, Windows sends the WM_MOUSEACTIVATE message (among others) to the top-level or child window. Windows sends this message after posting the WM_NCHITTEST message to the window, but before posting the button down message. When WM_MOUSEACTIVATE is passed to the DefWindowProc function, Windows activates the top-level window and then posts the button down message to the top-level or child window.

By processing WM_MOUSEACTIVATE, a window can control whether the top-level window becomes the active window as a result of a mouse click, and whether the window that was clicked receives the subsequent button down message. It does so by returning one of the following values after processing WM_MOUSEACTIVATE.

Value	Meaning
MA_ACTIVATE	Activate the window, and do not discard the mouse message.
MA_NOACTIVATE	Do not activate the window, and do not discard the mouse message.
MA_ACTIVATEANDEAT	Activate the window, and discard the mouse message.
MA_NOACTIVATEANDEAT	Do not activate the window, but discard the mouse message.


  6.2  Using Mouse Input

This section explains how to perform the following tasks:

•	Track the mouse cursor.

•	Process double-click messages.


  6.2.1  Tracking the Mouse Cursor

Windows-based applications often perform tasks that involve tracking the position of the mouse cursor. Most drawing applications, for example, track it during drawing operations, allowing the user to draw in a window's client area by dragging the mouse. Word-processing applications also track the cursor, enabling the user to select a word or block of text by clicking and dragging the mouse.

Tracking the cursor typically involves processing the WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP messages. A window determines when to begin tracking the cursor by checking the cursor position provided in the lParam parameter of the WM_LBUTTONDOWN message. For example, a word-processing application would begin tracking the cursor only if the WM_LBUTTONDOWN message occurred while the cursor was on a line of text, but not if it was past the end of the document.

A window tracks the position of the cursor by processing the stream of WM_MOUSEMOVE messages posted to the window as the mouse moves. Processing the WM_MOUSEMOVE message typically involves a repetitive painting or drawing operation in the client area. For example, a drawing application might redraw a line repeatedly as the mouse moves. A window uses the WM_LBUTTONUP message as a signal to stop tracking the cursor.


  6.2.2  Drawing Lines with the Mouse

The example in this section demonstrates how to track the mouse cursor. It contains portions of a window procedure that enables the user to draw lines in a window's client area by dragging the mouse.

When the window procedure receives a WM_LBUTTONDOWN message, it captures the mouse and saves the coordinates of the cursor, using the coordinates as the starting point of the line. It also uses the ClipCursor function to confine the cursor to the client area during the line drawing operation.

During the first WM_MOUSEMOVE message, the window procedure draws a line from the starting point to the current position of the cursor. During subsequent WM_MOUSEMOVE messages, the window procedure erases the previous line by drawing over it with an inverted pen color. Then it draws a new line from the starting point to the new position of the cursor.

The WM_LBUTTONUP message signals the end of the drawing operation. The window procedure releases the mouse capture and frees the mouse from the client area.

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)

HWND hwndMain;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    HDC hdc;                       /* handle of device context  */

    RECT rcClient;                 /* client area rectangle     */

    POINT ptClientUL;              /* client upper-left corner  */

    POINT ptClientLR;              /* client lower-right corner */

    static POINTS ptsBegin;        /* beginning point           */

    static POINTS ptsEnd;          /* new endpoint              */

    static POINTS ptsPrevEnd;      /* previous endpoint         */

    static BOOL fPrevLine = FALSE; /* previous line flag        */

    switch (uMsg) {

        case WM_LBUTTONDOWN:

            /* Capture mouse input. */

            SetCapture(hwndMain);

            /*

             * Retrieve the screen coordinates of the client area,

             * and convert them into client coordinates.

            /*

            GetClientRect(hwndMain, &rcClient);

            ptClientUL.x = rcClient.left;

            ptClientUL.y = rcClient.top;

            /*

             * Add one to the right and bottom sides, because the

             * coordinates retrieved by GetClientRect do not

             * include the far left and lowermost pixels.

             */

            ptClientLR.x = rcClient.right + 1;

            ptClientLR.y = rcClient.bottom + 1;

            ClientToScreen(hwndMain, &ptClientUL);

            ClientToScreen(hwndMain, &ptClientLR);

            /*

             * Copy the client coordinates of the client area

             * to the rcClient structure. Confine the mouse cursor

             * to the client area by passing the rcClient structure

             * to the ClipCursor function.

             */

            SetRect(&rcClient, ptClientUL.x, ptClientUL.y,

                ptClientLR.x, ptClientLR.y);

            ClipCursor(&rcClient);

            /*

             * Convert the cursor coordinates into a POINTS

             * structure, which defines the beginning point of the

             * line drawn during a WM_MOUSEMOVE message.

             */

            ptsBegin = MAKEPOINTS(lParam);

            return 0;

        case WM_MOUSEMOVE:

            /*

             * When moving the mouse, the user must hold down

             * the left mouse button to draw lines.

             */

            if (wParam & MK_LBUTTON) {

                /*

                 * Retrieve a device context (DC) for the client

                 * area.

                 */

                hdc = GetDC(hwndMain);

                /*

                 * The following function ensures that pixels of

                 * the previously drawn line are set to white and

                 * those of the new line are set to black.

                 */

                SetROP2(hdc, R2_NOTXORPEN);

                /*

                 * If a line was drawn during an earlier

                 * WM_MOUSEMOVE message, draw over it. This erases

                 * the line by setting the color of its pixels to

                 * white.

                 */

                if (fPrevLine) {

                    MoveToEx(hdc, ptsBegin.x, ptsBegin.y,

                        (LPPOINT) NULL);

                    LineTo(hdc, ptsPrevEnd.x, ptsPrevEnd.y);

                }

                /*

                 * Convert the current cursor coordinates to a

                 * POINTS structure, and then draw a new line.

                 */

                ptsEnd = MAKEPOINTS(lParam);

                MoveToEx(hdc, ptsBegin.x, ptsBegin.y,

                    (LPPOINT) NULL);

                LineTo(hdc, ptsEnd.x, ptsEnd.y);

                /*

                 * Set the previous line flag, save the ending

                 * point of the new line, and then release the DC.

                 */

                fPrevLine = TRUE;

                ptsPrevEnd = ptsEnd;

                ReleaseDC(hwndMain, hdc);

            }

            break;

        case WM_LBUTTONUP:

            /*

             * The user has finished drawing the line. Reset the

             * previous line flag, release the mouse cursor, and

             * release the mouse capture.

             */

            fPrevLine = FALSE;

            ClipCursor(NULL);

            ReleaseCapture();

            return 0;

        case WM_DESTROY:

            PostQuitMessage(0);

            break;

        .

        . /* Process other messages. */

        .


  6.2.3  Processing a Double-Click Message

To receive double-click messages, a window must belong to a window class that has the CS_DBLCLKS class style. You set this style when registering the window class, as shown in the following example.

BOOL InitApplication(hInstance)

HINSTANCE hInstance;

{

    WNDCLASS wc;

    wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

    wc.lpfnWndProc = (WNDPROC) MainWndProc;

    wc.cbClsExtra = 0;

    wc.cbWndExtra = 0;

    wc.hInstance = hInstance;

    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

    wc.hCursor = LoadCursor(NULL, IDC_IBEAM);

    wc.hbrBackground = GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName = "MainMenu";

    wc.lpszClassName = "MainWClass";

    return RegisterClass(&wc);

}

A double-click message is always preceded by a button down message. For this reason, applications typically use a double-click message to extend a task that it began during a button down message.


  6.2.4  Selecting a Line of Text

The example in this section is taken from a simple word-processing application. It includes code that enables the user to set the position of the caret by clicking anywhere on a line of text, and to select (highlight) a line of text by double-clicking anywhere on the line.

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)

HWND hwndMain;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    HDC hdc;                     /* handle of device context     */

    TEXTMETRIC tm;               /* font size data               */

    int i, j;                    /* loop counters                */

    int cCR = 0;                 /* count of carriage returns    */

    char ch;                     /* character from input buffer  */

    static int nBegLine;         /* beginning of selected line   */

    static int nCurrentLine = 0; /* currently selected line      */

    static int nLastLine = 0;    /* last text line               */

    static int nCaretPosX = 0;   /* x-coordinate of caret        */

    static int cch = 0;          /* number of characters entered */

    static int nCharWidth = 0;   /* exact width of a character   */

    static char szHilite[128];   /* text string to highlight     */

    static DWORD dwCharX;        /* average width of characters  */

    static DWORD dwLineHeight;   /* line height                  */

    static POINTS ptsCursor;     /* coordinates of mouse cursor  */

    static COLORREF crPrevText;  /* previous text color          */

    static COLORREF crPrevBk;    /* previous background color    */

    static PTCHAR pchInputBuf;   /* address of input buffer      */

    static BOOL fTextSelected = FALSE; /* text-selection flag    */

    switch (uMsg) {

        case WM_CREATE:

            /* Get the metrics of the current font. */

            hdc = GetDC(hwndMain);

            GetTextMetrics(hdc, &tm);

            ReleaseDC(hwndMain, hdc);

            /* Save the average character width and height. */

            dwCharX = tm.tmAveCharWidth;

            dwLineHeight = tm.tmHeight;

            /* Allocate a buffer to store keyboard input. */

            pchInputBuf = (LPSTR) GlobalAlloc(GPTR,

                BUFSIZE * sizeof(TCHAR));

            return 0;

        case WM_CHAR:

            switch (wParam) {

                case 0x08: /* backspace */

                case 0x0A: /* linefeed  */

                case 0x1B: /* escape    */

                    MessageBeep(0xFFFFFFFF);

                    return 0;

                case 0x09: /* tab */

                    /* Convert tabs to four consecutive spaces. */

                    for (i = 0; i < 4; i++)

                        SendMessage(hwndMain, WM_CHAR, 0x20, 0);

                    return 0;

                case 0x0D: /* carriage return */

                    /*

                     * Record the carriage return, and position

                     * the caret at the beginning of the new line.

                     */

                    pchInputBuf[cch++] = 0x0D;

                    nCaretPosX = 0;

                    nCurrentLine += 1;

                    break;

                default: /* displayable character */

                    ch = (char) wParam;

                    HideCaret(hwndMain);

                    /*

                     * Retrieve the character's width, and display

                     * the character.

                     */

                   hdc = GetDC(hwndMain);

                   GetCharWidth(hdc, (UINT) wParam, (UINT) wParam,

                        &nCharWidth);

                   TextOut(hdc, nCaretPosX,

                        nCurrentLine * dwLineHeight, &ch, 1);

                   ReleaseDC(hwndMain, hdc);

                    /* Store the character in the buffer. */

                    pchInputBuf[cch++] = ch;

                    /*

                     * Calculate the new horizontal position of

                     * the caret. If the new position exceeds the

                     * maximum, insert a carriage return and

                     * reposition the caret at the beginning of

                     * the next line.

                     */

                    nCaretPosX += nCharWidth;

                    if ((DWORD) nCaretPosX > dwMaxCharX) {

                        nCaretPosX = 0;

                        pchInputBuf[cch++] = 0x0D;

                        ++nCurrentLine;

                    }

                    ShowCaret(hwndMain);

                    break;

            }

            SetCaretPos(nCaretPosX, nCurrentLine * dwLineHeight);

            nLastLine = max(nLastLine, nCurrentLine);

            break;

        .

        . /* Process other messages. */

        .

        case WM_LBUTTONDOWN:

            /*

             * If a line of text is currently highlighted, redraw

             * the text to remove the highlighting.

             */

            if (fTextSelected) {

                hdc = GetDC(hwndMain);

                SetTextColor(hdc, crPrevText);

                SetBkColor(hdc, crPrevBk);

                TextOut(hdc, 0, nCurrentLine * dwLineHeight,

                    szHilite, lstrlen(szHilite));

                ReleaseDC(hwndMain, hdc);

                ShowCaret(hwndMain);

                fTextSelected = FALSE;

            }

            /* Save the current mouse-cursor coordinates. */

            ptsCursor = MAKEPOINTS(lParam);

            /*

             * Determine which line the cursor is on, and save

             * the line number. Do not allow line numbers greater

             * than the number of the last line of text. The

             * line number is later multiplied by the average

             * height of the current font. The result is used to

             * set the y-coordinate of the caret.

             */

            nCurrentLine = min((int)(ptsCursor.y / dwLineHeight),

                nLastLine);

            /*

             * Parse the text input buffer to find the first

             * character in the selected line of text. Each

             * line ends with a carriage return, so it is possible

             * to count the carriage returns to find the selected

             * line.

             */

            cCR = 0;

            nBegLine = 0;

            if (nCurrentLine != 0) {

                for (i = 0; (i < cch) &&

                        (cCR < nCurrentLine); i++) {

                    if (pchInputBuf[i] == 0x0D)

                        ++cCR;

                }

                nBegLine = i;

            }

            /*

             * Starting at the beginning of the selected line,

             * measure the width of each character, summing the

             * width with each character measured. Stop when the

             * sum is greater than the x-coordinate of the cursor.

             * The sum is used to set the x-coordinate of the

             * caret.

             */

            hdc = GetDC(hwndMain);

            nCaretPosX = 0;

            for (i = nBegLine;

                    (pchInputBuf[i] != 0x0D) && (i < cch); i++) {

               ch = pchInputBuf[i];

               GetCharWidth(hdc, (int) ch, (int) ch, &nCharWidth);

               if ((nCaretPosX + nCharWidth) > ptsCursor.x)

                    break;

               else

                    nCaretPosX += nCharWidth;

            }

            ReleaseDC(hwndMain, hdc);

            /* Set the caret to the user-selected position. */

            SetCaretPos(nCaretPosX, nCurrentLine * dwLineHeight);

            break;

        case WM_LBUTTONDBLCLK:

            /* Copy the selected line of text to a buffer. */

            for (i = nBegLine, j = 0; (pchInputBuf[i] != 0x0D) &&

                    (i < cch); i++)

                szHilite[j++] = pchInputBuf[i];

            szHilite[j] = '\0';

            /*

             * Hide the caret, invert the background and

             * foreground colors, and then redraw the selected

             * line.

             */

            HideCaret(hwndMain);

            hdc = GetDC(hwndMain);

            crPrevText = SetTextColor(hdc, RGB(255, 255, 255));

            crPrevBk = SetBkColor(hdc, RGB(0, 0, 0));

            TextOut(hdc, 0, nCurrentLine * dwLineHeight, szHilite,

                lstrlen(szHilite));

            SetTextColor(hdc, crPrevText);

            SetBkColor(hdc, crPrevBk);

            ReleaseDC(hwndMain, hdc);

            fTextSelected = TRUE;

            break;

            .

            . /* Process other messages. */

            .

        default:

            return DefWindowProc(hwndMain, uMsg, wParam, lParam);

    }

    return NULL;

}


  6.3  Functions and Messages

Following are the functions and messages used to receive and process mouse input.


  Functions

GetCapture
GetDoubleClickTime
mouse_event
ReleaseCapture
SetCapture
SetDoubleClickTime
SwapMouseButton


  Messages

WM_LBUTTONDBLCLK
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MBUTTONDBLCLK
WM_MBUTTONDOWN
WM_MBUTTONUP
WM_MOUSEACTIVATE
WM_MOUSEMOVE
WM_NCHITTEST
WM_NCLBUTTONDBLCLK
WM_NCLBUTTONDOWN
WM_NCLBUTTONUP
WM_NCMBUTTONDBLCLK
WM_NCMBUTTONDOWN
WM_NCMBUTTONUP
WM_NCMOUSEMOVE
WM_NCRBUTTONDBLCLK
WM_NCRBUTTONDOWN
WM_NCRBUTTONUP
WM_RBUTTONDBLCLK
WM_RBUTTONDOWN
WM_RBUTTONUP


7.1  About Timers
  Chapter 7    Timers

7.1  About Timers

A timer is an internal routine that repeatedly measures a specified interval, in milliseconds. Each time the interval called a time-out value elapses, the system notifies the window associated with the timer. Because the accuracy of a timer depends on the system clock rate and how often the application retrieves messages from the message queue, the time-out value is only approximate.

An application written for Microsoft® Windows (™)  creates a timer by using the SetTimer function. If a window handle is given in this function, the application creates the timer for that window. Then, whenever the time-out value elapses, the system posts a WM_TIMER message to the window. If no window handle is given in the SetTimer function, the application that created the timer must monitor its message queue for WM_TIMER messages and dispatch them to the appropriate window.

A new timer starts timing as soon as it is created. An application can change a timer's time-out value by using SetTimer and can destroy a timer by using the KillTimer function. To use system resources efficiently, applications should destroy timers that are no longer necessary.

Each timer has a unique identifier. When creating a timer, an application can either specify an identifier or have the system create a unique value. The first parameter of a WM_TIMER message contains the identifier of the timer that posted the message.


  7.2  Using Timers

This section shows how to perform the following tasks:

•	Create a timer.

•	Destroy a timer.

•	Process the WM_TIMER message.

•	Use a TimerProc callback function.


  7.2.1  Creating a Timer

The following code sample uses the SetTimer function to create two timers. The first timer is set for every 10 seconds, the second for every 5 minutes.

/* Set two timers. */

SetTimer(hwnd,             /* handle of main window */

    IDT_TIMER1,            /* timer identifier      */

    10000,                 /* 10-second interval    */

    (TIMERPROC) NULL);     /* no timer callback     */

SetTimer(hwnd,             /* handle of main window */

    IDT_TIMER2,            /* timer identifier      */

    300000,                /* 5-minute interval     */

    (TIMERPROC) NULL);     /* no timer callback     */

To process the WM_TIMER messages generated by these timers, add a WM_TIMER case statement to the window procedure for hwnd.

case WM_TIMER:

    switch (wParam) {

        case IDT_TIMER1:

            .

            . /* Process the 10-second timer. */

            .

            return 0;

        case IDT_TIMER2:

            .

            . /* Process the 5-minute timer. */

            .

            return 0;

    }

An application can also create a timer whose WM_TIMER messages are processed not by the main window procedure but by an application-defined callback function, as in the following code sample, which creates a timer and uses the callback function MyTimerProc to process the timer's WM_TIMER messages.

/* Set the timer. */

SetTimer(hwnd,                /* handle of main window */

    IDT_TIMER3,               /* timer identifier      */

    5000,                     /* 5-second interval     */

    (TIMERPROC) MyTimerProc); /* timer callback        */

The calling convention for MyTimerProc must be based on the Microsoft® Win32 (™)  callback function TimerProc.

If your application creates a timer without specifying a window handle, your application must monitor the message queue for WM_TIMER messages and dispatch them to the appropriate window.

HWND hwndTimer;   /* handle of window for timer messages */

MSG msg;          /* message structure */

    while (GetMessage(&msg, /* message structure                */

            NULL,           /* handle of window receiving msg.  */

            NULL,           /* lowest message to examine        */

            NULL))          /* highest message to examine       */

        {

        /* Post WM_TIMER messages to the hwndTimer procedure. */

        if (msg.message == WM_TIMER) {

            msg.hwnd = hwndTimer;

        }

        TranslateMessage(&msg); /* translates virtual-key codes */

        DispatchMessage(&msg);  /* dispatches message to window */

    }


  7.2.2  Destroying a Timer

Applications should use the KillTimer function to destroy timers that are no longer necessary. The following example destroys the timers identified by the constants IDT_TIMER1, IDT_TIMER2, and IDT_TIMER3.

/* Destroy the timers. */

KillTimer(hwnd, IDT_TIMER1);

KillTimer(hwnd, IDT_TIMER2);

KillTimer(hwnd, IDT_TIMER3);


  7.2.3  Creating a Mousetrap

Sometimes it is necessary to prevent more input while you have a cursor on the screen. One way to accomplish this is to create a special routine that traps mouse input until a specific event occurs. Many developers refer to this routine as "building a mousetrap."

The following code sample uses the SetTimer and KillTimer functions to create a simple mousetrap. SetTimer creates a timer that sends a WM_TIMER message every 10 seconds. Each time the application receives a WM_TIMER message, it records the cursor location. If the current location is the same as the previous location and the application's main window is minimized, the application moves the cursor to the icon. When the application closes, KillTimer stops the timer.

HICON hIcon1;               /* icon handle                       */

POINT ptOld;                /* previous cursor location          */

UINT uResult;               /* SetTimer's return value           */

HINSTANCE hinstance;        /* handle of current instance        */

.

. /* Perform application initialization here. */

.

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));

wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));

/* Record the initial cursor position. */

GetCursorPos(&ptOld);

/* Set the timer for the mousetrap. */

uResult = SetTimer(hwnd,             /* handle of main window */

    IDT_MOUSETRAP,                   /* timer identifier      */

    10000,                           /* 10-second interval    */

    (TIMERPROC) NULL);               /* no timer callback     */

if (uResult == 0) {

    ErrorHandler("No timer is available.");

}

LONG APIENTRY MainWndProc(

HWND hwnd,          /* handle of main window  */

UINT message,       /* type of message        */

UINT wParam,        /* additional information */

LONG lParam)        /* additional information */

{

    HDC hdc;        /* handle of device context     */

    POINT pt;       /* current cursor location      */

    RECT rc;        /* location of minimized window */

    switch (message) {

        .

        . /* Process other messages. */

        .

        case WM_TIMER:

            /*

             * If the window is minimized, compare the current

             * cursor position with the one from 10 seconds

             * earlier. If the cursor position has not changed,

             * move the cursor to the icon.

             */

            if (IsIconic(hwnd)) {

                GetCursorPos(&pt);

                if ((pt.x == ptOld.x) && (pt.y == ptOld.y)) {

                    GetWindowRect(hwnd, &rc);

                    SetCursorPos(rc.left, rc.top);

                }

                else {

                    ptOld.x = pt.x;

                    ptOld.y = pt.y;

                }

            }

            return 0;

        case WM_DESTROY:

            /* Destroy the timer. */

            KillTimer(hwnd, IDT_MOUSETRAP);

            PostQuitMessage(0);

            break;

        .

        . /* Process other messages. */

        .

}

Although the following code sample also creates a mousetrap, it processes the WM_TIMER message through the application-defined callback function MyTimerProc, rather than through the application's message queue.

UINT uResult;               /* SetTimer's return value     */

HICON hIcon1;               /* icon handle                 */

POINT ptOld;                /* previous cursor location    */

HINSTANCE hinstance;        /* handle of current instance  */

.

. /* Perform application initialization here. */

.

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));

wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));

/* Record the current cursor position. */

GetCursorPos(&ptOld);

/* Set the timer for the mousetrap. */

uResult = SetTimer(hwnd,      /* handle of main window */

    IDT_MOUSETRAP,            /* timer identifier      */

    10000,                    /* 10-second interval    */

    (TIMERPROC) MyTimerProc); /* timer callback        */

if (uResult == 0) {

    ErrorHandler("No timer is available.");

}

LONG APIENTRY MainWndProc(

HWND hwnd,          /* handle of main window  */

UINT message,       /* type of message        */

UINT wParam,        /* additional information */

LONG lParam)        /* additional information */

{

    HDC hdc;        /* handle of device context */

    switch (message) {

        .

        . /* Process other messages. */

        .

        case WM_DESTROY:

            /* Destroy the timer. */

            KillTimer(hwnd, IDT_MOUSETRAP);

            PostQuitMessage(0);

            break;

        .

        . /* Process other messages. */

        .

}

/*

 * MyTimerProc is an application-defined callback function that

 * processes WM_TIMER messages.

 */

VOID CALLBACK MyTimerProc(

    HWND hwnd,        /* handle of window for timer messages */

    UINT message,     /* WM_TIMER message                    */

    UINT idTimer,     /* timer identifier                    */

    DWORD dwTime)     /* current system time                 */

{

    RECT rc;

    POINT pt;

    /*

     * If the window is minimized, compare the current

     * cursor position with the one from 10 seconds earlier.

     * If the cursor position has not changed, move the

     * cursor to the icon.

     */

    if (IsIconic(hwnd)) {

        GetCursorPos(&pt);

        if ((pt.x == ptOld.x) && (pt.y == ptOld.y)) {

            GetWindowRect(hwnd, &rc);

            SetCursorPos(rc.left, rc.top);

        }

        else {

            ptOld.x = pt.x;

            ptOld.y = pt.y;

        }

    }

}


  7.3  Functions

The following functions are used with timers.

KillTimer
SetTimer
TimerProc


8.1  About Hooks
  Chapter 8    Hooks

8.1  About Hooks

A hook is a point in the Microsoft® Windows (™)  message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure. This chapter describes Windows hooks and explains how to use them in a Windows-based application.


  8.1.1  Hook Chains

Windows contains many different types of hooks; each type provides access to a different aspect of the Windows message-handling mechanism. For example, an application can use the WH_MOUSE hook to monitor the message traffic for mouse messages.

Windows maintains a separate hook chain for each type of hook. A hook chain is a list of pointers to special, application-defined callback functions called hook procedures. When a message occurs that is associated with a particular type of hook, Windows passes the message to each hook procedure referenced in the hook chain, one after the other. The action a hook procedure can take depends on the type of hook involved. The hook procedures for some types of hooks can only monitor messages; others can modify messages or stop their progress though the chain, preventing them from reaching the next hook procedure or the destination window.

Hooks tend to slow down the system because they increase the amount of processing the system must perform for each message. A developer should install a hook only when necessary, and remove it as soon as possible.


  8.1.2  Hook Procedures

To take advantage of a particular type of hook, the developer provides a hook procedure and uses the SetWindowsHookEx function to install it into the chain associated with the hook. A hook procedure must have the following syntax:

LRESULT CALLBACK HookProc(nCode, wParam, lParam)
int nCode;
WPARAM wParam;
LPARAM lParam;

HookProc is a placeholder for an application-defined name. Because Windows must call the hook procedure, the actual name must be exported by listing it and, optionally, its ordinal value, in the EXPORTS statement of the application's module-definition file.

The nCode parameter is a hook code that the hook procedure uses to determine the action to perform. The value of the hook code depends on the type of the hook; each type has its own characteristic set of hook codes. The values of the wParam and lParam parameters depend on the hook code, but they typically contain information about a message that was sent or posted.

SetWindowsHookEx always installs a hook procedure at the beginning of a hook chain. When an event occurs that is monitored by a particular type of hook, Windows calls the procedure at the beginning of the hook chain associated with the hook. Each hook procedure in the chain determines whether to pass the event to the next procedure. A hook procedure passes an event to the next procedure by calling the CallNextHookEx function.

Note that the hook procedures for some types of hooks can only monitor messages. Windows passes messages to each hook procedure, regardless of whether a particular procedure calls CallNextHookEx.

A hook procedure can be global, monitoring messages for all threads in the system, or it can be thread specific, monitoring messages for only an individual thread. A global hook procedure can be called in the context of any application, so the procedure must be in a separate dynamic-link library (DLL) module. A thread specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application's code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL. For information about DLLs, see Chapter 50, "Dynamic-Link Libraries," in the Microsoft Win32 Programmer's Reference, Volume 2.


  8.1.3  Hook Types

Each type of hook enables an application to monitor a different aspect of the Windows message-handling mechanism. The following sections describe the types of hooks available in Windows. For more information about each type of hook, see the description of the appropriate hook procedure in the Microsoft Win32 Programmer's Reference, Volumes 3 and 4.


  8.1.3.1  WH_CALLWNDPROC Hook

The WH_CALLWNDPROC hook enables an application to monitor messages sent to window procedures by the SendMessage function. Windows calls a WH_CALLWNDPROC hook procedure before passing the message to the receiving window procedure.


  8.1.3.2  WH_CBT Hook

Windows calls a WH_CBT hook procedure before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the input focus; or before synchronizing with the system message queue. The value the hook procedure returns determines whether Windows allows or prevents one of these operations. The WH_CBT hook is intended primarily for Windows computer-based training (CBT) applications.


  8.1.3.3  WH_DEBUG Hook

Windows calls a WH_DEBUG hook procedure before calling hook procedures associated with any other hook in the system. An application can use this hook to determine whether to allow the system to call hook procedures associated with other types of hooks.


  8.1.3.4  WH_GETMESSAGE Hook

The WH_GETMESSAGE hook enables an application to monitor messages about to be returned by the GetMessage or PeekMessage function. An application uses the WH_GETMESSAGE hook to monitor mouse and keyboard input and other messages posted to a queue.


  8.1.3.5  WH_JOURNALRECORD Hook

The WH_JOURNALRECORD hook enables an application to monitor and record input events. Typically, an application uses this hook to record a sequence of mouse and keyboard events it can play back later by using the WH_JOURNALPLAYBACK hook. The WH_JOURNALRECORD hook is a global hook — it cannot be used as a thread-specific hook.


  8.1.3.6  WH_JOURNALPLAYBACK Hook

The WH_JOURNALPLAYBACK hook enables an application to insert messages into the system message queue. An application might use this hook to play back a series of mouse and keyboard events recorded earlier by using the WH_JOURNALRECORD hook. Regular mouse and keyboard input is disabled as long as a WH_JOURNALPLAYBACK hook is installed. A WH_JOURNALPLAYBACK hook is a global hook — it cannot be used as a thread-specific hook.

The WH_JOURNALPLAYBACK hook returns a time-out value. This value tells the system how many milliseconds to wait before processing the current message from the playback hook. This enables the hook to control the timing of the events it plays back.


  8.1.3.7  WH_KEYBOARD Hook

The WH_KEYBOARD hook enables an application to monitor message traffic for WM_KEYDOWN and WM_KEYUP messages about to be returned by the GetMessage or PeekMessage function. An application uses the WH_KEYBOARD hook to monitor keyboard input posted to a message queue.


  8.1.3.8  WH_MOUSE Hook

The WH_MOUSE hook enables an application to monitor mouse messages about to be returned by the GetMessage or PeekMessage function. An application uses the WH_MOUSE hook to monitor mouse input posted to a message queue.


  8.1.3.9  WH_MSGFILTER and WH_SYSMSGFILTER Hooks

The WH_MSGFILTER and WH_SYSMSGFILTER hooks enable an application to monitor messages about to be processed by a menu, scroll bar, message box, or dialog box, and to detect when a different window is about to be activated as a result of the user's pressing the ALT+TAB or ALT+ESC key combination. The WH_MSGFILTER hook can monitor only messages passed to a menu, scroll bar, message box, or dialog box created by the application that installed the hook procedure. The WH_SYSMSGFILTER hook monitors such messages for all applications.

The WH_MSGFILTER and WH_SYSMSGFILTER hooks enable an application to perform message filtering during modal loops that is equivalent to the filtering done in the main message loop. For example, an application often examines a new message in the main loop between the time it retrieves the message from the queue and the time it dispatches the message, performing special processing as appropriate. However, during a modal loop, the system retrieves and dispatches messages without allowing an application the chance to filter the messages in its main message loop. If an application installs a WH_MSGFILTER or WH_SYSMSGFILTER hook procedure, the system calls the procedure during the modal loop. For more information about modal loops, see Chapter 1, »Windows«.

An application can call the WH_MSGFILTER hook directly by calling the CallMsgFilter function. By using this function, the application can use the same code to filter messages during modal loops as it uses in the main message loop. To do so, the application encapsulates the filtering operations in a WH_MSGFILTER hook procedure and calls CallMsgFilter between the calls to the GetMessage and DispatchMessage functions.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

    if (!CallMsgFilter(&qmsg, 0))

        DispatchMessage(&qmsg);

}

The last argument of CallMsgFilter is simply passed to the hook procedure; the application can enter any value. The hook procedure, by defining a constant such as MSGF_MAINLOOP, can use this value to determine where the procedure was called from.


  8.1.3.10  WH_SHELL Hook

A Windows shell application can use the WH_SHELL hook to receive important notifications. Windows calls a WH_SHELL hook procedure when the shell application is about to be activated and when a top-level window is created or destroyed.


  8.2  Using Hooks

This section explains how to install and release hook procedures. It also contains an example demonstrating how to use hooks to monitor the system for a variety of events.


  8.2.1  Installing and Releasing Hook Procedures

You can install a hook procedure by calling the SetWindowsHookEx function and specifying the type of hook calling the procedure, whether the procedure should be associated with all threads or with a particular thread, and a pointer to a procedure entry point.

You must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle of the DLL module before it can install the hook procedure. The LoadLibrary function, when given the name of the DLL, returns the handle of the DLL module. After you have the handle, you can call the GetProcAddress function to retrieve the address of the hook procedure. Finally, you use SetWindowsHookEx to install the hook procedure address in the appropriate hook chain. SetWindowsHookEx passes the module handle, a pointer to the hook-procedure entry point, and 0 for the thread identifier, indicating that the hook procedure should be associated with all threads in the system. This sequence is shown in the following example.

HOOKPROC hkprcSysMsg;

static HINSTANCE hinstDLL;

static HHOOK hhookSysMsg;

    .

    .

    .

hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll");

hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");

hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,

    hkprcSysMsg, hinstDLL, 0);

    .

    .

    .

You can release a thread-specific hook procedure (remove its address from the hook chain) by calling the UnhookWindowsHookEx function, specifying the handle of the hook procedure to release. Release a hook procedure as soon as your application no longer needs it.

You can release a global hook procedure by using UnhookWindowsHookEx, but this function does not free the DLL containing the hook procedure. This is because global hook procedures are called in the process context of every Windows-based application in the system, causing an implicit call to the LoadLibrary function for all of those processes. Because a call to the FreeLibrary function cannot be made for another process, there is then no way to free the DLL. Windows eventually frees the DLL after all processes explicitly linked to the DLL have either terminated or called FreeLibrary and all processes that called the hook procedure have resumed processing outside the DLL.

An alternative method for installing a global hook procedure is to provide an installation function in the DLL, along with the hook procedure. With this method, the installing application does not need the handle of the DLL module. By linking with the DLL, the application gains access to the installation function. The installation function can supply the DLL module handle and other details in the call to SetWindowsHookEx. The DLL can also contain a function that releases the global hook procedure; the application can call this hook-releasing function when terminating.


  8.2.2  Monitoring System Events

The example in this section uses a variety of thread-specific hook procedures to monitor the system for events affecting a thread. It demonstrates how to process events for the following types of hook procedures:

WH_CALLWNDPROC
WH_CBT
WH_DEBUG
WH_GETMESSAGE
WH_KEYBOARD
WH_MOUSE
WH_MSGFILTER

In this example, the user can install and remove a hook procedure by using the menu. When a hook procedure is installed and an event that is monitored by the procedure occurs, the procedure writes information about the event to the client area of the application's main window.

#define NUMHOOKS 7

/* Global variables */

typedef struct _MYHOOKDATA {

    int nType;

    HOOKPROC hkprc;

    HHOOK hhook;

} MYHOOKDATA;

MYHOOKDATA myhookdata[NUMHOOKS];

LONG APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)

HWND hwndMain;

UINT uMsg;

UINT wParam;

LONG lParam;

{

    static BOOL afHooks[NUMHOOKS];

    int index;

    static HMENU hmenu;

    switch (uMsg) {

        case WM_CREATE:

            /* Save the menu handle. */

            hmenu = GetMenu(hwndMain);

            /*

             * Initialize structures with hook data. The menu-item

             * identifiers are defined as 0 through 6 in the

             * header file. They can be used to identify array

             * elements both here and during the WM_COMMAND

             * message.

             */

            myhookdata[IDM_CALLWNDPROC].nType = WH_CALLWNDPROC;

            myhookdata[IDM_CALLWNDPROC].hkprc = CallWndProc;

            myhookdata[IDM_CBT].nType = WH_CBT;

            myhookdata[IDM_CBT].hkprc = CBTProc;

            myhookdata[IDM_DEBUG].nType = WH_DEBUG;

            myhookdata[IDM_DEBUG].hkprc = DebugProc;

            myhookdata[IDM_GETMESSAGE].nType = WH_GETMESSAGE;

            myhookdata[IDM_GETMESSAGE].hkprc = GetMsgProc;

            myhookdata[IDM_KEYBOARD].nType = WH_KEYBOARD;

            myhookdata[IDM_KEYBOARD].hkprc = KeyboardProc;

            myhookdata[IDM_MOUSE].nType = WH_MOUSE;

            myhookdata[IDM_MOUSE].hkprc = MouseProc;

            myhookdata[IDM_MSGFILTER].nType = WH_MSGFILTER;

            myhookdata[IDM_MSGFILTER].hkprc = MessageProc;

            /* Initialize all flags in the array to FALSE. */

            memset(afHooks, FALSE, sizeof(afHooks));

            return 0;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                /*

                 * The user selected a hook command from the menu.

                 */

                case IDM_CALLWNDPROC:

                case IDM_CBT:

                case IDM_DEBUG:

                case IDM_GETMESSAGE:

                case IDM_KEYBOARD:

                case IDM_MOUSE:

                case IDM_MSGFILTER:

                    /*

                     * Use the menu-item identifier as an index

                     * into the array of structures with hook data.

                     */

                    index = LOWORD(wParam);

                    /*

                     * If the selected type of hook procedure isn't

                     * installed yet, install it and check the

                     * associated menu item.

                     */

                    if (!afHooks[index]) {

                        myhookdata[index].hhook = SetWindowsHookEx(

                            myhookdata[index].nType,

                            myhookdata[index].hkprc,

                            (HINSTANCE) NULL, GetCurrentThreadId());

                        CheckMenuItem(hmenu, index,

                            MF_BYCOMMAND | MF_CHECKED);

                        afHooks[index] = TRUE;

                    }

                    /*

                     * If the selected type of hook procedure is

                     * already installed, remove it and remove the

                     * check mark from the associated menu item.

                     */

                    else {

                        UnhookWindowsHookEx(myhookdata[index].hhook);

                        CheckMenuItem(hmenu, index,

                            MF_BYCOMMAND | MF_UNCHECKED);

                        afHooks[index] = FALSE;

                    }

                default:

                    return (DefWindowProc(hwndMain, uMsg, wParam,

                        lParam));

            }

            break;

            .

            . /* Process other messages. */

            .

        default:

            return DefWindowProc(hwndMain, uMsg, wParam, lParam);

    }

    return NULL;

}

/****************************************************************

  WH_CALLWNDPROC hook procedure

 ****************************************************************/

LRESULT CALLBACK CallWndProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szCWPBuf[256];

    CHAR szMsg[16];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0)  /* do not process message */

        return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,

                wParam, lParam);

    /*

     * Call an application-defined function that converts a message

     * constant to a string and copies it to a buffer.

     */

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);

    switch (nCode) {

        case HC_ACTION:

            cch = wsprintf(szCWPBuf,

               "CALLWNDPROC - tsk: %ld, msg: %s, %d times   ",

                wParam, szMsg, c++);

            TextOut(hdc, 2, 15, szCWPBuf, cch);

            break;

        default:

            break;

    }

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,

        wParam, lParam);

}

/****************************************************************

  WH_GETMESSAGE hook procedure

 ****************************************************************/

LRESULT CALLBACK GetMsgProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szMSGBuf[256];

    CHAR szRem[16];

    CHAR szMsg[16];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0) /* do not process message */

        return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,

            wParam, lParam);

    switch (nCode) {

        case HC_ACTION:

            switch (wParam) {

                case PM_REMOVE:

                    lstrcpy(szRem, "PM_REMOVE");

                    break;

                case PM_NOREMOVE:

                    lstrcpy(szRem, "PM_NOREMOVE");

                    break;

                default:

                    lstrcpy(szRem, "Unknown");

                    break;

            }

            /*

             * Call an application-defined function that converts a

             * message constant to a string and copies it to a

             * buffer.

             */

            LookUpTheMessage((PMSG) lParam, szMsg);

            hdc = GetDC(hwndMain);

            cch = wsprintf(szMSGBuf,

                "GETMESSAGE - wParam: %s, msg: %s, %d times   ",

                szRem, szMsg, c++);

            TextOut(hdc, 2, 35, szMSGBuf, cch);

            break;

        default:

            break;

    }

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,

        wParam, lParam);

}

/****************************************************************

  WH_DEBUG hook procedure

 ****************************************************************/

LRESULT CALLBACK DebugProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szBuf[128];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0)  /* do not process message */

        return CallNextHookEx(myhookdata[DEBUG].hhook, nCode,

            wParam, lParam);

    hdc = GetDC(hwndMain);

    switch (nCode) {

        case HC_ACTION:

            cch = wsprintf(szBuf,

                "DEBUG - nCode: %d, tsk: %ld, %d times   ",

                nCode,wParam, c++);

            TextOut(hdc, 2, 55, szBuf, cch);

            break;

        default:

            break;

    }

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[DEBUG].hhook, nCode, wParam,

        lParam);

}

/****************************************************************

  WH_CBT hook procedure

 ****************************************************************/

LRESULT CALLBACK CBTProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szBuf[128];

    CHAR szCode[128];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0)  /* do not process message */

        return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,

            lParam);

    hdc = GetDC(hwndMain);

    switch (nCode) {

        case HCBT_ACTIVATE:

            lstrcpy(szCode, "HCBT_ACTIVATE");

            break;

        case HCBT_CLICKSKIPPED:

            lstrcpy(szCode, "HCBT_CLICKSKIPPED");

            break;

        case HCBT_CREATEWND:

            lstrcpy(szCode, "HCBT_CREATEWND");

            break;

        case HCBT_DESTROYWND:

            lstrcpy(szCode, "HCBT_DESTROYWND");

            break;

        case HCBT_KEYSKIPPED:

            lstrcpy(szCode, "HCBT_KEYSKIPPED");

            break;

        case HCBT_MINMAX:

            lstrcpy(szCode, "HCBT_MINMAX");

            break;

        case HCBT_MOVESIZE:

            lstrcpy(szCode, "HCBT_MOVESIZE");

            break;

        case HCBT_QS:

            lstrcpy(szCode, "HCBT_QS");

            break;

        case HCBT_SETFOCUS:

            lstrcpy(szCode, "HCBT_SETFOCUS");

            break;

        case HCBT_SYSCOMMAND:

            lstrcpy(szCode, "HCBT_SYSCOMMAND");

            break;

        default:

            lstrcpy(szCode, "Unknown");

            break;

    }

    cch = wsprintf(szBuf, "CBT - nCode: %s, tsk: %ld, %d times   ",

        szCode, wParam, c++);

    TextOut(hdc, 2, 75, szBuf, cch);

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,

        lParam);

}

/****************************************************************

  WH_MOUSE hook procedure

 ****************************************************************/

LRESULT CALLBACK MouseProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szBuf[128];

    CHAR szMsg[16];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0)  /* do not process the message */

        return CallNextHookEx(myhookdata[MOUSE].hhook, nCode,

            wParam, lParam);

    /*

     * Call an application-defined function that converts a message

     * constant to a string and copies it to a buffer.

     */

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);

    cch = wsprintf(szBuf,

        "MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times   ",

        nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++);

    TextOut(hdc, 2, 95, szBuf, cch);

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[MOUSE].hhook, nCode, wParam,

        lParam);

}

/****************************************************************

  WH_KEYBOARD hook procedure

 ****************************************************************/

LRESULT CALLBACK KeyboardProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szBuf[128];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0)  /* do not process message */

        return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode,

            wParam, lParam);

    hdc = GetDC(hwndMain);

    cch = wsprintf(szBuf, "KEYBOARD - nCode: %d, vk: %d, %d times ",

        nCode, wParam, c++);

    TextOut(hdc, 2, 115, szBuf, cch);

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, wParam,

        lParam);

}

/****************************************************************

  WH_MSGFILTER hook procedure

 ****************************************************************/

LRESULT CALLBACK MessageProc(nCode, wParam, lParam)

int nCode;

WPARAM wParam;

LPARAM lParam;

{

    CHAR szBuf[128];

    CHAR szMsg[16];

    CHAR szCode[32];

    HDC hdc;

    static int c = 0;

    int cch;

    if (nCode < 0)  /* do not process message */

        return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,

            wParam, lParam);

    switch (nCode) {

        case MSGF_DIALOGBOX:

            lstrcpy(szCode, "MSGF_DIALOGBOX");

            break;

        case MSGF_MENU:

            lstrcpy(szCode, "MSGF_MENU");

            break;

        case MSGF_SCROLLBAR:

            lstrcpy(szCode, "MSGF_SCROLLBAR");

            break;

        case MSGF_NEXTWINDOW:

            lstrcpy(szCode, "MSGF_NEXTWINDOW");

            break;

        default:

            wsprintf(szCode, "Unknown: %d", nCode);

            break;

    }

    /*

     * Call an application-defined function that converts a message

     * constant to a string and copies it to a buffer.

     */

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);

    cch = wsprintf(szBuf,

        "MSGFILTER  nCode: %s, msg: %s, %d times    ",

        szCode, szMsg, c++);

    TextOut(hdc, 2, 135, szBuf, cch);

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,

        wParam, lParam);

}


  8.3  Functions

Following are the Windows functions and the message used with hooks.


  Functions

CallMsgFilter
CallNextHookEx
CallWndProc
CBTProc
DebugProc
DefHookProc
GetMsgProc
HardwareProc
JournalPlaybackProc
JournalRecordProc
KeyboardProc
MessageProc
MouseProc
SetWindowsHook
SetWindowsHookEx
ShellProc
SysMsgProc
UnhookWindowsHook
UnhookWindowsHookEx


  Message

WM_QUEUESYNC


9.1  About Controls
  Chapter 9    Controls

9.1  About Controls

In Microsoft® Windows (™) , a control is a child window an application uses in conjunction with another window to carry out simple input and output (I/O) tasks. Controls are most often used within dialog boxes, but they can also be used in other windows. Controls within dialog boxes provide the user with the means to type text, choose options, and direct a dialog box to complete its action. Controls in other windows provide a variety of services, such as letting the user choose commands, view status, and view and edit text.

Like other windows, each control belongs to a window class, either predefined or application defined. The window class and the corresponding window procedure define the properties of the control, its appearance, behavior, and purpose. An application can create controls individually by specifying the name of the window class when calling the CreateWindow or CreateWindowEx function. An application can also direct Windows to create controls for a dialog box by specifying the controls in the dialog box template.

Controls are child windows. When Windows creates controls for a dialog box, each control is the child of the dialog box. When an application creates a control, the control is the child of a window identified by the application. This relationship is important because a control sends messages, called notification messages, to its parent window when events, such as input from the user, occur in the control. The application relies on these notification messages to determine what action the user wants the application to take.

Because controls are windows, an application can manipulate them by using the window-management functions, such as the ShowWindow and EnableWindow functions. If the window class for a control supports control messages, an application can also manipulate a control of that class by using the SendMessage function to send these messages to the control. The purpose and function of each control message is specific to the window class and is defined by the control's window procedure.


  9.1.1  Predefined Controls

Windows provides several predefined window classes for controls. Controls belonging to these window classes are called predefined controls. An application creates a predefined control of a particular type by specifying the appropriate window class name in either the CreateWindow function or the dialog box template. Following are the predefined window classes.

Name	Description
BUTTON	Creates button controls. These controls typically notify the parent window when the user chooses the control.
LISTBOX	Creates list boxes. These controls display a list from which the user can select one or more items.
EDIT	Creates edit controls. These controls let the user view and edit text.
COMBOBOX	Creates combo boxes. These controls are a combination of list boxes and edit controls, letting the user choose and edit items.
SCROLLBAR	Creates scroll bar controls. These controls let the user choose the direction and distance to scroll information in a related window.
STATIC	Creates static controls. These controls often act as labels for other controls.
Each predefined window class has a corresponding set of control styles that enable an application to vary the appearance and behavior of the controls it creates. For example, the BUTTON class supports styles to create push buttons, radio buttons, check boxes, and group boxes. An application specifies the style when creating the control.

Each predefined window class has a corresponding set of notification and control messages. Applications rely on the notification messages to determine when the user has provided input to the controls. For example, a push button sends a BN_CLICKED message to the parent window when the user chooses the button. Applications use the control messages to retrieve information from the controls and to manipulate the appearance and behavior of the controls. For example, an application can send a BM_GETCHECK message to a check box to determine whether it currently contains a check mark.

Most applications make extensive use of predefined controls in dialog boxes and other windows. Because predefined controls offer many capabilities, a full discussion of each is beyond the scope of this chapter. For more information about the predefined controls, see the individual chapters for each window class following this chapter.


  9.1.2  Custom Controls

Applications can create custom controls to carry out tasks not supported by predefined controls. Windows provides the following ways to create custom controls:

•	Use owner-drawn buttons, list boxes, and combo boxes.

•	Subclass an existing control-window class.

•	Register and implement from scratch an application-defined window class.

Buttons, list boxes, and combo boxes have owner-drawn styles available that direct the control to send a message to the parent window whenever the control must be drawn. This feature permits an application to alter the appearance of a control. For buttons, the owner-drawn style affects how the system draws the entire control. For list boxes and combo boxes, the parent window draws the items within the control, and the control draws its own outline. For example, an application can customize a list box so that it displays a small bitmap beside each item in the list.

An application can designate list boxes, combo boxes, and buttons as owner-drawn controls by creating them with the appropriate style. When a control has the owner-drawn style, Windows handles the user's interaction with the control as usual, performing such tasks as detecting when a user has chosen a button and notifying the button's owner of the event. However, because the control is owner drawn, the parent window of the control is responsible for the visual appearance of the control. For more information about owner-drawn controls, see the individual chapters for buttons, list boxes, and combo boxes.

Subclassing an existing control is another way to create a custom control. The subclass procedure can alter selected behaviors of the control by processing those messages that affect the selected behaviors. All other messages pass to the original window procedure for the control. For example, an application can display a small bitmap next to the text in a read-only, single-line edit control by subclassing the control and processing the WM_PAINT message. For more information about subclassing, see Chapter 3, »Window Classes«.

Although an application may subclass a predefined control, it relies on the window procedure of the control to provide all other aspects of the control's behavior. For more information about a control's behavior, see the individual chapters for the predefined controls.

An application can create custom controls by registering an application-defined window class and specifying the name of the window class in the CreateWindow or CreateWindowEx function or in the dialog box template. The process for registering an application-defined window class for a custom control is the same as for registering a class for an ordinary window. Each class must have a unique name, a corresponding window procedure, and other information.

At a minimum, the window procedure draws the control. If an application uses the control to let the user type information, the window procedure also processes input messages from the keyboard and mouse and sends notification messages to the parent window. In addition, if the control supports control messages, the window procedure processes messages sent to it by the parent window or other windows. For example, controls often process the WM_GETDLGCODE message sent by dialog boxes to direct a dialog box to process keyboard input in a given way.


  9.1.3  Notification Messages

A control should send a notification message to its parent window to notify the parent about user input or changes to the control. The notification message is a WM_COMMAND message that includes a control identifier and a notification code identifying the nature of the event. A control identifier is a unique number the application uses to identify the control sending the message. The application sets the identifier for a control when it creates the control. The application specifies the identifier either in the hMenu parameter of the CreateWindow or CreateWindowEx function or in the id member of the dialog box template.

Because the control does not set the control identifier, the control must retrieve the identifier before it can send notification messages. A control must use the GetDlgCtrlID function to retrieve its own control identifier. Although the control identifier is specified as the menu handle when the control is created, the GetMenu function cannot be used to retrieve the identifier. Alternatively, a control can retrieve the identifier from the hMenu member in the CREATESTRUCT structure while processing the WM_CREATE message.


  9.1.4  Control Messages

A parent window or other windows send control messages to direct a control to carry out specific tasks. The window procedure processes these messages and carries out the requested action.

Control messages can be predefined or application defined. Windows has several predefined messages, such as WM_GETTEXT and WM_GETDLGCODE, that it sends to controls. These messages typically correspond to window-management functions that carry out actions on windows. In general, the window procedure for an application-defined control should process any predefined control message in the following table if the message affects the operation of the control.

Message	Recommendation
WM_GETDLGCODE	Process if the control uses the ENTER, ESC, TAB, or direction keys. The IsDialogMessage function sends this message to controls in a dialog box to determine whether to process the keys or pass them to the control.
WM_GETFONT	Process if the WM_SETFONT message is also processed.
WM_GETTEXT	Process if the control text is not the same as the title specified by the CreateWindow or CreateWindowEx function.
WM_GETTEXTLENGTH	Process if the control text is not the same as the title specified by the CreateWindow or CreateWindowEx function.
WM_KILLFOCUS	Process if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus.
WM_SETFOCUS	Process if the control displays a caret, a focus rectangle, or another item to indicate that it has the input focus.
WM_SETTEXT	Process if the control text is not the same as the title specified by the CreateWindow or CreateWindowEx function.
WM_SETFONT	Process if the control displays text. Windows sends this message when creating a dialog box that has the DS_SETFONT style.
Application-defined control messages are specific to the given control and must be explicitly sent to the control by using a SendMessage or SendDlgItemMessage function. The numeric value for each message must be unique and must not conflict with the values of other window messages. To ensure that application-defined message values do not conflict, an application should create each value by adding a unique number to the WM_USER value.


  9.2  Messages

Following are the messages used with controls.

WM_GETFONT
WM_SETFONT
WM_SETTEXT


10.1  About Buttons
  Chapter 10    Buttons

10.1  About Buttons

Microsoft® Windows (™)  provides dialog boxes and controls to support communication between an application and the user. A button is a control the user can turn on or off to provide input to an application. There are several types of buttons and, within each type, one or more styles to distinguish among buttons of the same type. The user turns a button on or off by selecting it using the mouse or keyboard. Selecting a button typically changes its visual appearance and state (from checked to unchecked, for example). Windows, the button, and the application cooperate in changing the button's appearance and state. A button can send messages to its parent window, and a parent window can send messages to a button. Some buttons are painted by Windows, some by the application. Buttons can be used alone or in groups and can appear with or without a label. They belong to the BUTTON window class.

Although an application can use buttons in overlapped, pop-up, and child windows, they are designed for use in dialog boxes, where Windows standardizes their behavior. If an application uses buttons outside dialog boxes, it increases the risk that the application may behave in a nonstandard fashion. Applications typically either use buttons in dialog boxes or use window subclassing to create customized buttons.

For general information about controls, see Chapter 9, »Controls«. For more information about dialog boxes, see Chapter 18, »Dialog Boxes«. For more information about window subclassing, see Chapter 4, »Window Procedures«.


  10.1.1  Button Types and Styles

Windows provides five kinds of buttons: push buttons, check boxes, radio buttons, group boxes, and owner-drawn buttons. Each type has one or more styles.


  10.1.1.1  Push Buttons

A push button is a round-cornered rectangle containing application-defined text (label) that specifies what the button does when the user selects it. The push button includes the following styles: push button and default push button, defined by the constants BS_PUSHBUTTON and BS_DEFPUSHBUTTON, respectively. A standard push button is typically used to start an operation. It receives the keyboard focus when the user selects it. A default push button, on the other hand, is typically used to cancel an operation. It receives the keyboard focus when it is created (thus, becoming the default).

When the user selects a push button (of either style), it receives the keyboard focus from Windows, which sends the button's parent window a WM_COMMAND message containing the BN_CLICKED notification code. In response, the parent window typically sets the button's highlight state to highlighted, closes the dialog box, and starts (or cancels) the operation.

»This figure« shows both a standard and a default push button.

The labels on push buttons are always centered on the button.


  10.1.1.2  Check Boxes

A check box consists of a square box and application-defined text (label) that specifies a choice the user can make by selecting the button. Applications typically display check boxes in a group box to permit the user to choose from a set of related but independent options. For example, an application might present a group of check boxes from which the user can select error conditions that produce warning beeps.

A check box can be one of four styles: check box, automatic check box, three-state check box, and automatic three-state check box, which are defined by the constants BS_CHECKBOX, BS_AUTOCHECKBOX, BS_3STATE, and BS_AUTO3STATE, respectively. All four styles can assume two check states: checked (an X inside the box) or unchecked (no X). In addition, a three-state check box can assume a disabled state (the box is grayed). Repeatedly selecting a standard or automatic check box toggles it from checked to unchecked and back again. Repeatedly selecting a three-state check box toggles it from checked to unchecked to grayed and back again.

»This figure« shows all three states of a three-state check box.

When the user selects a check box (of any style), the check box receives the keyboard focus from Windows, which sends the check box's parent window a WM_COMMAND message containing the BN_CLICKED notification code. The parent window doesn't acknowledge this message if it comes from an automatic check box or automatic three-state check box, because Windows automatically sets the check state and the highlight state for those styles. But the parent window must acknowledge the message if it comes from a check box or three-state check box because the parent window, not Windows, is responsible for setting the check state and highlight state for those styles. Regardless of the check box style, Windows automatically repaints the check box once its state is changed.

By default, a label is placed on the right of a check box. An application can place labels on the left instead by using the left-text style (BS_LEFTTEXT). The left-text style is only a style, not a distinct button type.


  10.1.1.3  Radio Buttons

A radio button consists of a round button and application-defined text (a label) that specifies a choice the user can make by selecting the button. An application typically uses radio buttons in a group box to permit the user to choose from a set of related but mutually exclusive options. For example, the application might present a group of radio buttons from which the user can select a format preference for text selected in the client area. The user could select a left-aligned, right-aligned, or centered format by selecting the corresponding radio button. Typically, the user can select only one option at a time from a set of radio buttons.

The radio button includes the following styles: radio button and automatic radio button, defined by the constants BS_RADIOBUTTON and BS_AUTORADIOBUTTON, respectively. Both styles can assume two check states: checked (a black dot on the button) or unchecked (no dot on the button). Repeatedly selecting a check box (standard or automatic) toggles it from checked to unchecked and back again. Repeatedly selecting a three-state check box (standard or automatic) toggles it from checked to unchecked to grayed and back again.

»This figure« shows both states of a radio button.

When the user selects either state, the radio button receives the keyboard focus from Windows, which sends the button's parent window a WM_COMMAND message containing the BN_CLICKED notification code. The parent window doesn't acknowledge this message if it comes from an automatic radio button because Windows automatically sets the check state and the highlight state for that style. But the parent window should acknowledge the message if it comes from a radio button because the parent window, not Windows, is responsible for setting the check state and highlight state for that style. Regardless of the radio button style, Windows automatically repaints the button as its state changes.

When the user selects an automatic radio button, Windows automatically removes the highlighting from any previously selected automatic radio button within the same group. The same behavior is available for standard radio buttons by using the WS_GROUP style, as discussed in Chapter 18, »Dialog Boxes«.

By default, a label is placed on the right of a radio button. An application can place labels on the left instead by using the left-text style (BS_LEFTTEXT). The left-text style is only a style, not a distinct button type.


  10.1.1.4  Owner-Drawn Buttons

Unlike radio buttons, an owner-drawn button is painted by the application, not Windows, and has no predefined appearance or usage. Its purpose is to provide a button whose appearance and behavior are defined by the application alone. There is only one owner-drawn button style: BS_OWNERDRAW.

When the user selects an owner-drawn button, Windows sends the button's parent window a WM_COMMAND message containing the BN_CLICKED notification code, just as it does for a button that is not owner-drawn. The application must respond appropriately.


  10.1.1.5  Group Boxes

A group box is a rectangle that surrounds a set of controls, such as check boxes or radio buttons, with application-defined text (label) in its upper-left corner. The sole purpose of a group box is to organize controls related by a common purpose (usually indicated by the label). The group box has only one style, defined by the constant BS_GROUPBOX.

»This figure« shows a group box containing two radio buttons.

Because a group box cannot be selected, it has no check state, focus state, highlight state, or enabled state. An application cannot send messages to a group box.


  10.1.1.6  Button Styles

Many developers create dialog boxes by using stand-alone tools not requiring them to specify button styles. However, if an application creates a button by using the CreateWindow or CreateWindowEx function, the following table of constants can be used to define the button style.

Style	Meaning
BS_3STATE	Creates a button that is the same as a check box, except that the box can be grayed as well as checked. Use the grayed state to show that the state of the check box is not determined.
BS_AUTO3STATE	Creates a button that is the same as a three-state check box, except that the box changes its state when the user selects it. The state cycles through checked, grayed, and normal.
BS_AUTOCHECKBOX	Creates a button that is the same as a check box, except that an X appears in the check box when the user selects the box; the X disappears the next time the user selects the box.
BS_AUTORADIOBUTTON	Creates a button that is the same as a radio button, except that when the user selects it, the button automatically highlights itself and removes the selection from any other buttons in the same group.
BS_CHECKBOX	Creates a small empty square, with text displayed to its right, unless this style is combined with the BS_LEFTTEXT style.
BS_DEFPUSHBUTTON	Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style is useful for enabling the user to quickly select the most likely (default) option.
BS_GROUPBOX	Creates a rectangle in which other controls can be grouped. Any text associated with this style is displayed in the rectangle's upper left corner.
BS_LEFTTEXT	Places text on the left side of the radio button or check box when combined with a radio button or check box style.
BS_OWNERDRAW	Creates an owner-drawn button. The owner window receives a WM_MEASUREITEM message when the button is created and a WM_DRAWITEM message when a visual aspect of the button has changed. Do not combine the BS_OWNERDRAW style with any other button styles.
BS_PUSHBOX	Unsupported. Applications should use BS_PUSHBUTTON instead.
BS_PUSHBUTTON	Creates a push button that posts a WM_COMMAND message to the owner window when the user selects the button.
BS_RADIOBUTTON	Creates a small circle that has text displayed to its right, unless this style is combined with the BS_LEFTTEXT style. Use radio buttons for groups of related but mutually exclusive choices.
BS_USERBUTTON	Obsolete. Applications should use BS_OWNERDRAW instead.


  10.1.2  Button States

This section discusses how selecting a button changes its state and how the application should respond.


  10.1.2.1  Button Selection

The user can select a button in three ways: by clicking it with the mouse, by tabbing to it and then pressing the ENTER key, or (if the button is part of a group defined by the WS_GROUP style) by tabbing to the selected button in the group and using the arrow keys to move within that group. The two tabbing methods are part of the predefined keyboard interface provided by Windows. For a complete description of this interface, see Chapter 18, »Dialog Boxes«.

Selecting a button typically causes the following events:

•	Windows gives the button the keyboard focus.

•	The button sends its parent window a message to notify it of the selection.

•	The parent window (or Windows) sends the button a message to change its state.

•	The parent window (or Windows) repaints the button to reflect its new state.

The following paragraphs discuss these events and button states in greater detail.


  10.1.2.2  Elements of a Button State

A button's state can be characterized by its focus state, highlight state, check state, and enabled state. The focus state applies to a check box, radio button, push button, or owner-drawn button. A button receives the keyboard focus when the user selects it and loses the focus when the user selects another button. Only one button can have the keyboard focus at a time. For example, when one radio button in a group receives the focus, the previously selected radio button in the group loses it, to preserve the mutually exclusive nature of radio buttons.

The highlight state applies to a check box, radio button, push button, or owner-drawn button. A button is highlighted when it receives the keyboard focus and loses its highlighting when it loses the focus. Typically, a highlighted button surrounds its text with a dotted line and has a heavy dark border. Windows automatically changes the highlight state for an automatic button, but the application must change the highlight state for a non-automatic button.

The check state applies to a check box, radio button, or three-state check box, but does not apply to other buttons. The state can be checked, unchecked, or (for three-state check boxes) disabled. A check box is checked when it contains an X, and is unchecked when it does not. A radio button is checked when it contains a black dot, and is unchecked when it does not. A three-state check box is checked when it contains an X, unchecked when it does not, and is disabled when it is grayed. Windows changes the check state of an automatic button automatically, but the application must change the check state of a non-automatic button.

The enabled state applies to a standard or automatic three-state check box, but does not apply to other buttons. The state can be enabled or disabled.


  10.1.2.3  Changes to a Button State

When the user selects a button, it is generally necessary to change one or more of the button's state elements. Windows automatically changes the focus state for all button types and the highlight, check, and enabled states for all automatic buttons, but the application must make all other state changes, taking into account the button's type, style, and current state. The following list shows the state elements that must be changed for each button type:

•	A push button must change the highlight state but not the check state or the enabled state, because push buttons cannot be checked or disabled.

•	A check box must change the check state, the highlight state, and the enabled state for three-state check boxes.

•	A radio button must change the check state and the highlight state, but not the enabled state (because radio buttons cannot be disabled). It may also be necessary to change other radio buttons in the same group to ensure the mutually exclusive nature of radio buttons.

•	Because the state of an owner-drawn button is application dependent, what the application must change in the button can vary. No elements of a group box must be changed, because users cannot select group boxes.

An application can determine a button's state by sending it a BM_GETCHECK or BM_GETSTATE message; the application can set a button's state by sending it a BM_SETCHECK or BM_SETSTATE message.


  10.1.3  Notification Messages from Buttons

When the user selects a button, its state changes, and the button sends notification messages to its parent window. For example, a push button control sends the BN_CLICKED notification message whenever the user chooses the button. In all cases, the low word of the wParam parameter contains the control identifier, the high word of wParam contains the notification code, and the lParam parameter contains the control window handle.

Portability Issue   In Windows® NT (™) , the placement of the notification code in a notification message has moved from the lParam parameter to the wParam parameter. To accommodate this change in placement, when porting your Windows 3.x−based application to Windows NT, you must modify the code that processes notification messages.

Both the message and the parent window's response depend on the type, style, and current state of the button. Following are the button notification messages an application should monitor and process.

Message	Description
BN_CLICKED	The user clicked a button.
BN_DISABLE	A button is disabled.
BN_DOUBLECLICKED	The user double-clicked a button.
BN_HILITE	The user highlighted a button.
BN_PAINT	The button should be painted.
BN_UNHILITE	The highlight should be removed.
For automatic buttons, the operating system performs disabling, highlighting, unhighlighting, and painting. In this case, the application typically processes only the BN_CLICKED and BN_DOUBLECLICKED notification messages. For buttons that are not automatic, the application typically responds to the notification message by sending a message to change the state of the button. For information about sending messages to buttons, see Section 10.1.4, »Messages to Buttons«.

When the user selects an owner-drawn button, the button sends its parent window a WM_DRAWITEM message containing the identifier of the control to be drawn and information about its dimensions and state. For more information about this message, see Section 10.2.3, »Using Owner-Drawn Buttons«.


  10.1.4  Messages to Buttons

A parent window can send messages to a button in an overlapped or child window by using the SendMessage function, or it can send messages to a button in a dialog box by using the SendDlgItemMessage, CheckDlgButton, CheckRadioButton, and IsDlgButtonChecked functions.

An application can use the BM_GETCHECK message to retrieve the check state of two-state buttons (check boxes, automatic check boxes, radio buttons, and automatic radio buttons). An application can also use the BM_GETSTATE message to retrieve the button's current states (the check state, highlight state, and focus state). It retrieves the check state of a three-state check box or the focus or highlight state of a button. To get information about a specific state, use a bitmask on the returned state value.

The BM_SETCHECK message sets the check state of a check box or radio button; the message returns zero. The BM_SETSTATE message sets the highlight state of a button; this message also returns zero. The BM_SETSTYLE message changes the style of a button. It is designed for changing button styles within a type (for example, changing a check box to an automatic check box). It is not designed for changing between types (for example, changing a check box to a push button). An application should not change a button from one type to another.

An application can also use the DM_GETDEFID message to retrieve the identifier of the default push button control. An application can use the DM_SETDEFID message to set the default push button for a dialog box.

Calling the CheckDlgButton or CheckRadioButton function is equivalent to sending a BM_SETCHECK message. Calling the IsDlgButtonChecked function is equivalent to sending a BM_GETCHECK message.


  10.1.5  Button Color Messages

Windows provides default color values for buttons. The system sends a WM_CTLCOLORBTN message to a button's parent window before the button is drawn. This message contains a handle of the button's device context and a handle of the child window. The parent window can use these handles to change the button's text and background colors. The following table shows the default button-color values.

Value	Element colored
COLOR_BTNFACE	Button faces.
COLOR_BTNHIGHLIGHT	Highlight area (the top and left edges) of a button.
COLOR_BTNSHADOW	Shadow area (the bottom and right edges) of a button.
COLOR_BTNTEXT	Regular (non-gray) text in buttons.
COLOR_GRAYTEXT	Disabled (gray) text in buttons. This color is set to 0 if the current display driver does not support a solid gray color.
COLOR_WINDOW	Window backgrounds.
COLOR_WINDOWFRAME	Window frames.
COLOR_WINDOWTEXT	Text in windows.
An application can retrieve the default values for these colors by calling the GetSysColor function, or set the values by calling the SetSysColor function. For more information about system colors, see Chapter 67, "System Information," in Microsoft Win32 Programmer's Reference, Volume 2. For more information about how colors are used with controls, see Chapter 9, »Controls«.

Portability Issue   In Windows NT, the WM_CTLCOLOR message has been replaced by the set of control-color messages. When porting your Windows 3.x−based application to Windows NT, you must modify any code that processes the WM_CTLCOLOR message.


  10.1.6  Default Message Processing

The window procedure for the predefined button control window class carries out default processing for all messages that the button control procedure does not process. When the button control procedure returns FALSE for any message, the predefined window procedure checks the messages and carries out the default actions listed in the following table.

Message	Default action
BM_GETCHECK	Returns the check state of the button.
BM_GETSTATE	Returns the current state of the button.
BM_SETCHECK	Sets the check mark for all styles of radio buttons and check boxes. If the wParam parameter is greater than zero for radio buttons, the button is given the WS_TABSTOP style.
BM_SETSTATE	Highlights or unhighlights the button. For owner-drawn buttons, a WM_DRAWITEM message is sent to the parent window if the state of the button has changed.
BM_SETSTYLE	Sets the button style. If the low word of the lParam parameter is TRUE, the button is redrawn.
WM_CHAR	Checks a check box or automatic check box when the user presses the + or = keys. Removes the check mark from a check box or automatic check box when the user presses the − key.
WM_ENABLE	Paints the button.
WM_ERASEBKGND	Erases the background for owner-drawn buttons. The backgrounds of other buttons are erased as part of the WM_PAINT and WM_ENABLE processing.
WM_GETDLGCODE	Returns values indicating the type of input processed by the default button procedure, as shown in the following.
Button style	Returns
BS_AUTOCHECKBOX
	DLGC_WANTCHARS | DLGC_BUTTON
BS_AUTORADIOBUTTON
	DLGC_RADIOBUTTON
BS_CHECKBOX
	DLGC_WANTCHARS | DLGC_BUTTON
BS_DEFPUSHBUTTON
	DLGC_DEFPUSHBUTTON
BS_GROUPBOX
	DLGC_STATIC
BS_PUSHBUTTON
	DLGC_UNDEFPUSHBUTTON
BS_RADIOBUTTON
	DLGC_RADIOBUTTON
WM_GETFONT	Returns a handle of the current font.
WM_KEYDOWN	Highlights the button if the user presses the SPACEBAR.
WM_KEYUP	Releases the mouse capture for all cases except the TAB key.
WM_KILLFOCUS	Removes the focus rectangle from a button. For push buttons and default push buttons, the focus rectangle is invalidated. If the button has the mouse capture, the capture is released, the button is not clicked, and any highlighting is removed.
WM_LBUTTONDBLCLK	Sends a BN_DOUBLECLICKED notification message to the parent window for radio buttons and owner-drawn buttons. For other buttons, a double-click is processed as a WM_LBUTTONDOWN message.
WM_LBUTTONDOWN	Highlights the button if the position of the mouse cursor is within the button's client rectangle.
WM_LBUTTONUP	Releases the mouse capture if the button had the mouse capture.
WM_MOUSEMOVE	Performs the same action as WM_LBUTTONDOWN if the button has the mouse capture. Otherwise, no action is performed.
WM_NCCREATE	Turns any BS_USERBUTTON button into a BS_PUSHBUTTON button.
WM_NCHITTEST	Returns HTTRANSPARENT if the button control is a group box.
WM_PAINT	Draws the button according to its style and current state.
WM_SETFOCUS	Draws a focus rectangle on the button getting the focus. For radio buttons and automatic radio buttons, the parent window is sent a BN_CLICKED notification message.
WM_SETFONT	Sets a new font and optionally updates the window.
WM_SETTEXT	Sets the text of the button. In the case of a group box, paints over the preexisting text before repainting the group box with the new text.
WM_SYSKEYUP	Releases the mouse capture for all cases except the TAB key.
The predefined window procedure passes all other messages to the DefWindowProc function for default processing.


  10.2  Using Buttons

This section explains how to perform the following tasks:

•	Create a button outside a dialog box.

•	Use system-drawn buttons.

•	Use owner-drawn buttons.


  10.2.1  Creating a Button Outside a Dialog Box

The following code sample shows how to use the CreateWindow function to create a default push button.

hwndButton = CreateWindow(

    "BUTTON",   /* predefined class                              */

    "OK",       /* button text                                   */

    WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, /* styles          */

     /*

      * Size and position values are given explicitly, because

      * the CW_USEDEFAULT constant gives zero values for buttons.

      */

    10,         /* starting x position                           */

    10,         /* starting y position                           */

    100,        /* button width                                  */

    100,        /* button height                                 */

    hwnd,       /* parent window                                 */

    NULL,       /* No menu                                       */

    (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),

    NULL);      /* pointer not needed                            */


  10.2.2  Using Buttons That Are Not Owner-Drawn

The code example in this section is the window procedure for a dialog box, as shown in »this illustration«.

The check boxes and radio buttons in the Buttons dialog box are automatic. The check boxes are three-state. The Clear colors push button is a default push button. The check boxes, radio buttons, and push buttons are defined as follows in the application's header file.

#define IDB_BOX1        101               /* first check box     */

#define IDB_BOX2        102               /* second check box    */

#define IDB_BOX3        103               /* third check box     */

#define IDB_REDBACK     104               /* top radio button    */

#define IDB_BLUEBACK    105               /* bottom radio button */

#define IDB_CLEARBOXES  107               /* top push button     */

#define IDB_CLEARBACK   108               /* bottom push button  */

HBRUSH hbrRed, hbrBlue, hbrWhite;

BOOL fRedBack, fBlueBack, fClearColor; /* background-state flags */

Note that it is not necessary to define IDOK, the identifier for the OK push button.

In the following window procedure, the WM_CTLCOLORDLG message notifies the application that the dialog box is about to be drawn. If the user presses the Clear colors button (signified by the fClearColor flag), the procedure uses the SendDlgItemMessage function to uncheck the check boxes and radio buttons. The BN_CLICKED notification message contains the identifiers of the buttons.

LRESULT APIENTRY ButtonProc(hDlg, message, wParam, lParam)

HWND hDlg;                /* window handle of dialog box  */

UINT message;             /* type of message              */

UINT wParam;              /* message-specific information */

LONG lParam;

{

    LRESULT lState;

    switch (message) {

        case WM_INITDIALOG:

            hbrRed = CreateSolidBrush(RGB(255, 0, 0));

            hbrBlue = CreateSolidBrush(RGB(0, 0, 255));

            hbrWhite = GetStockObject(WHITE_BRUSH);

            return TRUE;

        case WM_CTLCOLORDLG:

            if (fRedBack) {

                fRedBack = FALSE;

                return (LRESULT) hbrRed;

            }

            else if (fBlueBack) {

                fBlueBack = FALSE;

                return (LRESULT) hbrBlue;

            }

            else if (fClearColor) {

                fClearColor = FALSE;

                /*

                 * Uncheck all check boxes and radio buttons.

                 */

                SendDlgItemMessage(hDlg, /* window handle           */

                    IDB_BOX1,            /* button identifier       */

                    BM_SETCHECK,         /* message                 */

                    0,                   /* check state (unchecked) */

                    0);                  /* must be zero            */

                SendDlgItemMessage(hDlg, IDB_BOX2,

                    BM_SETCHECK, 0, 0);

                SendDlgItemMessage(hDlg, IDB_BOX3,

                    BM_SETCHECK, 0, 0);

                SendDlgItemMessage(hDlg, IDB_REDBACK,

                    BM_SETCHECK, 0, 0);

                SendDlgItemMessage(hDlg, IDB_BLUEBACK,

                    BM_SETCHECK, 0, 0);

            }

            return (LRESULT) hbrWhite;

        case WM_COMMAND:

                if (wParam == IDOK) {

                    EndDialog(hDlg, TRUE);

                    return TRUE;

                }

                if (HIWORD(wParam) == BN_CLICKED) {

                    switch (LOWORD(wParam)) {

                        case IDB_BOX1:

                            /* Retrieve the state of the check box. */

                            lState = SendDlgItemMessage(hDlg,

                                IDB_BOX1, BM_GETSTATE, 0, 0);

                            /*

                             * The box-painting function is

                             * application defined.

                             */

                            BoxPainter(hDlg, /* window handle    */

                                1,           /* box to paint     */

                                lState);     /* check box state  */

                            break;

                        case IDB_BOX2:

                            lState = SendDlgItemMessage(hDlg,

                                IDB_BOX2, BM_GETSTATE, 0, 0);

                            BoxPainter(hDlg, 2, lState);

                            break;

                        case IDB_BOX3:

                            lState = SendDlgItemMessage(hDlg,

                                IDB_BOX3, BM_GETSTATE, 0, 0);

                            BoxPainter(hDlg, 3, lState);

                            break;

                        case IDB_REDBACK:

                            fRedBack = TRUE;

                            InvalidateRect(hDlg, NULL, TRUE);

                            break;

                        case IDB_BLUEBACK:

                            fBlueBack = TRUE;

                            InvalidateRect(hDlg, NULL, TRUE);

                            break;

                        case IDB_CLEARBACK:

                            fClearColor = TRUE;

                            InvalidateRect(hDlg, NULL, TRUE);

                            break;

                        case IDB_CLEARBOXES:

                            BoxPainter(hDlg, 4, (LRESULT) 0);

                            break;

                    }

                }

        case WM_DESTROY:

            DeleteObject(hbrRed);

            DeleteObject(hbrBlue);

             /*

              * Do not delete hbrWhite, because it is a stock

              * object.

              */

            break;

    }

    return FALSE;       /* did not process a message */

        UNREFERENCED_PARAMETER(lParam);

}


  10.2.3  Using Owner-Drawn Buttons

The parent window of an owner-drawn button typically responds to at least three messages for the button: WM_INITDIALOG, WM_COMMAND, and WM_DRAWITEM. It is not necessary to process the WM_MEASUREITEM message for owner-drawn buttons.

When you must paint an owner-drawn button, Windows sends the parent window a WM_DRAWITEM message whose lParam parameter points to a DRAWITEMSTRUCT structure. Use this structure with all owner-drawn controls to provide the application with the information it requires to paint the control. The itemAction and itemState structure members define how to paint an owner-drawn button.

The following code sample shows how to process WM_INITDIALOG, WM_DRAWITEM, and WM_COMMAND messages for owner-drawn buttons. This code demonstrates how to draw one of two bitmaps for a control, depending on whether the control is selected. You would typically use the wParam parameter of the WM_DRAWITEM message to identify the control; in this example, only one control is assumed.

LRESULT APIENTRY OwnDrawProc(hDlg, message, wParam, lParam)

HWND hDlg;      /* window handle of dialog box           */

UINT message;   /* type of message                       */

UINT wParam;    /* message-specific information          */

LONG lParam;

{

    HDC hdcMem;

    LPDRAWITEMSTRUCT lpdis;

    switch (message) {

        case WM_INITDIALOG:

            /* hinst, hbm1 and hbm2 are defined globally. */

            hbm1 = LoadBitmap((HANDLE) hinst, "OwnBit1");

            hbm2 = LoadBitmap((HANDLE) hinst, "OwnBit2");

            return TRUE;

        case WM_DRAWITEM:

            lpdis = (LPDRAWITEMSTRUCT) lParam;

            hdcMem = CreateCompatibleDC(lpdis->hDC);

            if (lpdis->itemState & ODS_SELECTED) /* if selected     */

                SelectObject(hdcMem, hbm2);

            else

                SelectObject(hdcMem, hbm1);

            StretchBlt(

                lpdis->hDC,         /* destination device context   */

                lpdis->rcItem.left, /* x upper-left destination     */

                lpdis->rcItem.top,  /* y upper-left destination     */

                /* The next two lines specify the width and height. */

                lpdis->rcItem.right - lpdis->rcItem.left,

                lpdis->rcItem.bottom - lpdis->rcItem.top,

                hdcMem,    /* handle of source device context       */

                0,         /* x-coordinate upper-left source        */

                0,         /* y-coordinate upper-left source        */

                32,        /* source bitmap width                   */

                32,        /* source bitmap height                  */

                SRCCOPY);  /* raster operation                      */

            DeleteDC(hdcMem);

            return TRUE;

        case WM_COMMAND:

            if (wParam == IDOK

                || wParam == IDCANCEL) {

                EndDialog(hDlg, TRUE);

                return TRUE;

            }

            if (HIWORD(wParam) == BN_CLICKED) {

                switch (LOWORD(wParam)) {

                    case IDB_OWNERDRAW:

                        .

                        . /* application-defined processing */

                        .

                    break;

                }

            }

            break;

        case WM_DESTROY:

            DeleteObject(hbm1); /* delete bitmaps                */

            DeleteObject(hbm2);

            break;

    }

    return FALSE;

        UNREFERENCED_PARAMETER(lParam);

}


  10.3  Functions and Messages

The following functions and messages can be used with buttons.


  Functions

CheckDlgButton
CheckRadioButton
IsDlgButtonChecked


  Messages

BM_GETCHECK
BM_GETSTATE
BM_SETCHECK
BM_SETSTATE
BM_SETSTYLE
BN_CLICKED
BN_DISABLE
BN_DOUBLECLICKED
BN_HILITE
BN_PAINT
BN_UNHILITE
DM_GETDEFID
DM_SETDEFID
WM_CTLCOLORBTN


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


11.1  About List Boxes
  Chapter 11    List Boxes

11.1  About List Boxes

Microsoft® Windows (™)  provides dialog boxes and controls to support communication between an application and the user. A list box is a control window that contains a list of items from which the user can choose. List box items can be represented by text strings, bitmaps, or both. If the list box is not large enough to display all the list box items at once, the list box can provide a scroll bar.

The user selects a list box item or cancels a selection by using the mouse or keyboard. Selecting a list box item changes its visual appearance, usually by changing the text and background colors to the colors specified by the operating system metrics for selected items. When the user selects or cancels an item, Windows sends a notification message to the parent window of the list box.

Although an application can use a list box in an overlapped, child, or pop-up window, list boxes are mainly designed for use in dialog boxes, where most of their functionality is predefined by Windows. When using a list box in windows other than dialog boxes, it is difficult to maintain a consistent user interface. Therefore, you should use window subclassing to implement a list box outside a dialog box. This chapter primarily discusses the use of list boxes within dialog boxes, but this discussion also applies to the use of list boxes in any parent window. For more information about window subclassing, see Chapter 4, »Window Procedures«.

A dialog box procedure is responsible for initializing and monitoring its child windows, including any list boxes. The dialog box procedure communicates with the list box by sending messages to it and by processing the notification messages sent by the list box. For more information about dialog boxes, see Chapter 18, »Dialog Boxes«.

For general information about controls, see Chapter 9, »Controls«.


  11.1.1  List Box Styles

Windows provides two general styles of list box: single-selection and multiple-selection. In a single-selection list box (the default), the user can select only one item at a time. In a multiple-selection list box, the user can select more than one item at a time. Either the LBS_MULTIPLESEL or the LBS_EXTENDEDSEL style must be specified for a multiple-selection list box.

Windows provides many other list box and window styles that control the appearance and operation of a list box. These styles indicate whether list box items are sorted, arranged in multiple columns, drawn by the application, and so on. The dimensions and styles of a list box are typically defined in a dialog box template included in an application's resources. For information about how to create a dialog box template and include it in an application, refer to the documentation provided with your application-development tools.

To create a list box by using the CreateWindow or CreateWindowEx function, use the LISTBOX class, appropriate window-style constants, and the following list box−style constants to define the list box.

Style	Meaning
LBS_DISABLENOSCROLL
	Shows a disabled vertical scroll bar for the list box when the box does not contain enough items to scroll. If an application does not specify this style, the scroll bar is hidden when the list box does not contain enough items.
LBS_EXTENDEDSEL
	Allows multiple items to be selected by using the SHIFT key and the mouse or special key combinations.
LBS_HASSTRINGS
	Specifies that a list box contains items consisting of strings. The list box maintains the memory and addresses for the strings so the application can use the LB_GETTEXT message to retrieve the text for a particular item. By default, all list boxes except owner-drawn list boxes have this style. An application can create an owner-drawn list box either with or without this style.
LBS_MULTICOLUMN
	Specifies a multicolumn list box with horizontal scrolling. The LB_SETCOLUMNWIDTH message sets the width of the columns.
LBS_MULTIPLESEL
	Turns string selection on or off each time the user clicks or double-clicks the string. The user can select any number of strings.
LBS_NODATA
	Specifies a no-data list box. To use memory efficiently, an application should specify this style when the count of items in the list box exceed one thousand. A no-data list box must also have the LBS_OWNERDRAWFIXED style, but must not have the LBS_SORT or LBS_HASSTRINGS style.
LBS_NOINTEGRALHEIGHT
	Specifies that the size of the list box is exactly the size specified by the application when it created the list box. By default, Windows sizes a list box so that the list box does not display partial items.
LBS_NOREDRAW
	Specifies that the appearance of the list box is not updated when changes are made. An application can change this style at any time by sending a WM_SETREDRAW message.
LBS_NOTIFY
	Sends an input message to the parent window whenever the user clicks or double-clicks a string.
LBS_OWNERDRAWFIXED
	Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are the same height. The owner window receives a WM_MEASUREITEM message when the list box is created and a WM_DRAWITEM message whenever a visual aspect of the list box changes.
LBS_OWNERDRAWVARIABLE
	Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are variable in height. The owner window receives a WM_MEASUREITEM message for each item in the list box when the list box is created and a WM_DRAWITEM message whenever the visual aspect of the list box changes.
LBS_SORT
	Sorts strings in the list box alphabetically.
LBS_STANDARD
	Specifies a standard list box. Specifying this style is equivalent to specifying LBS_SORT, LBS_NOTIFY, and LBS_BORDER.
LBS_USETABSTOPS
	Allows a list box to recognize and expand tab characters when drawing its strings. The default tab positions are 32 dialog box units. Windows computes the dialog box base units based on the height and width of the current operating system font. One horizontal dialog box unit is equal to one-fourth of the current dialog box base width unit. The GetDialogBaseUnits function returns the current dialog box base units in pixels.
LBS_WANTKEYBOARDINPUT
	Specifies that the owner of the list box receives WM_VKEYTOITEM messages whenever the user presses a key and the list box has the input focus. This allows an application to perform special processing on the keyboard input.


  11.1.2  List Box Functions

Windows supports two functions specific to list boxes. The DlgDirList function fills a list box with the files and directories in a specified path. The DlgDirSelectEx function retrieves the current selection in a list box initialized by DlgDirList. These functions make it possible for the user to select a file from a list box without typing the location and name of the file.


  11.1.3  Notification Messages from List Boxes

When an event occurs in a list box, the list box sends a notification message to the dialog box procedure of the owner window. List box notification messages are sent when a user selects, double-clicks, or cancels a list box item; when the list box receives or loses the keyboard focus; and when the operating system cannot allocate enough memory for a list box request. A notification message is sent as a WM_COMMAND message in which the low-order word of the wParam parameter contains the list box identifier, the high-order word of wParam contains the notification code, and the lParam parameter contains the control window handle.

Portability Issue   In Microsoft® Windows NT (™) , the placement of the notification code has moved from the lParam parameter to the wParam parameter. Windows 3.x applications that process notification messages must be modified in this respect when they are ported to Windows NT.

A dialog box procedure is not required to process these messages; the default window procedure processes them.

An application should monitor and process the following list box notification messages.

Notification code	Meaning
LBN_DBLCLK	The user double-clicks an item in the list box.
LBN_ERRSPACE	The list box cannot allocate enough memory to fulfill a request.
LBN_KILLFOCUS	The list box loses the keyboard focus.
LBN_SELCANCEL	The user cancels the selection of an item in the list box.
LBN_SELCHANGE	The selection in a list box is about to change.
LBN_SETFOCUS	The list box receives the keyboard focus.


  11.1.4  Messages to List Boxes

A dialog box procedure can send messages to a list box to add, delete, examine, and change list box items. For example, a dialog box procedure could send an LB_ADDSTRING message to a list box to add an item, and the LB_GETSEL message to determine whether the item is selected. Other messages set and retrieve information about the size, appearance, and behavior of the list box. For example, the LB_SETHORIZONTALEXTENT message sets the scrollable width of a list box. A dialog box procedure can send any message to a list box by using the SendMessage or SendDlgItemMessage function.

A list box item is often referenced by its index, an integer that represents the item's position in the list box. The index of the first item in a list box is 0, the index of the second item is 1, and so on.

The following table describes how the predefined list box procedure responds to list box messages.

Message	Response
LB_ADDFILE	Inserts a file into a directory list box filled by the DlgDirList function and retrieves the list box index of the inserted item.
LB_ADDSTRING	Adds a string to a list box and returns its index.
LB_DELETESTRING	Removes a string from a list box and returns the number of strings remaining in the list.
LB_DIR	Adds a list of filenames to a list box and returns the index of the last filename added.
LB_FINDSTRING	Returns the index of the first string in the list box that matches a given prefix.
LB_FINDSTRINGEXACT	Returns the index of the string that is equivalent to or prefixed by a given prefix.
LB_GETANCHORINDEX	Returns the index of the item that the mouse last selected.
LB_GETCARETINDEX	Returns the index of the item that has the focus rectangle.
LB_GETCOUNT	Returns the number of items in the list box.
LB_GETCURSEL	Returns the index of the currently selected item in a single-selection list box.
LB_GETHORIZONTALEXTENT	Returns the scrollable width, in pixels, of a list box.
LB_GETITEMDATA	Returns the 32-bit value associated with the given item.
LB_GETITEMHEIGHT	Returns the height, in pixels, of an item in a list box.
LB_GETITEMRECT	Retrieves the client coordinates of the given list box item.
LB_GETLOCALE	Retrieves the locale of the list box. The high-order word contains the country code and the low-order word contains the language identifier.
LB_GETSEL	Returns the selection state of a list box item.
LB_GETSELCOUNT	Returns the number of selected items in a multiple-selection list box.
LB_GETSELITEMS	Creates an array of the indexes of all selected items in a multiple-selection list box and returns the total number of selected items.
LB_GETTEXT	Retrieves the string associated with a given item and the length of the string.
LB_GETTEXTLEN	Returns the length, in characters, of the string associated with a given item.
LB_GETTOPINDEX	Returns the index of the first visible item in a list box.
LB_INSERTSTRING	Inserts a string at a given index in a list box.
LB_RESETCONTENT	Removes all items from a list box.
LB_SELECTSTRING	Selects the first string it finds that matches a given prefix.
LB_SELITEMRANGE	Selects a given range of items in a list box.
LB_SELITEMRANGEEX	Selects a given range of items if the index of the first item in the range is less than the index of the last item in the range. Cancels the selection in the range if the index of the first item is greater than the last.
LB_SETANCHORINDEX	Sets the item that the mouse last selected to a given item.
LB_SETCARETINDEX	Sets the focus rectangle to a given list box item.
LB_SETCOLUMNWIDTH	Sets the width, in pixels, of all columns in a list box.
LB_SETCOUNT	Sets the number of items in a list box.
LB_SETCURSEL	Selects a given list box item.
LB_SETHORIZONTALEXTENT	Sets the scrollable width, in pixels, of a list box.
LB_SETITEMDATA	Associates a 32-bit value with a list box item.
LB_SETITEMHEIGHT	Sets the height, in pixels, of an item or items in a list box.
LB_SETLOCALE	Sets the locale of a list box and returns the previous locale identifier.
LB_SETSEL	Selects an item in a multiple-selection list box.
LB_SETTABSTOPS	Sets the tab stops to those specified in a given array.
LB_SETTOPINDEX	Scrolls the list box so the specified item is at the top of the visible range.


  11.1.5  Default Window-Message Processing

The window procedure for the predefined list box window class carries out default processing for all messages that the list box does not process. When the list box procedure returns FALSE for a message, the predefined window procedure checks the message and carries out default actions, as shown in the following table.

Message	Default
WM_CHAR	Moves the selection to the first item that begins with the character the user typed. If the list box has the LBS_OWNERDRAW style, nothing happens.
WM_COPYGLOBALDATA	Passes the message to the dialog box procedure or parent window process.
WM_CREATE	Creates an empty list box.
WM_DESTROY	Destroys the list box and frees any resources it uses.
WM_DRAGLOOP	Passes the message to the dialog box procedure or parent window process.
WM_DRAGMOVE	Passes the message to the dialog box procedure or parent window process.
WM_DRAGSELECT	Passes the message to the dialog box procedure or parent window process.
WM_DROPFILES	Passes the message to the dialog box procedure or parent window process.
WM_DROPOBJECT	Sets control data and sends the message to the dialog box procedure or parent window process.
WM_ENABLE	If the control is visible, invalidates the rectangle so the strings can be painted gray.
WM_ERASEBACKGROUND	Erases the background of a list box. If the list box has the LBS_OWNERDRAW style, the background is not erased.
WM_GETDLGCODE	Returns DLGC_WANTARROWS | DLGC_WANTCHARS, indicating the default list box procedure processes the arrow keys and WM_CHAR messages.
WM_GETFONT	Returns a handle of the current font for the list box.
WM_HSCROLL	Scrolls the list box horizontally.
WM_KEYDOWN	Processes virtual keys for scrolling. The virtual key is the index of the item to move the caret to. The selection is not changed.
WM_KILLFOCUS	Turns the caret off and destroys it. Sends an LBN_KILLFOCUS message to the owner of the list box.
WM_LBUTTONDBLCLK	Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_LBUTTONDOWN	Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_LBUTTONUP	Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_MOUSEMOVE	Tracks the mouse in the list box client area. This enables the user to cancel a selection if the mouse button is released outside the list box client area.
WM_PAINT	Performs a subclassed paint operation by using the list box handle of the device context.
WM_QUERYDROPOBJECT	Sets control data and sends the message to the dialog box procedure or parent window process.
WM_SETFOCUS	Turns the caret on and sends an LBN_SETFOCUS message to the owner of the list box.
WM_SETFONT	Sets a new font for the list box.
WM_SETREDRAW	Sets or clears the redraw flag based on the value of wParam.
WM_SIZE	Resizes the list box to an integral number of items.
WM_SYSTIMER	Notifies the list box window procedure that the timer set for tracking the mouse in the list box has elapsed.
WM_VSCROLL	Scrolls the list box vertically.
The predefined list box procedure passes all other messages to the DefWindowProc function for default processing.


  11.2  Using List Boxes

This section shows how to perform the following tasks:

•	Create a simple list box.

•	Create a directory listing in a single-selection list box.

•	Create a directory listing in a multiple-selection list box.

•	Create an owner-drawn list box.


  11.2.1  Creating a Simple List Box

The following code sample demonstates how a dialog box procedure creates a simple list box and fills it with the names of people on a softball team. When a name in the list is selected, additional information about the player is displayed in the dialog box. »This illustration« shows the dialog box.

The list box has the LBS_STANDARD style, a combination of LBS_SORT, LBS_NOTIFY, WS_VSCROLL, and WS_BORDER. The code initializes the dialog box while processing the WM_INITDIALOG message. For each name that appears in the list box, the code sends an LB_ADDSTRING message to the list box. By processing the LBN_SELCHANGE notification, the code also keeps track of when the selection changes.

#define BUFFER MAX_PATH

#define NAMELENGTH 15

#define POSITIONLENGTH 20

#define TEAMSIZE 15

typedef struct {

    TCHAR tchName[NAMELENGTH];

    TCHAR tchPosition[POSITIONLENGTH];

    int nGamesPlayed;

    int nInningsPlayed;

    double xBattingAverage;

    TCHAR tchFoodName[NAMELENGTH];

} Player;

Player Roster[] = {

      {"Pete", "shortstop", 26, 90, .608, "Rutabaga"},

      {"Suzanna", "catcher", 16, 53, .286, "Toast"},

      {"Jack", "pitcher", 27, 110, .542, "Animal Crackers"},

      {"Karen", "second base", 26, 140, .238, "Pez"},

      {"Dave", "first base", 28, 138, .508, "Suds"},

      {"Wendy", "third base", 25, 154, .493, "Ham"},

      {"Matt", "shortstop", 24, 112, .579, "Oats"},

      {"Jenny", "right field", 22, 101, .509, "Mashed Potatoes"},

      {"Seth", "left-center field", 20, 76, .407, "Otter Pop"},

      {"Kathie", "left field", 26, 127, .353, "Baba Ganouj"},

      {"Colin", "pitcher", 26, 96, .456, "Lefse"},

      {"Penny", "right field", 24, 112, .393, "Zotz"},

      {"Art", "left-center field", 17, 56, .375, "Cannelloni"},

      {"Cindy", "second base", 13, 58, .207, "Tequila"},

      {"David", "center field", 18, 101, .612, "Bok Choy"}

    };

   /*

    * FUNCTION: DlgTeamProc(HWND, unsigned, WORD, LONG)

    *

    * PURPOSE: Dialog box for "BFG Softball Statistics"

    */

BOOL APIENTRY DlgTeamProc(

    HWND hDlg,            /* window handle of dialog box   */

    UINT message,         /* type of message               */

    UINT wParam,          /* message-specific information  */

    LONG lParam)          /* message-specific information  */

{

  TCHAR tchName[NAMELENGTH];

  TCHAR tchBuffer[BUFFER];

  int nItem;

  int i;

  switch (message) {

    case WM_INITDIALOG:

      /* Initialize the list box (fill it with player names). */

      for (i = 0; i < TEAMSIZE; i++) {

          SendMessage(GetDlgItem(hDlg, IDL_SOFTBALL),

              LB_ADDSTRING, 0, (LPARAM) Roster[i].tchName);

      }

      SetFocus(GetDlgItem(hDlg, IDL_SOFTBALL));

      return FALSE;

    case WM_COMMAND:

      switch (LOWORD(wParam)) {

        case IDL_SOFTBALL:

          switch (HIWORD(wParam)) {

            case LBN_SELCHANGE:

              /* Display the selected player's statistics. */

              nItem = SendMessage(GetDlgItem(hDlg, IDL_SOFTBALL),

                  LB_GETCURSEL, 0, 0);

              SendMessage(GetDlgItem(hDlg, IDL_SOFTBALL),

                  LB_GETTEXT, nItem, (LPARAM) tchName);

              for (i = 0; strcmp(tchName, Roster[i].tchName); i++);

              SetDlgItemText(hDlg, IDS_POS, Roster[i].tchPosition);

              SetDlgItemText(hDlg, IDS_GAME,

                  _itoa(Roster[i].nGamesPlayed, tchBuffer, 10));

              SetDlgItemText(hDlg, IDS_INN,

                  _itoa(Roster[i].nInningsPlayed, tchBuffer, 10));

              SetDlgItemText(hDlg, IDS_BA,

                  _gcvt(Roster[i].xBattingAverage, 3, tchBuffer));

              SetDlgItemText(hDlg, IDS_FOOD,

                  Roster[i].tchFoodName);

              return TRUE;

           }

           break;

        case IDOK:

        case IDCANCEL:

          /* Destroy the dialog box. */

          EndDialog(hDlg, TRUE);

          return TRUE;

        default:

          return FALSE;

      }

    default:

        return FALSE;

  }

}


  11.2.2  Creating a Directory Listing in a Single-Selection List Box

The following code sample demonstrates how to display the contents of the current directory in a list box and enable the user to delete one file at a time. »This illustration« shows the dialog box.

In addition to the standard list box styles, this list box has the LBS_MULTICOLUMN and LBS_HSCROLL styles. The code initializes the list box by using the DlgDirList function to fill the list box with the names of all the files in the current directory. When the user selects the Delete button, the DlgDirSelectEx function retrieves the name of the selected file. The code deletes the file by using the DeleteFile function and updates the directory list box by sending the LB_DELETESTRING message.

#define BUFFER MAX_PATH

    /*

     * FUNCTION: DlgDelFileProc(HWND, unsigned, WORD, LONG)

     *

     * PURPOSE: "Delete File" dialog box

     */

BOOL APIENTRY DlgDelFileProc(

    HWND hDlg,            /* window handle of dialog box     */

    UINT message,         /* type of message                 */

    UINT wParam,          /* message-specific information    */

    LONG lParam)

{

  DWORD cchCurDir;

  LPTSTR lpszCurDir;

  LPTSTR lpszFileToDelete;

  int nItem;

  int nTotal;

  TCHAR tchBuffer[BUFFER];

  BOOL fResult;

  switch (message) {

    case WM_INITDIALOG:

      /*

       * Initialize the list box by filling it with files from

       * the current directory.

       */

      lpszCurDir = tchBuffer;

      GetCurrentDirectory(cchCurDir, lpszCurDir);

      DlgDirList(hDlg, lpszCurDir, IDL_FILES, IDS_PATHTOFILL, 0);

      SetFocus(GetDlgItem(hDlg, IDL_FILES));

      return FALSE;

    case WM_COMMAND:

      switch (LOWORD(wParam)) {

        case IDOK:

          /*

           * When the user presses the DEL (IDOK) button,

           * delete the selected file.

           */

          lpszFileToDelete = tchBuffer;

          DlgDirSelectEx(hDlg, lpszFileToDelete, MAX_PATH,

              IDL_FILES);

          fResult = DeleteFile(lpszFileToDelete);

          if (!fResult) {

              MessageBox(hDlg, "Could not delete file.",

                  NULL, MB_OK);

          } else {

              nItem = SendMessage(GetDlgItem(hDlg, IDL_FILES),

                  LB_GETCURSEL, 0, 0);

              nTotal = SendMessage(GetDlgItem(hDlg, IDL_FILES),

                  LB_DELETESTRING, nItem, 0);

              /* Update the list box. */

              if (nTotal > nItem) {

                  SendMessage(GetDlgItem(hDlg, IDL_FILES),

                      LB_SETCURSEL, nItem, 0);

              } else {

                  SendMessage(GetDlgItem(hDlg, IDL_FILES),

                      LB_SETCURSEL, nTotal, 0);

              }

          }

          return TRUE;

        case IDCANCEL:

          /* Destroy the dialog box. */

          EndDialog(hDlg, TRUE);

          return TRUE;

        default:

          return FALSE;

      }

    default:

        return FALSE;

  }

}


  11.2.3  Creating a Multiple-Selection List Box

The following code sample displays and initializes the same dialog box used in the preceding example. However, this code uses the LBS_MULTIPLESEL style to enable the user to select more than one file at a time. When the user selects the Delete button, the example sends the LB_GETSELCOUNT message (to retrieve the number of files selected) and the LB_GETSELITEMS message (to retrieve an array of selected list box items). After deleting a file, the code removes the corresponding item from the list box by sending the LB_DELETESTRING message.

#define BUFFER MAX_PATH

#define BIGBUFF 8192

    /*

     * FUNCTION: DlgDelFilesProc(HWND, unsigned, WORD, LONG)

     *

     * PURPOSE: "Delete files" dialog box

     */

BOOL APIENTRY DlgDelFilesProc(

    HWND hDlg,            /* window handle of dialog box  */

    UINT message,         /* type of message              */

    UINT wParam,          /* message-specific information */

    LONG lParam)

{

  DWORD cchCurDir;

  LPTSTR lpszCurDir;

  LPTSTR lpszFileToDelete;

  int nSelItems;

  int nSelItemsInBuffer;

  TCHAR tchBuffer[BUFFER];

  TCHAR tchMsgBuff[BUFFER];

  int nBuffer[BIGBUFF];

  int i;

  BOOL fResult;

  HWND hListBox;

  switch (message) {

    case WM_INITDIALOG:

      /*

       * Initialize the list box by filling it with files from

       * the current directory.

       */

      lpszCurDir = tchBuffer;

      GetCurrentDirectory(cchCurDir, lpszCurDir);

      DlgDirList(hDlg, lpszCurDir, IDL_FILES, IDS_PATHTOFILL, 0);

      SetFocus(GetDlgItem(hDlg, IDL_FILES));

      return FALSE;

    case WM_COMMAND:

      switch (LOWORD(wParam)) {

        case IDOK:

          /*

           * When the user presses the Delete (IDOK) button,

           * delete all the selected files.

           */

          lpszFileToDelete = tchBuffer;

          hListBox = GetDlgItem(hDlg, IDL_FILES);

          nSelItems = SendMessage(hListBox, LB_GETSELCOUNT, 0, 0);

          nSelItemsInBuffer = SendMessage(hListBox, LB_GETSELITEMS,

              512, (LPARAM) nBuffer);

          if (nSelItems > nSelItemsInBuffer) {

              MessageBox(hDlg, "Too many items selected.",

                  NULL, MB_OK);

          } else {

              for (i = nSelItemsInBuffer - 1; i > -1; i--) {

                SendMessage(hListBox, LB_GETTEXT, nBuffer[i],

                    (LPARAM) lpszFileToDelete);

                fResult = DeleteFile(lpszFileToDelete);

                if (!fResult) {

                    sprintf(tchMsgBuff,

                        "Could not delete file: %s GetLastError = %u",

                        (LPARAM) lpszFileToDelete);

                    ErrorHandler(tchMsgBuff);   /* app-defined */

                } else {

                    SendMessage(hListBox, LB_DELETESTRING,

                        nBuffer[i], 0);

                }

              }

              SendMessage(hListBox, LB_SETCARETINDEX, 0, 0);

          }

          return TRUE;

        case IDCANCEL:

          /* Destroy the dialog box. */

          EndDialog(hDlg, TRUE);

          return TRUE;

        default:

          return FALSE;

      }

    default:

        return FALSE;

  }

}


  11.2.4  Creating an Owner-Drawn List Box

The following code sample shows how to draw a list box that contains five owner-drawn items and prompts the user to select the item not like the others. »This illustration« shows the dialog box.

The list box has the LBS_OWNERDRAW and LBS_HASSTRINGS styles, in addition to the standard list box styles. The code initializes the list box by sending the LB_ADDSTRING message to set the text, and then sends the LB_SETITEMDATA message to associate a bitmap with each list box item. The code also sets the height of each list box item by processing the WM_MEASUREITEM message and draws the text and bitmap for each item by processing the WM_DRAWITEM message.

#define XBITMAP 80

#define YBITMAP 20

#define BUFFER MAX_PATH

HBITMAP hbmpPencil, hbmpCrayon, hbmpMarker, hbmpPen, hbmpFork;

HBITMAP hbmpPicture, hbmpOld;

    /*

     * FUNCTION: DlgDrawProc(HWND, unsigned, WORD, LONG)

     *

     * PURPOSE: "One of these things..." dialog box

     */

DWORD APIENTRY DlgDrawProc(

        HWND hDlg,            /* window handle of dialog box     */

        UINT message,         /* type of message                 */

        UINT wParam,          /* message-specific information    */

        LONG lParam)

{

  int nItem;

  TCHAR tchBuffer[BUFFER];

  HWND hListBox;

  TEXTMETRIC tm;

  int y;

  HDC hdcMem;

  LPMEASUREITEMSTRUCT lpmis;

  LPDRAWITEMSTRUCT lpdis;

  RECT rcBitmap;

  switch (message) {

    case WM_INITDIALOG:

      /* Load bitmaps. */

      hbmpPencil = LoadBitmap(hinst, MAKEINTRESOURCE(700));

      hbmpCrayon = LoadBitmap(hinst, MAKEINTRESOURCE(701));

      hbmpMarker = LoadBitmap(hinst, MAKEINTRESOURCE(702));

      hbmpPen = LoadBitmap(hinst, MAKEINTRESOURCE(703));

      hbmpFork = LoadBitmap(hinst, MAKEINTRESOURCE(704));

      /* Retrieve list box handle. */

      hListBox = GetDlgItem(hDlg, IDL_STUFF);

      /*

       * Initialize the list box text and associate a bitmap

       * with each list box item.

       */

      nItem = SendMessage(hListBox, LB_ADDSTRING, 0,

          (LPARAM) "pencil");

      SendMessage(hListBox, LB_SETITEMDATA, nItem,

          (LPARAM) hbmpPencil);

      nItem = SendMessage(hListBox, LB_ADDSTRING, 0,

          (LPARAM) "crayon");

      SendMessage(hListBox, LB_SETITEMDATA, nItem,

          (LPARAM) hbmpCrayon);

      nItem = SendMessage(hListBox, LB_ADDSTRING, 0,

          (LPARAM) "marker");

      SendMessage(hListBox, LB_SETITEMDATA, nItem,

          (LPARAM) hbmpMarker);

      nItem = SendMessage(hListBox, LB_ADDSTRING, 0,

          (LPARAM) "pen");

      SendMessage(hListBox, LB_SETITEMDATA, nItem,

          (LPARAM) hbmpPen);

      nItem = SendMessage(hListBox, LB_ADDSTRING, 0,

          (LPARAM) "fork");

      SendMessage(hListBox, LB_SETITEMDATA, nItem,

          (LPARAM) hbmpFork);

      SetFocus(hListBox);

      SendMessage(hListBox, LB_SETCURSEL, 0, 0);

      return TRUE;

    case WM_MEASUREITEM:

      lpmis = (LPMEASUREITEMSTRUCT) lParam;

      /* Set the height of the list box items. */

      lpmis->itemHeight = 20;

      return TRUE;

    case WM_DRAWITEM:

      lpdis = (LPDRAWITEMSTRUCT) lParam;

      /* If there are no list box items, skip this message. */

      if (lpdis->itemID == -1) {

        break;

      }

      /*

       * Draw the bitmap and text for the list box item. Draw a

       * rectangle around the bitmap if it is selected.

       */

      switch (lpdis->itemAction) {

        case ODA_SELECT:

        case ODA_DRAWENTIRE:

          /* Display the bitmap associated with the item. */

          hbmpPicture = (HBITMAP) SendMessage(lpdis->hwndItem,

              LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0);

          hdcMem = CreateCompatibleDC(lpdis->hDC);

          hbmpOld = SelectObject(hdcMem, hbmpPicture);

          BitBlt(lpdis->hDC,

              lpdis->rcItem.left, lpdis->rcItem.top,

              lpdis->rcItem.right - lpdis->rcItem.left,

              lpdis->rcItem.bottom - lpdis->rcItem.top,

              hdcMem, 0, 0, SRCCOPY);

          /* Display the text associated with the item. */

          SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID,

              (LPARAM) tchBuffer);

          GetTextMetrics(lpdis->hDC, &tm);

          y = (lpdis->rcItem.bottom + lpdis->rcItem.top -

              tm.tmHeight) / 2;

          TextOut(lpdis->hDC,

              XBITMAP + 6,

              y,

              tchBuffer,

              strlen(tchBuffer));

          SelectObject(hdcMem, hbmpOld);

          DeleteDC(hdcMem);

          /* Is the item selected? */

          if (lpdis->itemState & ODS_SELECTED) {

            /* Set RECT coordinates to surround only the bitmap. */

            rcBitmap.left = lpdis->rcItem.left;

            rcBitmap.top = lpdis->rcItem.top;

            rcBitmap.right = lpdis->rcItem.left + XBITMAP;

            rcBitmap.bottom = lpdis->rcItem.top + YBITMAP;

            /* Draw a rectangle around bitmap to indicate the selection. */

            DrawFocusRect(lpdis->hDC, &rcBitmap);

          }

          break;

        case ODA_FOCUS:

          /*

           * Do not process focus changes. The focus caret (outline

           * rectangle) indicates the selection. The Which one? (IDOK)

           * button indicates the final selection.

           */

          break;

      }

      return TRUE;

    case WM_COMMAND:

      switch (LOWORD(wParam)) {

        case IDOK:

          /* Get the selected item's text. */

          nItem = SendMessage(GetDlgItem(hDlg, IDL_STUFF),

              LB_GETCURSEL, 0, (LPARAM) 0);

          SendMessage(GetDlgItem(hDlg, IDL_STUFF), LB_GETTEXT,

              nItem, (LPARAM) tchBuffer);

          /*

           * If the item is not the correct answer, tell the

           * user to try again.

           *

           * If the item is the correct answer, congratulate

           * the user and destroy the dialog box.

           */

          if (strcmp(tchBuffer, "fork")) {

              MessageBox(hDlg, "Try again!", "Oops.", MB_OK);

              return FALSE;

          } else {

              MessageBox(hDlg, "You're right!", "Congratulations.",

                MB_OK);

            /* Fall through. */

          }

        case IDCANCEL:

          /* Destroy the dialog box. */

          EndDialog(hDlg, TRUE);

          return TRUE;

        default:

          return FALSE;

      }

    case WM_DESTROY:

        /* Free any resources used by the bitmaps. */

        DeleteObject(hbmpPencil);

        DeleteObject(hbmpCrayon);

        DeleteObject(hbmpMarker);

        DeleteObject(hbmpPen);

        DeleteObject(hbmpFork);

        return TRUE;

    default:

        return FALSE;

  }

  return FALSE;

}


  11.3  Functions and Messages

Following are the functions and messages used with list boxes.


  Functions

DigDirList
DigDirSelectEx


  Messages

LB_ADDFILE
LB_ADDSTRING
LB_DELETESTRING
LB_DIR
LB_FINDSTRING
LB_FINDSTRINGEXACT
LB_GETANCHORINDEX
LB_GETCARETINDEX
LB_GETCOUNT
LB_GETCURSEL
LB_GETHORIZONTALEXTENT
LB_GETITEMDATA
LB_GETITEMHEIGHT
LB_GETITEMRECT
LB_GETLOCALE
LB_GETSEL
LB_GETSELCOUNT
LB_GETSELITEMS
LB_GETTEXT
LB_GETTEXTLEN
LB_GETTOPINDEX
LB_INSERTSTRING
LB_RESETCONTENT
LB_SELECTSTRING
LB_SELITEMRANGE
LB_SELITEMRANGEEX
LB_SETANCHORINDEX
LB_SETCARETINDEX
LB_SETCOLUMNWIDTH
LB_SETCOUNT
LB_SETCURSEL
LB_SETHORIZONTALEXTENT
LB_SETITEMDATA
LB_SETITEMHEIGHT
LB_SETLOCALE
LB_SETSEL
LB_SETTABSTOPS
LB_SETTOPINDEX
LBN_DBLCLK
LBN_ERRSPACE
LBN_KILLFOCUS
LBN_SELCANCEL
LBN_SELCHANGE
LBN_SETFOCUS
WM_CHARTOITEM
WN_DELETEITEM
WN_VKEYTOITEM


12.1  About Edit Controls
  Chapter 12    Edit Controls

12.1  About Edit Controls

Microsoft® Windows (™)  provides dialog boxes and controls to support communication between the application and the user. An edit control is a rectangular control window typically used in a dialog box to permit the user to enter and edit text from the keyboard. The user selects an edit control giving it the input focus by clicking the mouse inside it or by pressing the TAB key. After it is selected, the edit control displays its text (if any) and a flashing caret that indicates the insertion point. The user can then enter text, move the insertion point, or select text to be moved or deleted by using the keyboard or the mouse. An edit control can send notification messages to its parent window in the form of WM_COMMAND messages. For more information about messages from an edit control, see Section 12.1.5, »Edit Control Notifications«. A parent window can send messages to an edit control in a dialog box by calling the SendDlgItemMessage function. Each of the messages sent to edit controls are discussed in this chapter.

Edit controls can be single-line (the default) or multiline. Multiline edit controls (sometimes called MLEs) can have scroll bars. Edit controls belong to the EDIT window class.

Although edit controls can be used in overlapped, pop-up, and child windows, they are designed for use in dialog boxes, where Windows standardizes their behavior. If the application uses edit controls outside dialog boxes, this creates extra work and increases the risk that the application may behave in a nonstandard fashion. For these reasons, the application should either use edit controls in dialog boxes or use window subclassing to create customized edit controls. For more information about dialog boxes, see Chapter 18, »Dialog Boxes«; for more information about window subclassing, see Chapter 4, »Window Procedures«.

A combo box is a control that combines much of the functionality of an edit control and a list box. In a combo box, the edit control displays the current selection and the list box presents options a user can select. For more information about combo boxes, see Chapter 13, »Combo Boxes«.

Many developers use the dialog boxes provided in the common dialog box library (COMDLG32.DLL) to perform tasks that otherwise might require customized edit controls. For information about common dialog boxes, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.


  12.1.1  Edit Control Styles

Windows provides 13 edit control styles. An individual edit control can have several styles at the same time. Most developers use stand-alone tools to develop dialog boxes and so may not need to specify edit control styles explicitly. If an application creates an edit control using the CreateWindow or CreateWindowEx function, however, it must specify these edit control styles.

Every edit control specifies a combination of style values that define the appearance and features of the edit control. The style values can establish the appearance of a single-line or multiline edit control, align the text in the control, and determine how, and even if, text appears in the edit control. The number and type of styles the application uses depend on the type and purpose of the edit control.

There are two line styles for edit controls. The default is a single-line edit control that doesn't require an associated style. An application can create a multiline edit control by using the ES_MULTILINE style.

There are three styles that cause Windows to align the text in an edit control. The ES_LEFT, ES_CENTER, and ES_RIGHT styles determine whether text is aligned on the left, center, or right, respectively. These styles apply only to multiline edit controls.

An application can use a style to determine how Windows displays text that a user enters in an edit control. The ES_LOWERCASE style converts the text into lowercase characters; the ES_UPPERCASE style converts the text into uppercase characters. Some applications may need to convert the text in a Windows string (such as a filename) into a specific character set. The ES_OEMCONVERT style ensures the proper conversion of characters in these instances. For more information about character sets, see Chapter 57, "Consoles and Character-Mode Support," in Microsoft Win32 Programmer's Reference, Volume 2.

When the amount of text to be displayed exceeds the size of the edit control, an application can use two styles to scroll the text through the edit control. The ES_AUTOHSCROLL style automatically scrolls text horizontally in single-line and multiline edit controls. When the application has a multiline edit control, it can also use the ES_AUTOVSCROLL style to automatically scroll text vertically, if necessary.

Other available styles define different aspects of an edit control. The ES_NOHIDESEL style specifies that the selected text is not hidden when the edit control loses the keyboard focus. The ES_READONLY style makes the edit control read-only. The ES_PASSWORD style displays all characters in the edit control as asterisks. (An application can define a different character to display by using the EM_SETPASSWORDCHAR message, as described later in this chapter.) In multiline edit controls, an application can specify the ES_WANTRETURN style to request that Windows insert a carriage return when the user presses the ENTER key in the edit control.

By default, an edit control has no border. To give it one, an application can use the WS_BORDER window style.


  12.1.2  The Text Buffer

Windows stores edit control text in a buffer and copies it to the control as necessary. This section discusses the tools Windows provides to allocate and initialize the buffer and to change its characteristics.


  12.1.2.1  Allocating a Text Buffer

When Windows creates an edit control, it automatically creates a text buffer, sets its initial size, and increases the size as necessary, up to a predefined limit of approximately 32 kilobytes for single-line edit controls. Because this limit can change, it is called a soft limit. An application can set a hard limit to the buffer size by sending an EM_LIMITTEXT message to the edit control. If the buffer exceeds either limit, Windows sends the application an EN_ERRSPACE message.

Windows typically creates an edit control buffer in a dialog box, using memory outside the application's data segment. An application can suppress this default allocation behavior and create the buffer from its local heap by using the DS_LOCALEDIT style when creating the edit control. An application that uses the DS_LOCALEDIT style is responsible for all buffer allocations. To make the initial allocation, an application can call the LocalAlloc function and pass the returned buffer handle to the edit control by sending it an EM_SETHANDLE message. To make subsequent allocations (in response to an EN_ERRSPACE message, for example), an application should save the current buffer contents (if necessary) and obtain a new buffer as follows:

1.	Retrieve the handle of the memory currently allocated for the text in a multiline edit control by sending the control an EM_GETHANDLE message.

2.	Free the buffer by calling the LocalFree function.

3.	Obtain a new buffer (and buffer handle) by calling LocalAlloc.

4.	Give the buffer handle to Windows by sending the control an EM_SETHANDLE message.

The EM_SETHANDLE and EM_GETHANDLE messages apply only to multiline edit controls.

An application that uses the default allocation behavior (that is, does not use the DS_LOCALEDIT style) must not send EM_SETHANDLE and EM_GETHANDLE messages to the edit control.

Sending an EM_SETHANDLE message has several side effects: it clears the undo flag (making the EM_CANUNDO message return zero), it clears the modify flag (making the EM_GETMODIFY message return zero), and it redraws the edit control window.


  12.1.2.2  Initializing a Text Buffer

An application can initialize or reinitialize an edit control's text buffer by calling the SetDlgItemText function. An application can retrieve the contents of a text buffer by calling the GetDlgItemText function.


  12.1.2.3  Making a Text Buffer Read-Only

For each edit control, Windows maintains a read-only flag that indicates whether the control's text is read-write (the default) or read-only. An application can set the read-write or read-only flag for the text by sending the control an EM_SETREADONLY message. To determine whether an edit control is read-only, an application can call the GetWindowLong function using the GWL_STYLE constant. The EM_SETREADONLY message applies to both single-line and multiline edit controls.


  12.1.3  Changing the Formatting Rectangle

The visibility of an edit control's text is governed by the dimensions of its window rectangle and its formatting rectangle. The window rectangle is the client area of the window containing the edit control. The formatting rectangle is a construct maintained by Windows for formatting the text displayed in the window rectangle. When an edit control is first displayed, the two rectangles are identical on the screen. An application can make the formatting rectangle larger than the window rectangle (thereby limiting the visibility of the edit control's text) or smaller than the window rectangle (thereby creating extra white space around the text).

An application can set the coordinates of an edit control's formatting rectangle by sending it an EM_SETRECT message. The EM_SETRECT message also automatically redraws the edit control's text. To establish the coordinates of the formatting rectangle without redrawing the control's text, an application can send the control an EM_SETRECTNP message. To retrieve the coordinates of the formatting rectangle, an application can send the control an EM_GETRECT message. These messages apply to multiline edit controls only.


  12.1.4  Text Operations

Windows automatically processes all user-initiated text operations and notifies the application when the operations are completed. This section discusses user-initiated text operations and the application's response.


  12.1.4.1  Character Sets

Windows supports two character sets: Unicode, a two-byte character set, and ANSI, a one-byte character set that is a strict subset of Unicode. In ANSI, n characters equals n bytes, but in Unicode, n characters equals 2n bytes. For more information about Unicode and character sets, see Chapter 53, "String Manipulation and Unicode," in Microsoft Win32 Programmer's Reference, Volume 2.


  12.1.4.2  Fonts

An application can change the font that an edit control uses by sending the WM_SETFONT message. Most applications do this while processing the WM_INITDIALOG message. Changing the font does not change the size of the edit control; applications that send the WM_SETFONT message may have to retrieve the font metrics for the text and recalculate the size of the edit control. For more information about fonts and font metrics, see Chapter 35, »Fonts and Text«.


  12.1.4.3  Selecting an Edit Control

The user can select an edit control in three ways: by clicking it with the mouse, by tabbing to it and pressing the SPACEBAR, or (when the edit control is part of a group defined using the WS_GROUP style) by tabbing to the selected edit control in the group and using the arrow keys to move within the group. (The latter two "tabbing" methods are part of a predefined keyboard interface that Windows provides. For a complete description of this interface, see Chapter 18, »Dialog Boxes«.) When the user selects an edit control, Windows gives the control the keyboard focus and highlights its text by using reverse video.


  12.1.4.4  Selecting Text

After selecting an edit control, the user can select text in the control by using the mouse or the keyboard. An application can retrieve the starting and ending character positions of the current selection in an edit control by sending the control an EM_GETSEL message. The return value for the ending position is one greater than the last character in the selection (that is, the position of the first character following the last selected character).

An application can also select text in an edit control by sending the control an EM_SETSEL message with the starting and ending character indices for the selection. For example, the application can use EM_SETSEL with EM_REPLACESEL to delete text from an edit control.

These three messages apply to both single-line and multiline edit controls.


  12.1.4.5  Replacing Text

An application can replace selected text in an edit control by sending the control an EM_REPLACESEL message with a pointer to the replacement text. If there is no current selection, EM_REPLACESEL inserts the replacement text at the insertion point. The application may receive an EN_ERRSPACE message if the replacement text exceeds the available memory. This message applies to both single-line and multiline edit controls.

An application can use EM_REPLACESEL to replace part of an edit control's text or the SetDlgItemText function to replace all of it.


  12.1.4.6  Cut, Copy, Paste, and Clear Operations

Windows provides four messages for moving text between an edit control and the Clipboard. The WM_COPY message copies the current selection (if any) from an edit control to the Clipboard without deleting it from the edit control. The WM_CUT message deletes the current selection, if any, in the edit control and copies the deleted text to the Clipboard. The WM_CLEAR message deletes the current selection (if any) from an edit control, but does not copy it to the Clipboard (unless the user pressed the SHIFT key). The WM_PASTE message copies text from the Clipboard into an edit control at the insertion point. These four messages apply to both single-line and multiline edit controls.


  12.1.4.7  Modifying Text

The user can select, delete, or move text in an edit control. Windows maintains an internal flag for each edit control indicating whether the contents of the control have been modified. Windows clears this flag when it creates the control and sets the flag whenever the text in the control is modified. An application can retrieve the modification flag by sending the control an EM_GETMODIFY message and set or clear the modification flag by sending the control an EM_SETMODIFY message. These messages apply to both single-line and multiline edit controls.


  12.1.4.8  Limiting User-Entered Text

The default limit to the amount of text a user can enter in an edit control is 32 kilobytes. An application can change the amount of text the user can enter by sending the control an EM_LIMITTEXT message. This message sets a hard limit to the number of bytes the user can enter into an edit control, but affects neither text in the control when the message was sent nor text copied to the control by the SetDlgItemText function. For example, suppose that the application uses the SetDlgItemText function to place 500 bytes in an edit control, and the user also enters 500 bytes (1000 bytes total). If the application then sends an EM_LIMITTEXT message limiting user-entered text to 300 bytes, the 1000 bytes already in the edit control remain there, and the user cannot add any more text (having entered 500 bytes already). On the other hand, if the application sends an EM_LIMITTEXT message limiting user-entered text to 1300 bytes, the 1000 bytes remain, but the user can add 800 more bytes (having entered only 500 bytes).

When the user reaches the character limit of an edit control, Windows sends the application a WM_COMMAND message containing an EN_MAXTEXT notification message. This notification message does not mean that memory has been exhausted, but that the limit for user-entered text has been reached and the user cannot enter any more text. To change this limit, an application must send the control a new EM_LIMITTEXT message with a higher limit.

As an example of the use of EM_LIMITTEXT and EN_MAXTEXT, suppose that the application must limit the user to no more than four characters in an edit control. The application would use EM_LIMITTEXT to specify a four-character limit. If the user tried to enter a fifth character, Windows would send an EN_MAXTEXT notification message to the application.


  12.1.4.9  Character and Line Operations

The Win32 application programming interface (API) provides several messages that return information about the characters and lines in an edit control. Most of the messages return an index, usually a zero-based number, to refer to a character or line. Given this, a single-line edit control containing n characters, the line index is zero and the characters are indexed from zero to n − 1. In a multiline edit control containing m lines and n characters, the lines are indexed from zero to m − 1, and the characters are indexed from zero to n − 1. Note that character indexing ignores line breaks.

An application can determine the number of characters in an edit control by sending the WM_GETTEXTLENGTH message to the edit control. This message returns the length, in characters (not including the terminating null character), of the text in a single-line or multiline edit control. The EM_LINELENGTH message returns the length, in characters, of a line specified by the character index of a character in the line. The returned length does not include any selected characters. An application can use these messages in a single-line or multiline edit control.

The EM_GETFIRSTVISIBLELINE message returns the zero-based index of the uppermost visible line in a multiline edit control, or the zero-based index of the first visible character in a single-line edit control. An application can copy a line from an edit control to a buffer by sending the EM_GETLINE message to the edit control. The line is specified by its line index and the first word of the receiving buffer contains the maximum number of bytes to be copied to the buffer. The return value is the number of bytes copied. This message can also be used in a single-line or multiline edit control.

There are unique messages available to return the information about a line in a multiline edit control. The EM_GETLINECOUNT message returns the number of lines in an edit control. An application can determine the index of a character in a specific line by using the EM_LINEFROMCHAR and EM_LINEINDEX messages. The EM_LINEFROMCHAR message returns the index of the line containing a specified character index. This message is the reverse of the EM_LINEINDEX message, which returns the index of the first character in a specified line.


  12.1.4.10  Scrolling Text

An application can implement scrolling in an edit control by using the automatic scrolling styles discussed in Section 12.1.1, »Edit Control Styles« or by explicitly adding scroll bars to the control. To add a horizontal scroll bar, use the style WS_HSCROLL; to add a vertical scroll bar, use the style WS_VSCROLL. An edit control with scroll bars processes its own scroll bar messages. For detailed information about adding scroll bars to edit controls, see Chapter 14, »Scroll Bars«.

Windows provides two messages that an application can send to an edit control with scroll bars. The EM_LINESCROLL message scrolls a multiline edit control vertically, or horizontally if the control has the ES_LEFT style. The lParam parameter specifies the number of lines to scroll vertically starting from the current line and the wParam parameter specifies the number of characters to scroll horizontally, starting from the current character. The edit control doesn't acknowledge horizontal scrolling messages if it has the ES_CENTER or ES_RIGHT style. This message applies to multiline edit controls only.

The EM_SCROLL message scrolls a multiline edit control vertically, which is the same effect as sending a WM_VSCROLL message. The wParam parameter specifies the scrolling action. The EM_SCROLL message applies to multiline edit controls only.

The EM_SCROLLCARET message scrolls the caret into view in an edit control. This was done in previous versions of Windows by specifying fScroll = FALSE in an EM_SETSEL message. A Win32 application should use the EM_SCROLLCARET message for the task.


  12.1.4.11  Tab Stops

An application can set tab stops in a multiline edit control by using the EM_SETTABSTOPS message. (The default for a tab stop is eight characters.) When an application adds text to the edit control, tab characters in the text automatically generate space up to the next tab stop. The EM_SETTABSTOPS message does not automatically cause Windows to redraw the text. To do that, an application can call the InvalidateRect function. The EM_SETTABSTOPS message applies to multiline edit controls only.


  12.1.4.12  Password Characters

An application can use a password character in an edit control to conceal user input. When a password character is set, it is displayed in place of each character the user types. When a password character is removed, the control displays the characters the user types. If the application creates an edit control using the style ES_PASSWORD, the default password character is an asterisk (*). An application can use the EM_SETPASSWORDCHAR message to remove or define a different password character and the EM_GETPASSWORDCHAR message to retrieve the current password character. These messages apply to single-line edit controls only.


  12.1.4.13  Using Integers

Windows provides two integer-conversion functions for edit controls designed to contain numbers only. The SetDlgItemInt function creates the string representation of a specified integer (signed or unsigned) and sends the string to an edit control. SetDlgItemInt returns no value. The GetDlgItemInt function creates an integer (signed or unsigned) from its string representation in an edit control. GetDlgItemInt returns the integer (or an error code).


  12.1.4.14  Undoing Text Operations

Every edit control maintains an undo flag that indicates whether an application can reverse (undo) the most recent operation on the edit control (to undo a text deletion, for example). The edit control sets the undo flag to indicate that the operation can be undone and resets it to indicate that the operation cannot be undone. An application can determine the setting of the undo flag by sending the control an EM_CANUNDO message.

An application can undo the most recent operation by sending the control an EM_UNDO message. An operation can be undone provided no other edit control operation occurs first. For example, the user can delete text, replace the text (undo the deletion), and then delete the text again (undo the replacement). The EM_UNDO message applies to both single-line and multiline edit controls and always works for single-line edit controls.

An application can reset an edit control's undo flag by sending the control an EM_EMPTYUNDOBUFFER message. Windows automatically resets the undo flag whenever an edit control receives an EM_SETHANDLE or WM_SETTEXT message. The SetDlgItemText function sends a WM_SETTEXT message.


  12.1.4.15  Wordwrap Functions

An application can use wordwrap functions with multiline edit controls to locate the word or word fragment that should be wrapped to the next line. Using the default wordwrap function provided by Windows, lines always end at the spaces between words. An application can specify its own wordwrap function by supplying a WordBreakProc wordwrap function and sending an edit control an EM_SETWORDBREAKPROC message. An application can retrieve the address of the current wordwrap function by sending the control an EM_GETWORDBREAKPROC message.

An application may direct a multiline edit control to add or remove a soft line-break character (two carriage returns and a linefeed) automatically at the end of wrapped text lines. An application can turn this feature on or off by sending the edit control an EM_FMTLINES message. This message applies only to multiline edit controls and does not affect a line that ends with a hard line break (one carriage return and a linefeed entered by the user).


  12.1.5  Edit Control Notifications

The user makes editing requests by using the keyboard and mouse. Windows sends each request to the edit control's parent window in the form of a WM_COMMAND message. The message includes the edit control identifier in the low-order word of the wParam parameter, the handle of the edit control in the lParam parameter, and an edit control notification message corresponding to the user's action in the high-order word of the wParam parameter.

Portability issue   In Microsoft® Windows NT (™) , the placement of the notification code in a notification message has moved from the lParam parameter to the wParam parameter. Windows 3.x applications that process notification messages must modify this code when porting to Windows NT.

An application should examine each notification message and respond appropriately. The following table lists each edit control notification message and the action that generates it.

Notification message	User action
EN_CHANGE	The user has modified text in an edit control. Windows updates the display before sending this message (unlike EN_UPDATE).
EN_ERRSPACE	The edit control cannot allocate enough memory to meet a specific request.
EN_HSCROLL	The user has clicked the edit control's horizontal scroll bar. Windows sends this message before updating the screen.
EN_KILLFOCUS	The user has selected another control.
EN_MAXTEXT	While inserting text, the user has exceeded the specified number of characters for the edit control. Insertion has been truncated. This message is also sent either when an edit control does not have the ES_AUTOHSCROLL style and the number of characters to be inserted exceeds the width of the edit control or when an edit control does not have the ES_AUTOVSCROLL style and the total number of lines to be inserted exceeds the height of the edit control.
EN_SETFOCUS	The user has selected this edit control.
EN_UPDATE	The user has altered the text in the edit control and Windows is about to display the new text. Windows sends this message after formatting the text, but before displaying it, so that the application can resize the edit control window.
EN_VSCROLL	The user has clicked the edit control's vertical scroll bar. Windows sends this message before updating the screen.
In addition, the system sends a WM_CTLCOLOREDIT message to an edit control's parent window before the edit control is drawn. This message contains a handle of the edit control's display context and a handle of the child window. The parent window can use these handles to change the edit control's text and background colors.


  12.1.6  Default Message Processing

The window procedure for the predefined edit control window class carries out default processing for all messages that the edit control procedure does not process. When the edit control procedure returns FALSE for any message, the predefined window procedure checks the messages and carries out the following default actions.

Message	Default action
EM_CANUNDO	Returns TRUE if the edit control operation can be undone.
EM_EMPTYUNDOBUFFER	Empties the undo buffer and sets the undo flag retrieved by the EM_CANUNDO message to FALSE. Windows automatically clears the undo flag whenever the edit control receives a WM_SETTEXT or EM_SETHANDLE message.
EM_FMTLINES	Adds or removes soft line-break characters (two carriage returns and a linefeed) to the ends of wrapped lines in a multiline edit control. It is not processed by single-line edit controls.
EM_GETFIRSTVISIBLELINE	Returns the zero-based index of the first visible character in a single-line edit control or the zero-based index of the uppermost visible line in a multiline edit control.
EM_GETHANDLE	Returns a handle identifying the buffer containing the multiline edit control's text. It is not processed by single-line edit controls.
EM_GETLINE	Copies characters in a single-line edit control to a buffer and returns the number of characters copied. In a multiline edit control, retrieves a line of text from the control and returns the number of characters copied.
EM_GETLINECOUNT	Returns the number of lines in the edit control.
EM_GETMODIFY	Returns a flag indicating whether the contents of an edit control have been modified.
EM_GETPASSWORDCHAR	Returns the character that edit controls use in conjunction with the ES_PASSWORD style.
EM_GETRECT	Returns the coordinates of the formatting rectangle in an edit control.
EM_GETSEL	Returns the starting and ending character positions of the current selection in the edit control.
EM_GETTHUMB	Unsupported.
EM_GETWORDBREAKPROC	Returns the address of the current wordwrap function in an edit control.
EM_LIMITTEXT	Sets the maximum number of characters the user may enter in the edit control. For single-line edit controls, this value is either 0x7FFFFFFE or the value of the wParam parameter, whichever is smaller. For multiline edit controls, this value is either 0xFFFFFFFF or the value of the wParam parameter, whichever is smaller.
EM_LINEFROMCHAR	Returns the zero-based number of the line in a multiline edit control that contains a specified character index This message is the reverse of the EM_LINEINDEX message. It is not processed by single-line edit controls.
EM_LINEINDEX	Returns the character of a line in a multiline edit control. This message is the reverse of the EM_LINEFROMCHAR message. It is not processed by single-line edit controls.
EM_LINELENGTH	Returns the length, in characters, of a single-line edit control. In a multiline edit control, returns the length, in characters, of a specified line.
EM_LINESCROLL	Scrolls the text vertically in a single-line edit control or horizontally in a multiline edit control (when the control has the ES_LEFT style). The lParam parameter specifies the number of lines to scroll vertically, starting from the current line. The wParam parameter specifies the number of characters to scroll horizontally, starting from the current character.
EM_MSGMAX	Unsupported.
EM_REPLACESEL	Replaces the current selection with the text in an application-supplied buffer, sends the parent window EN_UPDATE and EN_CHANGE messages, and updates the undo buffer.
EM_SCROLL	Scrolls the text vertically in a multiline edit control. This message is equivalent to sending a WM_VSCROLL message to the edit control. It is not processed by single-line edit controls.
EM_SCROLLCARET	Scrolls the caret into view in an edit control. In previous versions of Windows this was done via EM_SETSEL using particular parameters. A Win32 application should use EM_SCROLLCARET.
EM_SETFONT	Unsupported.
EM_SETHANDLE	Sets a handle to the memory used as a text buffer, empties the undo buffer, resets the scroll positions to zero, and redraws the window.
EM_SETMODIFY	Sets or clears the modification flag to indicate whether the edit control has been modified.
EM_SETPASSWORDCHAR	Defines the character that edit controls use in conjunction with the ES_PASSWORD style.
EM_SETREADONLY	Sets or removes the read-only style (ES_READONLY) in an edit control.
EM_SETRECT	Sets the formatting rectangle for the multiline edit control and redraws the window. It is not processed by single-line edit controls.
EM_SETRECTNP	Sets the formatting rectangle for the multiline edit control but does not redraw the window. It is not processed by single-line edit controls.
EM_SETSEL	Selects a range of characters in the edit control by setting the starting and ending positions to be selected.
EM_SETTABSTOPS	Sets tab-stop positions in the multiline edit control. It is not processed by single-line edit controls.
EM_SETWORDBREAKPROC	Replaces the default wordwrap function with an application-defined wordwrap function.
EM_UNDO	Removes any text that was just inserted or inserts any deleted characters and sets the selection to the inserted text. If necessary, sends the EN_UPDATE and EN_CHANGE notification messages to the parent window.
WM_CHAR	Writes a character to the single-line edit control and sends the EN_UPDATE and EN_CHANGE notification messages to the parent window. Writes a character to the multiline edit control. Handles the accelerator keys for standard functions, such as CTRL+C for copying and CTRL+V for pasting. In multiline edit controls, also processes TAB, and CTRL+TAB keystrokes to move among the controls in a dialog box and to insert tabs into multiline edit controls. Uses the MessageBeep function for illegal characters.
WM_CLEAR	Clears the current selection, if any, in an edit control. If there is no current selection, deletes the character to the right of the caret. If the user presses the SHIFT key, this cuts the selection to the Clipboard, or deletes the character to the left of the caret when there is no selection. If the user presses the CTRL key, this deletes the selection, or deletes to the end of the line when there is no selection.
WM_COPY	Copies text to the Clipboard unless the style is ES_PASSWORD, in which case the message returns zero.
WM_CREATE	Creates the edit control and notifies the parent window with TRUE for success or −1 for failure.
WM_CUT	Cuts the selection to the Clipboard, or deletes the character to the left of the cursor if there is no selection.
WM_ENABLE	Causes the rectangle to be redrawn in gray for single-line edit controls. Returns the enabled state for single-line and multiline edit controls.
WM_ERASEBKGND	Fills the multiline edit control window with the current color of the edit control.
WM_GETDLGCODE	Returns the following values: DLGC_WANTCHARS, DLGC_HASSETSEL, and DLGC_WANTARROWS. In multiline edit controls, it also returns DLGC_WANTALLKEYS. If the user presses ALT+BACKSPACE, it also returns DLGC_WANTMESSAGE.
WM_GETFONT	Returns the handle of the font being used by the control, or NULL if the control uses the system font.
WM_GETTEXT	Copies the specified number of characters to a buffer and returns the number of characters copied.
WM_GETTEXTLENGTH	Returns the length, in characters, of the text in an edit control. The length does not include the null- terminating character.
WM_HSCROLL	Scrolls the text in a multiline edit control horizontally and handles scroll box movement.
WM_KEYDOWN	Performs standard processing of the virtual-key codes.
WM_KILLFOCUS	Removes the keyboard focus of an edit control window, destroys the caret, hides the current selection, and notifies the parent window that the edit control has lost the focus.
WM_LBUTTONDBLCLK	Clears the current selection and selects the word under the cursor. If the SHIFT key is down, extends the selection to the word under the cursor.
WM_LBUTTONDOWN	Changes the current insertion point. If the SHIFT key is down, it extends the selection to the position of the cursor. In multiline edit controls, also sets the timer to automatically scroll when the user holds down the mouse button outside the multiline edit control window.
WM_LBUTTONUP	Releases the mouse capture and sets the text insertion point in the single-line edit control. In a multiline edit control, it also kills the timer set in the WM_LBUTTONDOWN message.
WM_MOUSEMOVE	Changes the current selection in the single-line edit control, if the mouse button is down. In a multiline edit controls, also sets the timer to automatically scroll if the user holds down the mouse button outside the multiline edit control window.
WM_NCCREATE	Points to the CREATESTRUCT structure for the window. This message is sent to the WM_CREATE message when a window is first created.
WM_NCDESTROY	Frees all memory associated with the edit control window, including the text buffer, undo buffer, tab-stop buffer, and highlight brush.
WM_PAINT	Erases the background, fills the window with the current color of the edit control window, draws the border (if any), sets the font and draws any text, and shows the text-insertion caret.
WM_PASTE	Pastes text from the Clipboard into the edit control window at the caret position.
WM_SETFOCUS	Sets the keyboard focus of an edit control window (shows the current selection, if it was hidden, and creates the caret).
WM_SETFONT	Sets the font and optionally redraws the edit control.
WM_SETTEXT	Copies text to the single-line edit control, notifies the parent window when there is insufficient memory, empties the undo buffer, and sends the EN_UPDATE and EN_CHANGE notification messages to the parent window. In multiline edit controls, also rewraps the lines (if necessary) and sets the scroll positions.
WM_SIZE	Changes the size of the edit control window and ensures that the minimum size accommodates the height and width of a character.
WM_SYSCHAR	Returns TRUE if the user presses ALT+BACKSPACE; otherwise, it takes no action.
WM_SYSKEYDOWN	Undoes the last action if the user presses ALT+BACKSPACE; otherwise, it takes no action.
WM_TIMER	Scrolls the text in the edit control window if the user holds down the mouse button outside the multiline edit control window.
WM_UNDO	Removes any text that was just inserted or inserts any deleted characters and sets the selection to the inserted text. If necessary, sends the EN_UPDATE and EN_CHANGE notification messages to the parent window.
WM_VSCROLL	Scrolls a multiline edit control vertically and handles scroll box movement. It is not processed by single-line edit controls.
The predefined edit control window procedure passes all other messages to the DefWindowProc function for default processing.


  12.2  Using Edit Controls

Edit controls are typically used in dialog boxes, but you can use them in the client area of a standard window as well. Single-line edit controls are useful for retrieving a single string from the user. Multiline edit controls make it easy for your application to implement most of the features of a simple word processor.


  12.2.1  Simple Word Processing with an Edit Control

The following code sample implements much of the functionality of a simple word processor by filling the client area of a window with a multiline edit control. The system automatically performs wordwrap operations for this edit control and also handles the processing for the vertical scroll bar (created by specifying ES_AUTOVSCROLL in the call to the CreateWindow function). The WM_COMMAND message processes menu items; they allow the user to undo the previous action, cut or copy selections to the Clipboard, paste text from the Clipboard, and delete the current selection.

LONG APIENTRY MainWndProc(

HWND hwnd,                /* window handle                   */

UINT message,             /* type of message                 */

UINT wParam,              /* additional information          */

LONG lParam)              /* additional information          */

{

    static HWND hwndEdit;

    CHAR lpszTrouble[] = "When in the Course of human Events "

                         "it becomes necessary for one People "

                         "to dissolve the Political Bands which "

                         "have connected them with another, and "

                         "to assume among the Powers of the "

                         "Earth, the separate and equal Station "

                         "to which the Laws of Nature and of "

                         "Nature's God entitle them, a decent "

                         "Respect to the Opinions of Mankind "

                         "requires that they should declare the "

                         "causes which impel them to the "

                         "Separation. ";

    switch (message) {

        case WM_CREATE:

            hwndEdit = CreateWindow(

                "EDIT",     /* predefined class                  */

                NULL,       /* no window title                   */

                WS_CHILD | WS_VISIBLE | WS_VSCROLL |

                    ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,

                0, 0, 0, 0, /* set size in WM_SIZE message       */

                hwnd,       /* parent window                     */

                (HMENU) ID_EDITCHILD, /* edit control ID         */

                (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),

                NULL);                /* pointer not needed      */

             /* Add text to the window. */

             SendMessage(hwndEdit, WM_SETTEXT, 0,

                (LPARAM) lpszTrouble);

            return 0;

        case WM_COMMAND:

            switch (wParam) {

                case IDM_EDUNDO:

                   SingleLine

                     /*

                     * Send WM_UNDO only if there is something

                     * to be undone.

                     */

                    if (SendMessage(hwndEdit, EM_CANUNDO, 0, 0))

                        SendMessage(hwndEdit, WM_UNDO, 0, 0);

                    else

                        MessageBox(hwndEdit,

                            "Nothing to undo.",

                            "Undo notification", MB_OK);

                    break;

                case IDM_EDCUT:

                    SendMessage(hwndEdit, WM_CUT, 0, 0);

                    break;

                case IDM_EDCOPY:

                    SendMessage(hwndEdit, WM_COPY, 0, 0);

                    break;

                case IDM_EDPASTE:

                    SendMessage(hwndEdit, WM_PASTE, 0, 0);

                    break;

                case IDM_EDDEL:

                    SendMessage(hwndEdit, WM_CLEAR, 0, 0);

                    break;

                default:

                    return DefWindowProc(hwnd, message, wParam, lParam);

            }

            break;

        case WM_SETFOCUS:

            SetFocus(hwndEdit);

            return 0;

        case WM_SIZE:

            /*

             * Make the edit control the size of the window's

             * client area.

             */

            MoveWindow(hwndEdit,

                0, 0,           /* starting x- and y-coordinates */

                LOWORD(lParam), /* width of client area          */

                HIWORD(lParam), /* height of client area         */

                TRUE);          /* repaint window                */

            return 0;

        case WM_DESTROY:

            PostQuitMessage(0);

            return 0;

        default:

            return DefWindowProc(hwnd, message, wParam, lParam);

    }

    return NULL;

}


  12.2.2  Using Single-Line Edit Controls

The code sample in this section demonstrates how to use a window procedure to produce a dialog box, as shown in »this illustration«.

The single-line edit control in the Password dialog box has the ES_PASSWORD style. By default, edit controls with this style display an asterisk for each character the user types. This example, however, uses the EM_SETPASSWORDCHAR message to change the default character from an asterisk to a plus sign (+).

This window procedure changes the default push button from Cancel to OK as soon as the user enters text in the edit control. If the user presses the OK button, the window procedure uses the EM_LINELENGTH and EM_GETLINE messages to retrieve the text.

LRESULT CALLBACK PassProc(hDlg, message, wParam, lParam)

HWND hDlg;                /* window handle of the dialog box */

UINT message;             /* type of message                 */

UINT wParam;              /* message-specific information    */

LONG lParam;

{

    CHAR lpszPassword[16];

    WORD cchPassword;

    switch (message) {

        case WM_INITDIALOG:

            /* Set password character to a plus sign (+) */

            SendDlgItemMessage(hDlg,

                IDE_PASSWORDEDIT,

                EM_SETPASSWORDCHAR,

                (WPARAM) '+',

                (LPARAM) 0);

            /* Set the default push button to "Cancel." */

            SendMessage(hDlg,

                DM_SETDEFID,

                (WPARAM) IDCANCEL,

                (LPARAM) 0);

            return TRUE;

        case WM_COMMAND:

            /*

             * Set the default push button to "OK" when the user

             * enters text.

             */

            if(HIWORD (wParam) == EN_CHANGE &&

                    LOWORD(wParam) == IDE_PASSWORDEDIT)

                SendMessage(hDlg,

                    DM_SETDEFID,

                    (WPARAM) IDOK,

                    (LPARAM) 0);

            switch(wParam) {

                case IDOK:

                    /* Get number of characters. */

                    cchPassword = (WORD) SendDlgItemMessage(hDlg,

                        IDE_PASSWORDEDIT,

                        EM_LINELENGTH,

                        (WPARAM) 0,

                        (LPARAM) 0);

                    if (cchPassword >= 16) {

                        MessageBox(hDlg,

                            "Too many characters.",

                            "Error",

                            MB_OK);

                        EndDialog(hDlg, TRUE);

                        return FALSE;

                    }

                    else if (cchPassword == 0) {

                        MessageBox(hDlg,

                            "No characters entered.",

                            "Error",

                            MB_OK);

                        EndDialog(hDlg, TRUE);

                        return FALSE;

                    }

                    /*

                     * Put the number of characters into first word

                     * of buffer.

                     */

                    *((LPWORD)lpszPassword) = cchPassword;

                    /* Get the characters. */

                    SendDlgItemMessage(hDlg,

                        IDE_PASSWORDEDIT,

                        EM_GETLINE,

                        (WPARAM) 0,       /* line 0 */

                        (LPARAM) lpszPassword);

                    /* Null-terminate the string. */

                    lpszPassword[cchPassword] = 0;

                    /* Call a local password-parsing function. */

                    ParsePassword(lpszPassword);

                    EndDialog(hDlg, TRUE);

                    return TRUE;

                case IDCANCEL:

                    EndDialog(hDlg, TRUE);

                    return TRUE;

            }

            return 0;

    }

    return FALSE;

        UNREFERENCED_PARAMETER(lParam);

}


  12.3  Functions and Messages

Following are the function and messages used with edit controls.


  Function

WordBreakProc


  Messages

EM_CANUNDO
EM_EMPTYUNDOBUFFER
EM_FMTLINES
EM_GETFIRSTVISIBLELINE
EM_GETHANDLE
EM_GETLINE
EM_GETLINECOUNT
EM_GETMODIFY
EM_GETPASSWORDCHAR
EM_GETRECT
EM_GETSEL
EM_GETWORDBREAKPROC
EM_LIMITTEXT
EM_LINEFROMCHAR
EM_LINEINDEX
EM_LINELENGTH
EM_LINESCROLL
EM_REPLACESEL
EM_SCROLL
EM_SCROLLCARET
EM_SETHANDLE
EM_SETMODIFY
EM_SETPASSWORDCHAR
EM_SETREADONLY
EM_SETRECT
EM_SETRECTNP
EM_SETSEL
EM_SETTABSTOPS
EM_SETWORDBREAKPROC
EM_UNDO
EN_CHANGE
EN_ERRSPACE
EN_HSCROLL
EN_KILLFOCUS
EN_MAXTEXT
EN_SETFOCUS
EN_UPDATE
EN_VSCROLL
WM_COMMAND
WM_COPY
WM_CTLCOLOREDIT
WM_CUT
WM_PASTE
WM_UNDO


  Terms

Term	Definition
edit control	An element of the Windows user interface that allows the user to enter and edit text. Edit controls are typically used in dialog boxes.


13.1  About Combo Boxes
  Chapter 13    Combo Boxes

13.1  About Combo Boxes

As discussed in Chapter 9, "Controls," dialog boxes and controls provide users of the Microsoft® Windows (™)  operating system with the means to enter text, choose options, and complete actions. A combo box, however, is a unique type of control. It is defined by the COMBOBOX class and combines much of the functionality of a list box and an edit control.

Windows provides three types of combo box: simple combo boxes (CBS_SIMPLE), drop-down combo boxes (CBS_DROPDOWN), and drop-down list boxes (CBS_DROPDOWNLIST).

There are also a number of combo box styles that define specific properties. For example, two styles enable an application to create an owner-drawn combo box, making the application responsible for displaying information in the control.

A combo box consists of a list and a selection field. The list presents the options a user can select and the selection field displays the current selection. Except in drop-down list boxes, the selection field is an edit control and can be used to enter text not in the list.

Combo boxes are used primarily in dialog boxes. Dialog boxes can process keyboard input messages that combo boxes cannot, such as the TAB, ENTER, and ESCAPE keys. However, an application can provide this functionality outside a dialog box by using window subclassing. For more information about dialog boxes, see Chapter 18, »Dialog Boxes«.

This chapter describes the types and styles of combo box, the parts of a combo box, the use of an owner-drawn combo box, and how to subclass a combo box. Additional features of combo boxes are also discussed.


  13.1.1  Combo Box Types and Styles

Combo boxes can be characterized by type and style. Combo box types determine whether the combo box list is a drop-down list and whether the selection field is an edit control. A drop-down list appears only when the user opens it, so it uses less screen space than a list that is always visible. If the selection field is an edit control, the user can enter information not in the list; otherwise, the user can only select items in the list.

The following table shows the three combo box types and indicates whether each includes a drop-down list and an edit control.

Combo box type	Drop-down list	Edit control
Simple combo box	No	Yes
Drop-down combo box	Yes	Yes
Drop-down list box	Yes	No
Combo box styles define specific properties of a combo box. An application can combine styles; however some styles only apply to certain combo box types. The following table describes the combo box styles.

Style	Desription
CBS_AUTOHSCROLL	Automatically scrolls text to the left when the user types beyond the right end of the selection field. If an application does not specify this style, only text that fits within the edit control is allowed. This style does not apply to drop-down list boxes.
CBS_DISABLENOSCROLL	Displays a scroll bar in the list even if the entire contents are visible at once. Ordinarily, the scroll bar only appears if the list contains enough items to scroll through.
CBS_HASSTRINGS	Keeps track of strings for list items in an owner-drawn combo box. For more information, see Section 13.1.4, »Owner-Drawn Combo Boxes«.
CBS_NOINTEGRALHEIGHT	Specifies that the combo box is exactly the size set forth by the application when it created the combo box. Ordinarily, Windows adjusts the size of a combo box so it does not display partial items.
CBS_OEMCONVERT	Specifies that text in the selection field is in the OEM character set. Windows automatically converts text to and from the OEM character set as it is entered in and retrieved from the selection field. This style does not apply to drop-down list boxes.
CBS_OWNERDRAWFIXED	Assigns responsibility for displaying information to the parent window or dialog box procedure It specifies that list items are all the same size. For more information, see Section 13.1.4, »Owner-Drawn Combo Boxes«.
CBS_OWNERDRAWVARIABLE	Assigns responsibility for displaying information to the parent window or dialog box procedure It specifies that list items vary in size. For more information, see Section 13.1.4, »Owner-Drawn Combo Boxes«.
CBS_SORT	Automatically sorts the contents of the list. An application can ensure that sorted combo box items are correct for a given language and sublanguage by using CB_SETLOCALE message. To retrieve the current locale for a combo box, use the CB_GETLOCALE message.


  13.1.2  Combo Box List

The list is the portion of a combo box that displays the items a user can select. Typically, an application initializes the contents of the list when it creates a combo box. Any list item selected by the user is the current selection. In simple and drop-down combo boxes, the user can type in the selection field instead of selecting a list item. In these cases, there is no current selection. For more information, see Section 13.1.3, »Edit Control Selection Fields«.


  13.1.2.1  List Contents

When an application creates a combo box, it typically initializes the combo box by adding one or more strings to the list. Later, an application may add or delete list items reinitialize the list, or retrieve strings from it.

An application adds list items to a combo box by sending the CB_ADDSTRING message to it. The specified string is added to the end of the list or, in a sorted combo box, in its correct sorted position. In an unsorted combo box, an application can use the CB_INSERTSTRING message to insert a string at a specific position. Once added, a list item is identified by its position.

An application can determine the position of a list item by using the CB_FINDSTRING or CB_FINDSTRINGEXACT message. The CB_FINDSTRING message finds an item beginning with the specified string. The CB_FINDSTRINGEXACT message finds an item that matches the string exactly. Neither message is case sensitive.

An application can remove a list item by using the CB_DELETESTRING message. If an application needs to reinitialize the combo box list, it can first clear its entire contents by using the CB_RESETCONTENT message. When adding multiple strings to the list after a combo box has already been shown, an application can clear the redraw flag to prevent the combo box from being repainted after each string is added. For more information, see the WM_SETREDRAW message.

To retrieve the text for a list entry, an application can use the CB_GETLBTEXT message. The string is copied to the buffer specified by the application. To ensure that the buffer is large enough to receive the string, the application can first use the CB_GETLBTEXTLEN message to determine the length of the string. To get the number of list items in a combo box, an application can use the CB_GETCOUNT message.


  13.1.2.2  Current Selection

The current selection is a list item the user has selected; the selected text appears in the selection field edit control in the combo box. However, the current selection is only one form of possible user input in a combo box. The user can also type text in the selection field. In a drop-down list box, the current selection is the only form of user input.

The current selection is identified by the zero-based index of the selected list item. An application can set and retrieve it at any time. The parent window or dialog box procedure receives notifications when the current selection for a combo box changes.

When a combo box is created, there is no current selection. This is also true for a simple or drop-down combo box if the user has edited the contents of the selection field. To set the current selection, an application sends the CB_SETCURSEL message to the combo box. An application can also use the CB_SELECTSTRING message to set the current selection to a list item beginning with a specified string. To determine the current selection, an application sends the CB_GETCURSEL message to the combo box. If there is no current selection, this message returns CB_ERR.

When the current selection in a combo box changes, the parent window or dialog-box procedure receives a WM_COMMAND message with the CBN_SELCHANGE notification code in the high-order word of wParam. As a result, the application can respond to this notification message and execute a specific process each time the user selects a list item. This notification is not sent when the current selection is set using the CB_SETCURSEL message nor when the user modifies the current selection in a simple or drop-down combo box.

In a drop-down combo box or drop-down list box, an application can close the list and wait to process a change in the current selection until the user selects a new item. This can be useful when significant processing is required. For example, to update a directory list based on the selected drive, an application can process the CBN_CLOSEUP message instead of CBN_SELCHANGE to update a directory list after the user selects a drive.

Alternatively, an application can process the CBN_SELENDOK and CBN_SELENDCANCEL messages. The system sends the CBN_SELENDOK notification when the user clicks a list item or selects an item and then closes the list. This indicates the user has finished and the selection should be processed. The CBN_SELENDCANCEL notification is sent when the user selects an item but then selects another control or closes the dialog box. This indicates the user's selection should be ignored. In a simple combo box, a CBN_SELENDOK notification is sent before every CBN_SELCHANGE message. The system does not send the CBN_SELENDOK and CBN_SELENDCANCEL messages if the WS_EX_NOPARENTNOTIFY extended window style is specified for the combo box.

In a simple combo box, the system sends the CBN_DBLCLK notification when the user double-clicks a list item. In a drop-down combo box or drop-down list, however, a single click hides the list so it is not possible to double-click an item.


  13.1.2.3  Drop-Down Lists

Certain notifications and messages apply only to combo boxes containing drop-down lists. When a drop-down list is open or closed, the parent window of a combo box receives a notification in the form of a WM_COMMAND message. If the list is being opened, the high-order word of wParam is CBN_DROPDOWN. If the list is being closed, it is CBN_CLOSEUP.

An application can open the list of a drop-down combo box or drop-down list box by using the CB_SHOWDROPDOWN message. It can determine whether the list is open by using the CB_GETDROPPEDSTATE message and can determine the coordinates of a drop-down list by using the CB_GETDROPPEDCONTROLRECT message.


  13.1.3  Edit Control Selection Fields

The selection field is the portion of a combo box that displays the currently selected list item. In simple and drop-down combo boxes, the selection field is an edit control and can be used to enter text that is not in the list.

An application can retrieve or set the contents of the selection field and can determine or set the edit selection. The application can also limit the amount of text a user can type in the selection field. When the contents of the selection field change, Windows sends notification messages to the parent window or dialog box procedure.

To retrieve the contents of the selection field of a simple or drop-down combo box, an application can send the WM_GETTEXT message to the combo box. To set the contents of the selection field, an application can send the WM_SETTEXT message to the combo box.

The edit selection is the range of selected text, if any, in the selection field of a simple or drop-down combo box. An application can determine the starting and ending character positions of the current selection by using the CB_GETEDITSEL message. It can also select characters in the edit selection by using the CB_SETEDITSEL message.

By using the CB_LIMITTEXT message, an application can limit the amount of text a user can type into the selection field.

When the user edits the contents of the selection field, the parent window or dialog box procedure receives notification messages. Windows sends the CBN_EDITUPDATE notification first, indicating that the text in the selection field has been edited. After the altered text is displayed, Windows sends the CBN_EDITCHANGE notification. When the contents of the selection field change as the result of a list item being selected, these notifications are not sent.


  13.1.4  Owner-Drawn Combo Boxes

An application can create an owner-drawn combo box to take responsibility for painting list items. The parent window or dialog box of an owner-drawn combo box (its owner) receives WM_DRAWITEM messages when a portion of the combo box needs to be painted. An owner-drawn combo box can list information other than, or in addition to, text strings. Owner-drawn combo boxes can be of any type. However, the edit control in a simple or drop-down combo box can only display text, while the owner paints the selection field in a drop-down list box.

The owner of an owner-drawn combo box must process the WM_DRAWITEM message. This message is sent whenever a portion of the combo box must be redrawn. The owner may need to process other messages, depending on the styles specified for the combo box.

An application can create an owner-drawn combo box by specifying the CBS_OWNERDRAWFIXED or CBS_OWNERDRAWVARIABLE style. If all list items in the combo box are the same height, such as strings or icons, an application can use the CBS_OWNERDRAWFIXED style. If list items are of varying height, bitmaps of different size, for example, an application can use the CBS_OWNERDRAWVARIABLE style.

The owner of an owner-drawn combo box can process a WM_MEASUREITEM message to specify the dimensions of list items in the combo box. If the application creates the combo box by using the CBS_OWNERDRAWFIXED style, Windows sends the WM_MEASUREITEM message only once. The dimensions specified by the owner are used for all list items. If the CBS_OWNERDRAWVARIABLE style is used, Windows sends a WM_MEASUREITEM message for each list item added to the combo box. The owner can determine or set the height of a list item at any time by using the CB_GETITEMHEIGHT and CB_SETITEMHEIGHT messages, respectively.

If the information displayed in an owner-drawn combo box includes text, an application can keep track of the text for each list item by specifying the CBS_HASSTRINGS style. Combo boxes with the CBS_SORT style are sorted based on this text. If a combo box is sorted and does not have the CBS_HASSTRINGS style, the owner must process the WM_COMPAREITEM message.

In an owner-drawn combo box, the owner must keep track of list items containing information other than or in addition to text. One convenient way to do this is to save the handle of the information as item data. For more information about item data, see Section 13.1.6.2, »Data Associated With List Items«. To free data objects associated with items in a combo box, the owner can process the WM_DELETEITEM message.

For an example of an owner-drawn combo box, see Section 13.2.2, »Creating an Owner-Drawn Combo Box«.


  13.1.5  Subclassing Combo Boxes

Subclassing is a procedure that allows an application to intercept and process messages sent or posted to a window. By using subclassing, an application can substitute its own processing for certain messages, while leaving most message processing to the class-defined window procedure.

When the operating system creates a window, it saves information about it in an internal data structure that includes the address of the window procedure. To subclass a window, an application calls the SetClassLong function to replace the address of that procedure with the instance address of an application-defined subclass procedure. Thereafter, all messages to the window are sent to the subclass procedure. This procedure then uses the CallWindowProc function to pass unprocessed messages to the original window procedure. For a description of the message processing performed by the COMBOBOX class window procedure, see Section 13.1.8, »Default Combo Box Behavior«.

When the combo box is outside a dialog box, an application cannot process the TAB, ENTER, and ESCAPE keys unless it uses a subclass procedure. When a simple or drop-down combo box receives the input focus, it immediately sets the focus to its child edit control. Therefore, an application must subclass the edit control to intercept keyboard input for a simple or drop-down combo box. For an example of this, see Section 13.2.3, »Subclassing a Combo Box«.

If a subclass procedure processes the WM_PAINT message, it must use the BeginPaint function to prepare for painting. Before calling the EndPaint function, it passes the device-context handle as the wParam parameter for the window procedure. If EndPaint is called first, the class window procedure does no painting because EndPaint validates the entire window.

A technique related to subclassing is superclassing. A superclass resembles any other class except that its window procedure does not call DefWindowProc to handle unprocessed messages. Instead, it passes unprocessed messages to the window procedure for the parent window class. Follow the guidelines in Chapter 4, "Window Procedures," to avoid problems that can occur with subclassing and superclassing.


  13.1.6  Special Combo Box Features

The Win32 API provides special-purpose messages and functions that enable an application to display a directory listing in a combo box, associate data with list items in a combo box, and change the keyboard interface for a drop-down combo box or drop-down list box.


  13.1.6.1  Directory Lists

An application can add the names of files or subdirectories to a combo box by sending the CB_DIR message to it. The wParam parameter for the window procedure specifies the attributes of the files to add, and the lParam parameter points to the text string that defines the file specification.

Within a dialog box, an application can also use the DlgDirListComboBox function. If the specified filename includes a drive, path, or both, the DlgDirListComboBox function changes the current drive or directory and removes the drive and path from the filename string. To show the directory name, the function updates the specified static control, if any. It then resets the contents of the combo box, and sends the CB_DIR message to the combo box to add the specified filenames.

To remove the selected filename, directory name, or drive letter from a combo box that has been filled by using the DlgDirListComboBox function, an application can use the DlgDirSelectComboBoxEx function.

The CB_DIR message and the DlgDirListComboBox and DlgDirSelectComboBoxEx functions are similar to the LB_DIR message and the DlgDirList and DlgDirSelectEx functions used with list boxes.


  13.1.6.2  Data Associated With List Items

An application can associate data with the list items in a combo box. The CB_SETITEMDATA message associates a DWORD value with a list item, and the CB_GETITEMDATA retrieves the value associated with a list item.

The example in Section 13.2.2, "Creating an Owner-Drawn Combo Box," uses item data to associate a constant with each item in a drop-down list box. Such a unique value identifies each item independent of its sorted position.

Other applications might use item data to associate a handle or pointer with a list item. If so, an application can process a WM_DELETEITEM message to delete or free the specified object when the list item is deleted.


  13.1.6.3  The Extended User Interface

Drop-down combo boxes and drop-down list boxes support an alternative keyboard interface called the extended user interface. By default, the F4 key opens or closes the list, and the DOWN ARROW changes the current selection. In a combo box with the extended user interface, however, the F4 key is disabled and pressing the DOWN ARROW key opens the drop-down list.

To select the user interface for a combo box, an application can send the CB_SETEXTENDEDUI message to the combo box. A TRUE value for the wParam parameter enables the extended user interface; a FALSE value sets the default user interface. To determine whether a combo box uses the extended user interface, an application can send the CB_GETEXTENDEDUI message to the combo box.


  13.1.7  Combo Box Notifications

Messages from combo boxes are sent as notifications in the form of WM_COMMAND messages. The notification code is stored in the high word of the wParam parameter and an application can process the following combo box notification messages:

Notification code	Description
CBN_CLOSEUP	Indicates the list in a drop-down combo box or drop-down list box is about to close.
CBN_DBLCLK	Indicates the user has double-clicked a list item in a simple combo box.
CBN_DROPDOWN	Indicates the list in a drop-down combo box or drop-down list box is about to open.
CBN_EDITCHANGE	Indicates the user has changed the text in the edit control of a simple or drop-down combo box. This notification is sent after the altered text is displayed.
CBN_EDITUPDATE	Indicates the user has changed the text in the edit control of a simple or drop-down combo box. This notification is sent before the altered text is displayed.
CBN_ERRSPACE	Indicates the combo box cannot allocate enough memory to carry out a request, such as adding a list item.
CBN_KILLFOCUS	Indicates the combo box is about to lose the input focus.
CBN_SELCHANGE	Indicates the current selection has changed.
CBN_SETFOCUS	Indicates the combo box has received the input focus.


  13.1.8  Default Combo Box Behavior

This section describes the messages specifically handled by the predefined COMBOBOX class window procedure.

Message	Description
CB_ADDSTRING	Sends an LB_ADDSTRING message to the list window to add a list item.
CB_DELETESTRING	Sends an LB_DELETESTRING message to the list window to delete a list item.
CB_DIR	Adds the filenames matching the specified attributes and path to the list.
CB_FINDSTRING	Sends an LB_FINDSTRING message to the list window. This message returns the index of the first list item that begins with the specified text.
CB_FINDSTRINGEXACT	Sends an LB_FINDSTRING message to the list window. This message returns the index of the first list item exactly matching the specified text.
CB_GETCOUNT	Sends an LB_GETCOUNT message to the list window. It returns the number of list items.
CB_GETCURSEL	Sends an LB_GETCURSEL message to the list window. It returns the index of the currently selected item, if any.
CB_GETDROPPEDCONTROLRECT	Fills the specified rectangle structure with the screen coordinates of a drop-down list.
CB_GETDROPPEDSTATE	Returns TRUE if a drop-down list is open. Otherwise, it returns FALSE.
CB_GETEDITSEL	Sends an EM_GETSEL message to the edit control, and it returns the starting and ending position of the current selection. In drop-down list boxes, the window procedure returns CB_ERR.
CB_GETEXTENDEDUI	Returns TRUE if the combo box is a drop-down combo box or drop-down list box and the extend user-interface flag is set. Otherwise, it returns FALSE.
CB_GETITEMDATA	Sends an LB_GETITEMDATA message to the list window. It returns the 32-bit value associated with the specified list item.
CB_GETITEMHEIGHT	Sends an LB_GETITEMHEIGHT message to the list window. It returns the height, in pixels, of the specified owner-drawn list item.
CB_GETLBTEXT	Sends an LB_GETTEXT message to the list window. It copies the specified list text to the specified buffer.
CB_GETLBTEXTLEN	Sends an LB_GETTEXTLEN message to the list window. It returns the length, in bytes, of the specified list text.
CB_GETLOCALE	Sends an LB_GETLOCALE message to the list window. It returns the current locale for the list.
CB_INSERTSTRING	Sends an LB_INSERTSTRING message to the list window. It inserts a list item at the specified position.
CB_LIMITTEXT	Sends an EM_LIMITTEXT message to the edit control. It sets the maximum number of characters a user can enter in the edit control. In drop-down list boxes, the window procedure returns CB_ERR.
CB_RESETCONTENT	Sends an LB_RESETCONTENT message to the list window, and it removes the contents of the list.
CB_SELECTSTRING	Sends an LB_SELECTSTRING message to the list window. It selects the first list item, if any, that begins with the characters in the specified text.
CB_SETCURSEL	Sends an LB_SETCURSEL message to the list window, and it sets the current selection.
CB_SETEDITSEL	Sends an EM_SETSEL message to the edit control. It selects the specified range of text. In drop-down list boxes, the window procedure returns CB_ERR.
CB_SETEXTENDEDUI	Sets or clears the extended user interface flag. This flag changes the keys that open and close the list in a drop-down combo box or drop-down list box. if the combo box is a simple combo box, the window procedure returns CB_ERR.
CB_SETITEMDATA	Sends an LB_SETITEMDATA message to the list window. It associates the specified 32-bit value with a list item.
CB_SETITEMHEIGHT	Sends an LB_SETITEMHEIGHT message to the list window. It sets the height of the specified owner-drawn list item or the selection field.
CB_SETLOCALE	Sends an LB_SETLOCALE message to the list window, and it sets the current locale for the list. The locale affects how the list is sorted if it has the CBS_SORT style and strings are added using CB_ADDSTRING.
CB_SHOWDROPDOWN	Shows or hides the drop-down list. This message has no effect on simple combo boxes.
WM_CHAR	Processes character input. In drop-down list boxes, this message is passed on to the list window, which moves the selection to the first item beginning with the specified character. In simple and drop-down combo boxes, this message is passed on to the edit control.
WM_CLEAR	Deletes the edit selection. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.
WM_COMMAND	Processes notification messages from the edit control and list window and sends corresponding combo box notifications to the parent window.
	For edit control notifications, the window procedure may update the list window's current selection, caret index, and top index. For list notifications, the window procedure may update the contents of the selection field.
WM_COMPAREITEM	Passes the message on to the parent window, enabling the application to specify the relative sort position of two owner-drawn list items. The combo box window receives this message from the list window.
WM_COPY	Copies the edit selection to the clipboard. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.
WM_CREATE	Initializes the combo box.
WM_CUT	Deletes the edit selection and places it on the clipboard. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.
WM_DELETEITEM	Passes the message on to the parent window, notifying the application that a list item has been deleted. The combo box window receives this message from the list window.
WM_DRAWITEM	Passes the message on to the parent window enabling the application to paint the specified list item. The combo box window receives this message from the list window. The window procedure can also originate this message to have the application paint the selection field of a drop-down list box.
WM_ENABLE	Sets the state to enable or prohibit mouse and keyboard input.
WM_ERASEBKGND	Returns 1, indicating that the background is erased.
WM_GETDLGCODE	Returns a combination of the DLG_WANTCHARS and DLGC_WANTARROWS values.
WM_GETFONT	Returns the handle of the current font with which the combo box will draw its text.
WM_GETTEXT	Copies the contents of the selection field to the specified buffer. In simple and drop-down combo boxes, the edit control processes this message.
WM_GETTEXTLENGTH	Returns the length, in characters, of the text in the selection field. In simple and drop-down combo boxes, the edit control processes this message.
WM_KEYDOWN	Processes non-character keyboard input. In drop-down list boxes, this message is passed on to the list window, and it can be open or close, or change the current selection or caret index. In simple and drop-down combo boxes, this message is passed on to the edit control. The edit control passes certain keys to the list window, such as the UP and DOWN ARROW keys and the F4 key.
WM_KILLFOCUS	Hides the highlight in the selection field and closes the drop-down list, if necessary. If the window receiving the input focus is part of the combo box (for example, the edit control), this message is ignored.
WM_LBUTTONDBLCLK	Same as WM_LBUTTONDOWN.
WM_LBUTTONDOWN	Sets the focus to the combo box and, for drop-down combo boxes and drop-down lists, can open or close the list. If it opens the list, the window procedure captures the mouse to enable selection by dragging and releasing the mouse button.
WM_LBUTTONUP	Releases the mouse capture if the mouse opened the list.
WM_MEASUREITEM	Posts the message to the parent window, enabling the application to modify the contents of the specified MEASUREITEMSTRUCT structure. The combo box window receives this message from the list window.
WM_MOUSEMOVE	Posts the message to the list window if the mouse has opened the list and the mouse button is still down. This enables a user to select an item by dragging the mouse pointer to a list item and then releasing the button.
WM_NCCREATE	Allocates an internal data structure used by the combo box window procedure.
WM_NCDESTROY	Frees resources allocated in response to the WM_NCCREATE message.
WM_PAINT	Paints the invalid region of the combo box. If wParam is not NULL, it is assumed to be a device context handle passed from a subclass function. The window procedure uses the specified device context instead of calling BeginPaint and EndPaint.
WM_PASTE	Replaces the edit selection with the contents of the clipboard. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.
WM_SETFOCUS	Sets the focus to the edit control or, in drop-down list boxes, inverts the selection field and turns on the caret in the list window.
WM_SETFONT	Saves the specified font handle in an internal structure, adjusts the dimensions of the selection field and list, and invalidates the combo box window. Text in the selection field and the list is displayed in the saved font.
WM_SETREDRAW	Sets or clears the redraw flag. If the redraw flag is cleared, the combo box is not repainted until the flag is set again.
WM_SETTEXT	Sets the contents of the edit control. In simple and drop-down combo boxes, the edit control processes this message. In drop-down list boxes, the window procedure returns CB_ERR.
WM_SIZE	Resizes the child windows, if necessary.
WM_SYSKEYDOWN	Opens or closes the drop-down list depending on which arrow key the user pressed.
All other messages are passed to the DefWindowProc function for default processing.


  13.2  Using Combo Boxes

This section explains how to perform the following tasks:

•	Use a simple combo box in a dialog box.

•	Use an owner-drawn combo box in a dialog box.

•	Subclass a combo box for use outside dialog box.


  13.2.1  Creating a Simple Combo Box

This section describes how to use a simple combo box in a dialog box. The code example in Section 13.2.1.4, »Creating a Spell Dialog Box«, uses a simple combo box in a dialog box for a spelling checker. When it finds a misspelled word, the spelling checker suggests alternative spellings. The user can ignore the misspelling, change to one of the suggested spellings, or type a spelling not suggested. A simple combo box is well suited for receiving this kind of user input.


  13.2.1.1  Creating the Dialog Box

The dialog box template defines the window styles, buttons, and control identifiers for the combo box. In »this example«, the combo box uses the CBS_SIMPLE, CBS_SORT, WS_VSCROLL, and WS_TABSTOP styles.

The dialog box also contains three buttons: Change (IDOK), Ignore (IDSKIP), and Cancel (IDCANCEL). The constants IDOK and IDCANCEL are defined by the Win32 API. The constant IDSKIP is defined in the application's header file, as is the control identifier, IDCOMBO.

For more information about dialog boxes, see Chapter 18, »Dialog Boxes«.


  13.2.1.2  Processing the WM_INITDIALOG and WM_DESTROY Messages

When you use a combo box in a dialog box, you usually respond to the WM_INITDIALOG message by initializing the combo box. The code example in Section 13.2.1.4, "Creating a Spell Dialog Box," calls the application-defined OpenDictionary function to load the dictionary. It then calls the application-defined SelectNextWord and InitSpellList functions to select the first misspelled word.

SelectNextWord selects the next word in the edit control and copies it to the specified buffer. InitSpellList determines whether the selected word is in the dictionary. If not, it places the word in the selection field of the combo box and adds suggested spellings to the list.

The dialog box procedure processes the WM_DESTROY message to free the resources allocated to the spelling dictionary.


  13.2.1.3  Processing the WM_COMMAND Message

When an event occurs in a dialog box control, the control sends a WM_COMMAND message to the dialog box procedure.

For edit controls, the window procedure may update the current selection in the list window. Once the user types something in the edit control, triggering an edit control notification, there is no current selection. The window procedure also sets the top index, specifying the zero-based index of the list item at the top of the window. It may also set the caret index, indicating the index of the highlighted list item when the list window has the input focus.

The code example in Section 13.2.1.4, "Creating a Spell Dialog Box," processes notification messages from the combo box, the Change button, the Ignore button, and the Cancel button. The control identifier is in the low-order word of wParam, and the notification code is in the high-order word of wParam.

The control identifier IDCOMBO signifies that an event occurred in the combo box, although the dialog box procedure ignores all events in it except one. CBN_DBLCLK indicates the user has double-clicked a list item; this event is processed in the same way as a Change button click.

The control identifier IDOK signifies the user clicked the Change button. The dialog box procedure replaces the current selection in the application's edit control with the contents of the selection field in the combo box. The selection field may contain either the selected list item or text the user has typed. The dialog box procedure then selects the next misspelled word in the same way it processes an Ignore button click.

The control identifier IDSKIP signifies the user has clicked the Ignore button. The dialog box procedure calls SelectNextWord and InitSpellList to select the next misspelled word in the application's edit control. InitSpellList places the misspelled word in the selection field of the combo box and adds suggested spellings to the combo box list.

The control identifier IDCANCEL indicates the user clicked the Cancel button. The dialog box procedure calls the EndDialog function to close the dialog box.


  13.2.1.4  Creating a Spell Dialog Box

Following are the dialog box procedure and supporting functions for the spelling checker dialog box.

HWND hwndMain;

HWND hwndEdit;

char achTemp[256];       /* temporary buffer            */

LPSTR lpstrDict;         /* buffer for dictionary file  */

LPSTR *paLpDict;         /* array of pointers to words  */

UINT  cWords;            /* number of words             */

/********************************************************

    FUNCTION: SpellDlgProc

    PURPOSE: Dialog procedure for Spell dialog box.

*********************************************************/

BOOL CALLBACK SpellDlgProc(hwndDlg, msg, wParam, lParam)

HWND hwndDlg;

UINT msg;

WPARAM wParam;

LPARAM lParam;

{

    switch (msg) {

        case WM_INITDIALOG:

            if (!OpenDictionary()) {

                EndDialog(hwndDlg, 0);

                break;

            }

            SendMessage(hwndEdit, EM_SETSEL, 0, 0);

            do

                if (!SelectNextWord(hwndEdit, achTemp)) {

                    GlobalFree((HGLOBAL) lpstrDict);

                    LocalFree((HLOCAL) paLpDict);

                    EndDialog(hwndDlg, 0);

                    break;

                }

            while (!InitSpellList(

                GetDlgItem(hwndDlg, IDCOMBO), achTemp));

            break;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                case IDCOMBO:

                    if (HIWORD(wParam) != CBN_DBLCLK)

                        break;

                    /* For a double-click, process the OK case. */

                case IDOK:

                    SendDlgItemMessage(hwndDlg, IDCOMBO,

                        WM_GETTEXT, sizeof(achTemp),

                        (LPARAM) achTemp);

                    SendMessage(hwndEdit, EM_REPLACESEL, 0,

                        (LPARAM) achTemp);

                    /* Fall through to get the next word. */

                case IDSKIP:

                    do

                        if (!SelectNextWord(hwndEdit, achTemp)) {

                            EndDialog(hwndDlg, 0);

                            break;

                        }

                    while (!InitSpellList(GetDlgItem(hwndDlg,

                        IDCOMBO), achTemp));

                    break;

                case IDCANCEL:

                    EndDialog(hwndDlg, 0);

            }

            break;

        case WM_DESTROY:

            GlobalFree((HGLOBAL) lpstrDict);

            LocalFree((HLOCAL) paLpDict);

            break;

        default:

            return FALSE;

    }

    return TRUE;

}

/********************************************************

    FUNCTION: InitSpellList

    PURPOSE: Initializes the selection field and list

                of suggestions for the specified word, if

                it is not in the dictionary.

    RETURNS: If the list is initialized, the return

                value is TRUE. If an error occurs or the

                word is in the dictionary, the return

                value is FALSE.

*********************************************************/

BOOL PASCAL InitSpellList(HWND hwndCombo, LPSTR lpszWord)

{

    int min = 0;        /* beginning of search range */

    int max = cWords;   /* end of search range       */

    int n;              /* index of word             */

    int cmp;            /* result of comparison      */

    char ch;            /* first character in word   */

    ch = *lpszWord;

    AnsiLowerBuff(&ch, 1);

    /*

     * Perform a binary search for the word.

     *

     * The global array paLpDict contains pointers to words

     * in the global array lpstrDict. These two variables are

     * initialized by the OpenDictionary function.

     */

    n = max / 2;

    while (min < max) {

        cmp = lstrcmpi(lpszWord, paLpDict[n]);

        if (cmp == 0)

            return FALSE;       /* not misspelled */

        if (cmp < 0)

            max = n;

        else

            min = n + 1;

        n = (min + max) / 2;

    }

    /* List the words beginning with the same letter as lpszWord. */

    SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);

    while (n > 0 && *paLpDict[n - 1] == ch)

        n--;

    while (*paLpDict[n] == ch)

        SendMessage(hwndCombo, CB_ADDSTRING,

            0, (LPARAM) paLpDict[n++]);

    /* Place the word in the selection field. */

    SendMessage(hwndCombo, WM_SETTEXT, 0, (LPARAM) lpszWord);

    return TRUE;

}


  13.2.2  Creating an Owner-Drawn Combo Box

This section describes how to use an owner-drawn combo box. The code example in Section 13.2.2.6, "Creating a Square Meal Dialog Box," uses an owner-drawn drop-down list box to display the four food groups, each represented by a bitmap and a name. Selecting a food group causes the foods in that group to appear in a list.


  13.2.2.1  Creating the Dialog Box

The dialog box template defines the window styles, buttons, and control identifiers for the combo box. The combo box in »this example« uses the CBS_DROPDOWNLIST, CBS_OWNERDRAWFIXED, CBS_SORT, CBS_HASSTRINGS, WS_VSCROLL, and WS_TABSTOP styles.

The dialog box also contains a list box (IDLIST) and two buttons: OK (IDOK) and Cancel (IDCANCEL). The constants IDOK and IDCANCEL are defined by the Win32 API. The constant IDLIST is defined in the application's header file, as is the control identifier, IDCOMBO.

For more information about dialog boxes, see Chapter 18, »Dialog Boxes«.


  13.2.2.2  Processing the WM_INITDIALOG and WM_DESTROY Messages

When you use a combo box in a dialog box, you usually respond to a WM_INITDIALOG message by initializing the combo box. The code example in Section 13.2.2.6, "Creating a Square Meal Dialog Box," loads the bitmaps used for the owner-drawn combo box, then calls the application-defined InitGroupList function to initialize the combo box. It also selects the first list item in the combo box, then calls the application-defined InitFoodList function to initialize the list box.

In the example, the owner-drawn combo box is a drop-down list box containing the names of each of the four food groups. InitGroupList adds the name of each food group, and calls SetItemData to associate a constant with each list item that identifies a corresponding food group.

The list box in the example contains the names of foods in the selected food group. InitFoodList resets the contents of the list box, then adds the names of the current food selection in the current food group drop-down list box.

The dialog box procedure processes the WM_DESTROY message to delete the bitmaps in the owner-drawn combo box.


  13.2.2.3  Processing the WM_MEASUREITEM Message

An owner-drawn combo box sends the WM_MEASUREITEM message to its parent window or dialog box procedure so the application can set the dimensions of each list item. Because the example combo box has the CBS_OWNERDRAWFIXED style, the system sends the WM_MEASUREITEM message only once. Combo boxes with the CBS_OWNERDRAWVARIABLE style send a WM_MEASUREITEM message for each list item.

The lParam parameter points to a MEASUREITEMSTRUCT structure that identifies the control and list item. It also contains the default dimensions of the list item. The code example in Section 13.2.2.6, "Creating a Square Meal Dialog Box," modifies the itemHeight structure member to ensure that the list items are high enough to accommodate the food-group bitmaps.


  13.2.2.4  Processing the WM_DRAWITEM Message

An owner-drawn combo box sends the WM_DRAWITEM message to its parent window or dialog box procedure each time the application must repaint a list item. The lParam parameter points to a DRAWITEMSTRUCT structure that identifies the control and list item. It also contains information needed to paint the item.

The code example in Section 13.2.2.6, "Creating a Square Meal Dialog Box," displays the list-item text and the bitmap associated with the food group. If the item has the focus, it also draws a focus rectangle. Before displaying the text, the example sets the foreground and background colors, based on the item selected. Because the combo box has the CBS_HASSTRINGS style, the combo box maintains the text for each list item, that can be retrieved using the CB_GETLBTEXT message.

The bitmaps used for the list item depend on the food group. InitGroupList uses the CB_SETITEMDATA message to associate a constant with each list item, identifying the corresponding food group. The window procedure uses this value, contained in the itemData member of the DRAWITEMSTRUCT structure, to determine which bitmaps to display. The system uses two bitmaps for each food group symbol: a monochrome bitmap with the SRCAND raster operation to erase the irregular region behind the image and a color bitmap with the SRCPAINT raster operation to paint the image.


  13.2.2.5  Processing the WM_COMMAND Message

When an event occurs in a dialog box control, the control notifies the dialog box procedure, by means of a WM_COMMAND message. The code example in Section 13.2.2.6, "Creating a Square Meal Dialog Box," processes notification messages from the combo box, the list box, and the OK button. The control identifier is in the low-order word of wParam, and the notification code is in the high-order word of wParam.

If the control identifier is IDCOMBO, an event has occurred in the combo box. In response, the dialog box procedure ignores all other combo box events except CBN_SELCHANGE, used to indicate that the current selection has changed. The dialog box procedure calls InitFoodList to reset the contents of the list box and to add the names of the current selection in the drop-down list box.

If the control identifier is IDLIST, an event has occurred in the list box. This causes the dialog box procedure to ignore all list box events except LBN_DBLCLK, used to indicate that the user has double-clicked a list item. This event is processed in the same way as an OK button click.

If the control identifier is IDOK, the user has clicked the OK button. In response, the dialog box procedure inserts the name of the selected food into the application's multiline edit control, then calls the EndDialog function to close the dialog box.

If the control identifier is IDCANCEL, the user has clicked the Cancel button. In response, the dialog box procedure calls EndDialog to close the dialog box.


  13.2.2.6  Creating a Square Meal Dialog Box

Following are the dialog box procedure and supporting functions for the Square Meal dialog box.

HWND hwndMain;

HWND hwndEdit;

char achTemp[256];       /* temporary buffer            */

HBITMAP hbmBread;

HBITMAP hbmDairy;

HBITMAP hbmFruit;

HBITMAP hbmMeat;

HBITMAP hbmBreadMask;

HBITMAP hbmDairyMask;

HBITMAP hbmFruitMask;

HBITMAP hbmMeatMask;

/********************************************************

    FUNCTION: FoodDlgProc

    PURPOSE: Dialog procedure for Food dialog box.

*********************************************************/

BOOL CALLBACK FoodDlgProc(hwndDlg, msg, wParam, lParam)

HWND hwndDlg;

UINT msg;

WPARAM wParam;

LPARAM lParam;

{

    LPMEASUREITEMSTRUCT lpmis;

    LPDRAWITEMSTRUCT lpdis;

    HBITMAP hbmIcon;

    HBITMAP hbmMask;

    COLORREF clrBackground;

    COLORREF clrForeground;

    TEXTMETRIC tm;

    HDC hdc;

    HWND hwnd;

    int x;

    int y;

    switch (msg) {

        case WM_INITDIALOG:

            /*

             * Call an application-defined function to load

             * bitmap resources.

             */

            if (!LoadIconBitmaps()) {

                EndDialog(hwndDlg, -1);

                break;

            }

            /* Initialize the drop-down list box. */

            if (!InitGroupList(hwndDlg)) {

                DeleteIconBitmaps();

                EndDialog(hwndDlg, -1);

                break;

            }

            /* Select the first food group. */

            SendDlgItemMessage(hwndDlg, IDCOMBO, CB_SETCURSEL,

                0, 0);

            /* List the foods and select the first food. */

            InitFoodList(hwndDlg);

            SendDlgItemMessage(hwndDlg, IDLIST, LB_SETCURSEL,

                0, 0);

            break;

        case WM_MEASUREITEM:

            lpmis = (LPMEASUREITEMSTRUCT) lParam;

            if (lpmis->itemHeight < CY_BITMAP + 2)

                lpmis->itemHeight = CY_BITMAP + 2;

            break;

        case WM_DRAWITEM:

            lpdis = (LPDRAWITEMSTRUCT) lParam;

            if (lpdis->itemID == -1)            /* empty item */

                break;

            /* Determine the bitmaps used to draw the icon. */

            switch (lpdis->itemData) {

                case ID_BREAD:

                    hbmIcon = hbmBread;

                    hbmMask = hbmBreadMask;

                    break;

                case ID_DAIRY:

                    hbmIcon = hbmDairy;

                    hbmMask = hbmDairyMask;

                    break;

                case ID_FRUIT:

                    hbmIcon = hbmFruit;

                    hbmMask = hbmFruitMask;

                    break;

                default: /* meat */

                    hbmIcon = hbmMeat;

                    hbmMask = hbmMeatMask;

                    break;

            }

            /* The colors depend on whether the item is selected. */

            clrForeground = SetTextColor(lpdis->hDC,

                GetSysColor(lpdis->itemState & ODS_SELECTED ?

                COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));

            clrBackground = SetBkColor(lpdis->hDC,

                GetSysColor(lpdis->itemState & ODS_SELECTED ?

                COLOR_HIGHLIGHT : COLOR_WINDOW));

            /* Calculate the vertical and horizontal position. */

            GetTextMetrics(lpdis->hDC, &tm);

            y = (lpdis->rcItem.bottom + lpdis->rcItem.top -

                tm.tmHeight) / 2;

            x = LOWORD(GetDialogBaseUnits()) / 4;

            /* Get and display the text for the list item. */

            SendMessage(lpdis->hwndItem, CB_GETLBTEXT,

                lpdis->itemID, (LPARAM) (LPCSTR) achTemp);

            ExtTextOut(lpdis->hDC, CX_BITMAP + 2 * x, y,

                ETO_CLIPPED | ETO_OPAQUE, &lpdis->rcItem,

                achTemp, lstrlen(achTemp), NULL);

            /* Restore the previous colors. */

            SetTextColor(lpdis->hDC, clrForeground);

            SetBkColor(lpdis->hDC, clrBackground);

            /* Show the icon. */

            hdc = CreateCompatibleDC(lpdis->hDC);

            if (hdc == NULL)

                break;

            SelectObject(hdc, hbmMask);

            BitBlt(lpdis->hDC, x, lpdis->rcItem.top + 1,

                CX_BITMAP, CY_BITMAP, hdc, 0, 0, SRCAND);

            SelectObject(hdc, hbmIcon);

            BitBlt(lpdis->hDC, x, lpdis->rcItem.top + 1,

                CX_BITMAP, CY_BITMAP, hdc, 0, 0, SRCPAINT);

            DeleteDC(hdc);

            /* If the item has the focus, draw focus rectangle. */

            if (lpdis->itemState & ODS_FOCUS)

                DrawFocusRect(lpdis->hDC, &lpdis->rcItem);

            break;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                case IDCOMBO:

                    if (HIWORD(wParam) == CBN_SELCHANGE) {

                        InitFoodList(hwndDlg);

                        SendDlgItemMessage(hwndDlg, IDLIST,

                            LB_SETCURSEL, 0, 0);

                    }

                    break;

                case IDLIST:

                    if (HIWORD(wParam) != LBN_DBLCLK)

                        break;

                    /* For a double-click, process the OK case. */

                case IDOK:

                    /* Get the text for the selected list item. */

                    hwnd = GetDlgItem(hwndDlg, IDLIST);

                    SendMessage(hwnd, LB_GETTEXT,

                        SendMessage(hwnd, LB_GETCURSEL, 0, 0),

                        (LPARAM) achTemp);

                    /* Insert the text into the edit window. */

                    SendMessage(hwndEdit, EM_REPLACESEL, 0,

                        (LPARAM) achTemp);

                    EndDialog(hwndDlg, 0);

                    break;

                case IDCANCEL:

                    hwnd = GetDlgItem(hwndDlg, IDCOMBO);

                    if (SendMessage(hwnd, CB_GETDROPPEDSTATE,

                            0, 0))

                        SendMessage(hwnd, CB_SHOWDROPDOWN,

                            FALSE, 0);

                    else

                        EndDialog(hwndDlg, 0);

            }

            break;

        case WM_DESTROY:

            /*

             * Call the application-defined function to free

             * bitmap resources.

             */

            DeleteIconBitmaps();

            break;

        default:

            return FALSE;

    }

    return TRUE;

}

/********************************************************

    FUNCTION: InitGroupList

    PURPOSE: Initializes the "food groups" drop-down

                list box.

    COMMENTS: The ID of the food group associated with

                each list item is saved as item data.

*********************************************************/

BOOL PASCAL InitGroupList(HWND hwndDlg)

{

    HWND hwndCombo = GetDlgItem(hwndDlg, IDCOMBO);

    DWORD dwIndex;

    /* Add an item for each food group. */

    LoadString(hinst, ID_BREAD, achTemp, sizeof(achTemp));

    dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,

        (LPARAM) (LPCSTR) achTemp);

    SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_BREAD);

    LoadString(hinst, ID_DAIRY, achTemp, sizeof(achTemp));

    dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,

        (LPARAM) (LPCSTR) achTemp);

    SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_DAIRY);

    LoadString(hinst, ID_FRUIT, achTemp, sizeof(achTemp));

    dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,

        (LPARAM) (LPCSTR) achTemp);

    SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_FRUIT);

    LoadString(hinst, ID_MEAT, achTemp, sizeof(achTemp));

    dwIndex = SendMessage(hwndCombo, CB_ADDSTRING, 0,

        (LPARAM) (LPCSTR) achTemp);

    SendMessage(hwndCombo, CB_SETITEMDATA, dwIndex, ID_MEAT);

    return TRUE;

}

/********************************************************

    FUNCTION: InitFoodList

    PURPOSE: Clears the contents of the food list, and

                adds the names of foods for the current

                food group.

*********************************************************/

void PASCAL InitFoodList(HWND hwndDlg)

{

    HWND hwndCombo = GetDlgItem(hwndDlg, IDCOMBO);

    HWND hwndList = GetDlgItem(hwndDlg, IDLIST);

    UINT idFoodGroup;

    LPSTR lpsz;

    LPSTR lpszEnd;

    /* Determine the current food group. */

    idFoodGroup = SendMessage(

        hwndCombo,

        CB_GETITEMDATA,

        SendMessage(hwndCombo, CB_GETCURSEL, 0, 0),

        0

    );

    /* Clear the list contents. */

    SendMessage(hwndList, LB_RESETCONTENT, 0, 0);

    .

    . /* Add food names for the current food group. */

    .

}


  13.2.3  Subclassing a Combo Box

This section demonstrates how to subclass combo boxes so your application can use them outside a dialog box. The code example in Section 13.2.3.4, »Creating a Tool Bar«, shows the window procedure for a tool bar window containing two combo boxes. By subclassing the edit controls within the combo boxes, the tool bar window intercepts TAB, ENTER, and ESC keys that would otherwise be ignored.

»This illustration« shows the tool bar window:


  13.2.3.1  Processing the WM_CREATE Message

The code example in Section 13.2.3.4, "Creating a Tool Bar," processes the WM_CREATE message to create two combo box controls as child windows. It then subclasses the edit controls (selection fields) in each combo box because they receive the character input for simple and drop-down combo box. The application gets the handle of each edit control by using the ChildWindowFromPoint function.

To subclass the edit controls, the application calls the SetWindowLong function, replacing the address of the class window procedure with the address of the application-defined SubClassProc function. The address of the original window procedure is saved in the global variable lpfnEditWndProc.

The SubClassProc function intercepts TAB, ESC, and ENTER keys and notifies the tool bar window by sending application-defined messages (WM_TAB, WM_ESC, and WM_ENTER). SubClassProc uses the CallWindowProc function to pass most messages to the original window procedure, lpfnEditWndProc.


  13.2.3.2  Processing the WM_SETFOCUS Message

When the tool bar window receives the input focus, it immediately sets the focus to the first combo box in the tool bar. To do so, the code example in Section 13.2.3.4, "Creating a Tool Bar," calls the SetFocus function in response to the WM_SETFOCUS message.


  13.2.3.3  Processing the Application-Defined Messages

In the code example in Section 13.2.3.4, "Creating a Tool Bar," SubClassProc sends application-defined messages to the tool bar window when the user presses the TAB, ESC, or ENTER key in a combo box. The WM_TAB message is sent for the TAB key, the WM_ESC message for the ESC key, and the WM_ENTER message for the ENTER key.

The example processes the WM_TAB message by setting the focus to the next combo box in the tool bar. It processes the WM_ESC message by setting the focus to the main application window.

In response to the WM_ENTER message, the example ensures that the current selection for the combo box is valid and then sets the focus to the main application window. If the combo box contains no current selection, the example uses the CB_FINDSTRINGEXACT message to search for a list item that matches the contents of the selection field. If there is a match, the example sets the current selection; otherwise, it adds a new list item.


  13.2.3.4  Creating a Tool Bar

Following are the window procedure for the tool bar and the subclass procedure for the two combo boxes.

#define WM_TAB (WM_USER)

#define WM_ESC (WM_USER + 1)

#define WM_ENTER (WM_USER + 2)

HWND hwndMain;

HWND hwndEdit;

WNDPROC lpfnEditWndProc; /* original window procedure for */

                         /*   the combo box edit windows  */

int cyToolbar;           /* tool bar window height        */

/********************************************************

    FUNCTION: ToolbarWindowProc

    PURPOSE: Window procedure for the tool bar window

*********************************************************/

LRESULT CALLBACK ToolbarWindowProc(hwnd, msg, wParam, lParam)

HWND hwnd;

UINT msg;

WPARAM wParam;

LPARAM lParam;

{

    static HWND   hwndEdit1;

    static HWND   hwndEdit2;

    static HWND   hwndCombo1;

    static HWND   hwndCombo2;

    .

    .

    .

    FARPROC     lpfnSubClassProc;

    POINT       pt;

    DWORD       dwBaseUnits;

    HWND        hwndCombo;

    DWORD       dwIndex;

    switch (msg) {

        case WM_CREATE:

            /* Create two combo box child windows. */

            dwBaseUnits = GetDialogBaseUnits();

            hwndCombo1 = CreateWindow("COMBOBOX", "",

                CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,

                (6 * LOWORD(dwBaseUnits)) / 4,

                (2 * HIWORD(dwBaseUnits)) / 8,

                (100 * LOWORD(dwBaseUnits)) / 4,

                (50 * HIWORD(dwBaseUnits)) / 8,

                hwnd, NULL, hinst, NULL);

            hwndCombo2 = CreateWindow("COMBOBOX", "",

                CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,

                (112 * LOWORD(dwBaseUnits)) / 4,

                (2 * HIWORD(dwBaseUnits)) / 8,

                (100 * LOWORD(dwBaseUnits)) / 4,

                (50 * HIWORD(dwBaseUnits)) / 8,

                hwnd, NULL, hinst, NULL);

            /* Get the edit window handle for each combo box. */

            pt.x = 1;

            pt.y = 1;

            hwndEdit1 = ChildWindowFromPoint(hwndCombo1, pt);

            hwndEdit2 = ChildWindowFromPoint(hwndCombo2, pt);

            /*

             * Change the window procedure for both edit windows

             * to the subclass procedure.

             */

            lpfnSubClassProc = MakeProcInstance(

                (FARPROC) SubClassProc, hinst);

            lpfnEditWndProc = (WNDPROC) SetWindowLong(hwndEdit1,

                GWL_WNDPROC, (DWORD) lpfnSubClassProc);

            SetWindowLong(hwndEdit2, GWL_WNDPROC,

                (DWORD) lpfnSubClassProc);

            break;

        case WM_SETFOCUS:

            SetFocus(hwndCombo1);

            break;

        case WM_TAB:

            if (GetFocus() == hwndEdit1)

                SetFocus(hwndCombo2);

            else

                SetFocus(hwndCombo1);

            break;

        case WM_ESC:

            hwndCombo = GetFocus() == hwndEdit1 ?

                hwndCombo1 : hwndCombo2;

            /* Clear the current selection. */

            SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) (-1), 0);

            /* Set the focus to the main window. */

            SetFocus(hwndMain);

            break;

        case WM_ENTER:

            hwndCombo = GetFocus() == hwndEdit1 ?

                hwndCombo1 : hwndCombo2;

            SetFocus(hwndMain);

            /* If there is no current selection, set one. */

            if (SendMessage(hwndCombo, CB_GETCURSEL, 0, 0)

                    == CB_ERR) {

                if (SendMessage(hwndCombo, WM_GETTEXT,

                        sizeof(achTemp), (LPARAM) achTemp) == 0)

                    break;      /* empty selection field */

                dwIndex = SendMessage(hwndCombo,

                    CB_FINDSTRINGEXACT, (WPARAM) (-1),

                    (LPARAM) achTemp);

                /* Add the string, if necessary, and select it. */

                if (dwIndex == CB_ERR)

                    dwIndex = SendMessage(hwndCombo, CB_ADDSTRING,

                        0, (LPARAM) achTemp);

                if (dwIndex != CB_ERR)

                    SendMessage(hwndCombo, CB_SETCURSEL,

                        dwIndex, 0);

            }

            break;

            .

            . /* Process additional messages. */

            .

        default:

            return DefWindowProc(hwnd, msg, wParam, lParam);

    }

    return 0;

}

/********************************************************

    FUNCTION: SubClassProc

    PURPOSE: Process TAB and ESCAPE keys, and pass all

                other messages to the class window

                procedure.

*********************************************************/

LRESULT CALLBACK SubClassProc(hwnd, msg, wParam, lParam)

HWND hwnd;

UINT msg;

WPARAM wParam;

LPARAM lParam;

{

    switch (msg) {

        case WM_KEYDOWN:

            switch (wParam) {

                case VK_TAB:

                    SendMessage(hwndToolbar, WM_TAB, 0, 0);

                    return 0;

                case VK_ESCAPE:

                    SendMessage(hwndToolbar, WM_ESC, 0, 0);

                    return 0;

                case VK_RETURN:

                    SendMessage(hwndToolbar, WM_ENTER, 0, 0);

                    return 0;

            }

            break;

        case WM_KEYUP:

        case WM_CHAR:

            switch (wParam) {

                case VK_TAB:

                case VK_ESCAPE:

                case VK_RETURN:

                    return 0;

            }

    }

    /* Call the original window procedure for default processing. */

    return CallWindowProc(lpfnEditWndProc, hwnd,

        msg, wParam, lParam);

}


  13.3  Functions and Messages

Following are the functions and messages used with combo boxes.


  Functions

DlgDirListComboBox
DlgDirSelect
DlgDirSelectComboBox
DlgDirSelectComboBoxEx


  Messages

CB_ADDSTRING
CB_DELETESTRING
CB_DIR
CB_FINDSTRING
CB_FINDSTRINGEXACT
CB_GETCOUNT
CB_GETCURSEL
CB_GETDROPPEDCONTROLRECT
CB_GETDROPPEDSTATE
CB_GETEDITSEL
CB_GETEXTENDEDUI
CB_GETITEMDATA
CB_GETITEMHEIGHT
CB_GETLBTEXT
CB_GETLBTEXTLEN
CB_GETLOCALE
CB_INSERTSTRING
CB_LIMITTEXT
CB_RESETCONTENT
CB_SELECTSTRING
CB_SETCURSEL
CB_SETEDITSEL
CB_SETEXTENDEDUI
CB_SETITEMDATA
CB_SETITEMHEIGHT
CB_SETLOCALE
CB_SHOWDROPDOWN
CBN_CLOSEUP
CBN_DBLCLK
CBN_DROPDOWN
CBN_EDITCHANGE
CBN_EDITUPDATE
CBN_ERRSPACE
CBN_KILLFOCUS
CBN_SELCHANGE
CBN_SETFOCUS
WM_COMPAREITEM
WM_DRAWITEM
WM_MEASUREITEM


14.1  About Scroll Bars
  Chapter 14    Scroll Bars

14.1  About Scroll Bars

A window in an application written for Microsoft® Windows (™)  can display a data object, such as a document or a bitmap, that is larger than the window's client area. When provided with a scroll bar, the user can scroll a data object in the client area to bring into view the portions of the object that extend beyond the borders of the window. Scroll bars should be included in any window sized such that the contents of the client area extend beyond the window's borders.

A scroll bar's orientation determines the direction in which scrolling occurs when the user operates the scroll bar. A horizontal scroll bar enables the user to scroll the contents of a window to the left or right. A vertical scroll bar enables the user to scroll the contents up or down. »This illustration« shows horizontal and vertical scroll bars in Windows Write.


  14.1.1  Parts of a Scroll Bar

A scroll bar consists of a shaded shaft with an arrow button at each end and a scroll box (sometimes called a thumb) between the arrow buttons. »This illustration« shows the parts of a scroll bar.

A scroll bar represents the overall length or width of a data object in a window's client area; the scroll box represents the portion of the object that is visible in the client area. The position of the scroll box changes whenever the user scrolls a data object to display a different portion of it.

The user scrolls the contents of a window by clicking one of the arrow buttons, by clicking the area in the shaded shaft, or by dragging the scroll box. When the user clicks an arrow button, the application scrolls the contents by one unit (typically a single line or column). When the user clicks the shaded areas, the application scrolls the contents by one window. The amount of scrolling that occurs when the user drags the scroll box depends on the distance the user drags the scroll box and on the scrolling range of the scroll bar. For more information about the scrolling range, see Section 14.1.3, »Scroll Box Position and Scrolling Range«.


  14.1.2  Standard Scroll Bars and Scroll Bar Controls

A scroll bar is included in a window either as a standard scroll bar or as a scroll bar control. A standard scroll bar is located in the nonclient area of a window. It is created with the window and displayed when the window is displayed. The sole purpose of a standard scroll bar is to enable the user to generate scrolling requests for viewing the entire contents of the client area. You can include a standard scroll bar in a window by specifying WS_HSCROLL, WS_VSCROLL, or both styles when you create the window. The WS_HSCROLL style creates a horizontal scroll bar positioned at the bottom of the client area. The WS_VSCROLL style creates a vertical scroll bar positioned at the right of the client area. The SM_CXHSCROLL and SM_CYHSCROLL system metric values define the width and height of a standard horizontal scroll bar. The SM_CXVSCROLL and SM_CYVSCROLL values define the width and height of a standard vertical scroll bar.

A scroll bar control is a control window that belongs to the SCROLLBAR window class. A scroll bar control appears and functions like a standard scroll bar, but it is a separate window. As a separate window, a scroll bar control receives direct input focus, indicated by a flashing caret displayed in the scroll box. Unlike a standard scroll bar, a scroll bar control also has a built-in keyboard interface that enables the user to direct scrolling. You can use as many scroll bar controls as needed in a single window. When you create a scroll bar control, you must specify the scroll bar's size and position. However, if a scroll bar control's window can be resized, adjustments to the scroll bar's size must be made whenever the size of the window changes.

The advantage of using a standard scroll bar is that Windows creates the scroll bar and automatically sets its size and position. However, standard scroll bars are sometimes too restrictive. For example, suppose that you want to divide a client area into quadrants and use a separate set of scroll bars to control the contents of each quadrant. You cannot use standard scroll bars, because you can only create one set of scroll bars for a particular window. Use scroll bar controls instead, because you can add as many of them to a window as you want.

Applications can provide scroll bar controls for purposes other than scrolling the contents of a window. For example, the Mouse application in Windows Control Panel provides scroll bar controls making it possible for the user to set the mouse tracking speed and double-click speed. »This illustration« shows the Double-Click Speed scroll bar control in the Mouse application.

A scroll bar control can have a number of styles that serves to control the orientation and position of the scroll bar. You specify the styles that you want when you call the CreateWindowEx function to create a scroll bar control. Some of the styles create a scroll bar control that uses a default width or height. However, you must always specify the x- and y-coordinates and the other dimensions of the scroll bar. Following are the scroll bar control styles.

Style	Description
SBS_BOTTOMALIGN	Positions a horizontal scroll bar at the bottom of the rectangle specified by the x, y, nWidth and nHeight parameters of the CreateWindowEx function. The SBS_HORZ style must also be specified. The scroll bar uses the default height for standard horizontal scroll bars.
SBS_HORZ	Creates a horizontal scroll bar. If neither the SBS_BOTTOMALIGN nor SBS_TOPALIGN style is specified, the scroll bar uses the height, width, and position given in the CreateWindowEx function.
SBS_LEFTALIGN	Positions a vertical scroll bar at the left side of the rectangle specified by the x, y, nWidth and nHeight parameters of the CreateWindowEx function. The SBS_VERT style must also be specified. The scroll bar uses the default width for standard vertical scroll bars.
SBS_RIGHTALIGN	Positions a vertical scroll bar at the right side of the rectangle specified by the x, y, nWidth and nHeight parameters of the CreateWindowEx function. The SBS_VERT style must also be specified. The scroll bar uses the default width for standard vertical scroll bars.
SBS_TOPALIGN	Positions a horizontal scroll bar at the top of the rectangle specified by the x, y, nWidth and nHeight parameters of the CreateWindowEx function. The SBS_HORZ style must also be specified. The scroll bar uses the default height for standard horizontal scroll bars.
SBS_VERT	Creates a vertical scroll bar. If neither the SBS_RIGHTALIGN nor SBS_LEFTALIGN style is specified, the scroll bar uses the height, width, and position given by the CreateWindowEx function.


  14.1.3  Scroll Box Position and Scrolling Range

The position of the scroll box is represented as an integer; it is relative to the left or upper end of the scroll bar, depending on whether the scroll bar is horizontal or vertical. The position must be within the minimum and maximum values of the scrolling range. For example, in a scroll bar with a range of 0 through 100, position 50 is in the middle, with the remaining positions distributed equally along the scroll bar. The initial range depends on the scroll bar. Standard scroll bars have an initial range of 0 through 100; scroll bar controls have an empty range (both minimum and maximum values are zero), unless you supply an explicit range when the control is created. You can change the range at any time by using the SetScrollRange function to set new minimum and maximum values. The GetScrollRange function retrieves the current minimum and maximum values.

You can adjust the scroll range to convenient integers by using the SetScrollRange function. This function makes it easy to translate the scroll box position into a value corresponding to the scrolled data. For example, if an application must display 260 lines of text in a window that can show only 16 lines at a time, the vertical scroll bar range can be set to 1 through 244. If the scroll box is at position 1, the first line will be at the top of the window. If the scroll box is at position 244, the last line (line 260) will be at the bottom of the window. If the SetScrollPos function specifies a position value that is less than the minimum or more than the maximum, the minimum or maximum scrolling range value is used instead.

To establish a useful relationship between the scroll bar range and the data, an application must adjust the range whenever the data or the size of the window changes. The application must, therefore, adjust the scroll bar range when processing WM_SIZE messages.

As the user moves the scroll box in a scroll bar, the scroll bar reports the scroll box position as an integer in the scrolling range. If the position is the minimum value, the scroll box is at the top of a vertical scroll bar or at the left end of a horizontal scroll bar. If the position is the maximum value, the scroll box is at the bottom of a vertical scroll bar or at right end of a horizontal scroll bar.

An application must move the scroll box in a scroll bar. Although the user makes a request for scrolling in a scroll bar, the scroll bar does not update the scroll box position. Instead, it passes the request to the parent window, which must scroll the data and update the scroll box position by using the SetScrollPos function. Because it controls the scroll box movement, the application can move the scroll box in increments that work best for the data being scrolled.


  14.1.4  Scroll Bar Requests

The user makes scrolling requests by clicking various parts of a scroll bar. Windows sends the request to the given window in the form of a WM_HSCROLL or WM_VSCROLL message. A horizontal scroll bar sends the WM_HSCROLL message; a vertical scroll bar sends the WM_VSCROLL message. Each message includes a notification code that corresponds to the user's action, to the handle of the scroll bar (scroll bar controls only), and, in some cases, to the position of the scroll box.

»This illustration« shows the notification codes that the user generates when clicking various parts of a scroll bar.

The scroll bar notification codes specify the action the user takes. An application examines the codes that accompany the WM_HSCROLL and WM_VSCROLL messages and then performs the appropriate scrolling operation. In the following table of notification codes, the user's action is specified for each code, followed by the application's response. In each case, a unit is defined by the application as appropriate for the given data. For example, the typical unit for scrolling text vertically is a line.

Notification code	Action	Response
SB_LINEUP	The user clicks the top scroll arrow.	Decrement of the scroll box position; scrolls toward the top of the data by one unit.
SB_LINEDOWN	The user clicks the bottom scroll arrow.	Increment of the scroll box position; scrolls toward the bottom of the data by one unit.
SB_LINELEFT	The user clicks the left scroll arrow.	Decrement of the scroll box position; scrolls toward the left end of the data by one unit.
SB_LINERIGHT	The user clicks the right scroll arrow.	Increment of the scroll box position; scrolls toward the right end of the data by one unit.
SB_PAGEUP	The user clicks the scroll bar shaft above the scroll box.	Decrement of the scroll box position by the number of data units in the window; scrolls toward the top of the data by the same number of units.
SB_PAGEDOWN	The user clicks the scroll bar shaft below the scroll box.	Increment of the scroll box position by the number of data units in the window; scrolls toward the bottom of the data by the same number of units.
SB_PAGELEFT	The user clicks the scroll bar shaft to the left of the scroll box.	Decrement of the scroll box position by the number of data units in the window; scrolls toward the left end of the data by the same number of units.
SB_PAGERIGHT	The user clicks the scroll bar shaft to the right of the scroll box.	Increment of the scroll box position by the number of data units in the window; scrolls toward the right end of the data by the same number of units.
SB_THUMBPOSITION	The user releases the scroll box after dragging it.	Setting of the scroll box to the position given in the message; scrolls the data by the same number of units the scroll box has moved.
SB_THUMBTRACK	The user drags the scroll box.	Applications that draw data quickly can set the scroll box to the position given in the message and scroll the data by the same number of units the scroll box has moved. Applications that cannot draw data quickly must wait for the SB_THUMBPOSITION code before moving the scroll box and scrolling the data.
SB_ENDSCROLL	The user releases the mouse after holding it on an arrow or in the scrollbar shaft.	No response is needed.
A scroll bar generates the SB_THUMBPOSITION and SB_THUMBTRACK notification codes when the user clicks and drags the scroll box. An application should be programmed to process either the SB_THUMBTRACK or the SB_THUMBPOSITION notification code.

The SB_THUMBPOSITION notification code occurs when the user releases the mouse button after clicking the scroll box. An application that processes this code performs the scrolling operation after the user has dragged the scroll box to the desired position and released the mouse button.

SB_THUMBTRACK notification codes occur as the user drags the scroll box. If an application processes SB_THUMBTRACK messages, it can scroll the contents of a window as the user drags the scroll box. However, a scroll bar can generate many SB_THUMBTRACK notification codes in a short period, so an application should process these codes only if it can quickly repaint the contents of the window.


  14.1.5  Keyboard Interface for a Scroll Bar

A scroll bar control provides a built-in keyboard interface that enables the user to issue scrolling requests by using the keyboard; a standard scroll bar does not. When a scroll bar control has the keyboard focus, it sends WM_HSCROLL and WM_VSCROLL messages to its parent window when the user presses the arrow keys. The notification code is sent with each message corresponding to the arrow key the user has pressed. Following are the arrow keys and their corresponding notification codes.

Arrow key	Notification code
UP	SB_LINEUP or SB_LINELEFT
DOWN	SB_LINEDOWN or SB_LINERIGHT
LEFT	SB_LINEUP or SB_LINELEFT
RIGHT	SB_LINEDOWN or SB_LINERIGHT
PGUP	SB_PAGEUP or SB_PAGELEFT
PGDN	SB_PAGEDOWN or SB_PAGERIGHT
HOME	SB_TOP
END	SB_BOTTOM
Note that the keyboard interface of a scroll bar control sends the SB_TOP and SB_BOTTOM notification codes. The SB_TOP code indicates that the user has reached the top value of the scrolling range. An application scrolls the window contents downward so that the top of the data object is visible. The SB_BOTTOM code indicates that the user has reached the bottom value of the scrolling range. If an application processes the SB_BOTTOM code, it scrolls the window contents upward so that the bottom of the data object is visible.

If you want a keyboard interface for a standard scroll bar, you can create one yourself by processing the WM_KEYDOWN message in your window procedure and then performing the appropriate scrolling action based on the virtual-key code that accompanies the message. For information about how to create a keyboard interface for a scroll bar, see Section 14.2.4, »Creating a Keyboard Interface for a Standard Scroll Bar«.


  14.1.6  Scrolling the Client Area

The simplest way to scroll the contents of a client area is to erase and then redraw it. This is the method an application is likely to use with SB_PAGEUP, SB_PAGEDOWN, SB_TOP, and SB_END commands, which typically require completely new contents.

For some commands, such as SB_LINEUP and SB_LINEDOWN, not all the contents need be erased, since some remain visible after scrolling occurs. The ScrollWindow and ScrollWindowEx functions preserve a portion of the client area's contents, move the preserved portion a specified amount, and then prepare the rest of the client area for painting new information. ScrollWindow and ScrollWindowEx use the BitBlt function to move a specific part of the data object to a new location within the client area. Any uncovered part of the client area (anything not preserved) is invalidated, erased, and painted when the next WM_PAINT message occurs.

The ScrollWindow and ScrollWindowEx functions can be used to exclude a portion of the client area from the scrolling operation. This keeps items with fixed positions, such as child windows, from moving within the client area. It automatically invalidates the portion of the client area that is to receive the new information, so the application does not have to compute its own clipping regions. For more information on clipping, see Chapter 38, »Clipping«.

Usually an application scrolls the contents of a window in the direction opposite that indicated by the scroll bar. For example, when the user clicks the shaft in the area below the scroll box, an application scrolls the object in the window upward to reveal a portion of the object that is below the visible portion.


  14.1.7  Scroll Bar Visibility

The SetScrollRange function hides and disables a standard scroll bar when equal minimum and maximum values are specified. This is the way to temporarily hide a scroll bar when it is not needed for the contents of the client area. There is no need to make scrolling requests through the scroll bar when it is hidden. SetScrollRange enables the scroll bar and shows it again when it sets the minimum and maximum values to unequal values. The ShowScrollBar function can also be used to hide or show a scroll bar. It does not affect the scroll bar's range or scroll box position.

The EnableScrollBar function can be used to disable one or both arrows of a scroll bar. An application displays disabled arrows in gray and does not respond to user input.


  14.1.8  Scroll Bar Colors and Metrics

The system-defined color value, COLOR_SCROLLBAR, controls the color within a scroll bar's shaft. Use the GetSysColor function to determine the color of the shaft and the SetSysColor function to set the color of the shaft. Note, however, that this change of color affects all scroll bars in the system.

You can get the dimensions of the bitmaps that Windows uses in standard scroll bars by calling the GetSystemMetrics function. Following are the system metric values associated with scroll bars.

System metric	Description
SM_CXHSCROLL	Width of arrow bitmap on horizontal scroll bar
SM_CYHSCROLL	Height of arrow bitmap on horizontal scroll bar
SM_CXVSCROLL	Width of arrow bitmap on vertical scroll bar
SM_CYVSCROLL	Height of arrow bitmap on vertical scroll bar
SM_CXHTHUMB	Width of scroll box on horizontal scroll bar
SM_CYVTHUMB	Height of scroll box on vertical scroll bar


  14.2  Using Scroll Bars

This section explains how to perform the following tasks:

•	Create scroll bars

•	Scroll text

•	Scroll a bitmap

•	Create a keyboard interface for a standard scroll bar


  14.2.1  Creating Scroll Bars

When creating an overlapped, pop-up, or child window, you can add standard scroll bars by using the CreateWindowEx function and specifying WS_HSCROLL, WS_VSCROLL, or both styles. Doing this adds a horizontal or vertical scroll bar, or both, to the window. The code in the following example creates a window with standard horizontal and vertical scroll bars.

hwnd = CreateWindowEx(

    0L,                          /* no extended styles        */

    "MyAppClass",                /* window class              */

    "Scroll Bar Application",    /* text for window title bar */

    WS_OVERLAPPEDWINDOW |        /* window styles             */

        WS_HSCROLL |

        WS_VSCROLL,

    CW_USEDEFAULT,             /* default horizontal position */

    CW_USEDEFAULT,             /* default vertical position   */

    CW_USEDEFAULT,             /* default width               */

    CW_USEDEFAULT,             /* default height              */

    (HWND) NULL,         /* no parent for overlapped windows  */

    (HMENU) NULL,        /* window class menu                 */

    hinst,               /* instance owning this window       */

    (LPVOID) NULL        /* pointer not needed                */

);

To process scroll bar messages for these scroll bars, you must include appropriate code in the main window procedure.

When using the CreateWindowEx function to create a window, you can add a scroll bar control by specifying the SCROLLBAR window class. This creates a horizontal or vertical scroll bar, depending on whether SBS_HORZ or SBS_VERT is specified as the window style. The scroll bar size and its position relative to its parent window can also be specified. The following code example creates a horizontal scroll bar control and positions it in the upper-right corner of the window.

hwndScroll = CreateWindowEx(

    0L,                          /* no extended styles        */

    "SCROLLBAR",                 /* scroll bar control class  */

    (LPSTR) NULL,                /* text for window title bar */

    WS_CHILD | SBS_HORZ,         /* scroll bar styles         */

    0,                           /* horizontal position       */

    0,                           /* vertical position         */

    200,                         /* width of the scroll bar   */

    CW_USEDEFAULT,               /* default height            */

    hwnd,                   /* handle of main window          */

    (HMENU) NULL,           /* no menu for a scroll bar       */

    hinst,                  /* instance owning this window    */

    (LPVOID) NULL           /* pointer not needed             */

);


  14.2.2  Scrolling Text

This section describes the changes you can make to an application's main window procedure to enable a user to scroll text. The example in Section 14.2.2.5, "Example of Scrolling Text," creates and displays an array of text strings and processes WM_HSCROLL and WM_VSCROLL messages generated by the scroll bars so that the user can scroll text both vertically and horizontally.


  14.2.2.1  Processing the WM_CREATE Message

Scrolling units are typically set while processing the WM_CREATE message. It is convenient to base the scrolling units on the dimensions of the font associated with the window's display context. To retrieve the font dimensions for a specific display context, use the GetTextMetrics function.

In the example in Section 14.2.2.5, "Example of Scrolling Text," one vertical scrolling unit is equivalent to the height of a character cell, plus external leading. One horizontal scrolling unit is equivalent to the average width of a character cell. The horizontal scrolling positions, therefore, do not correspond to actual characters, unless the screen font is fixed-width.


  14.2.2.2  Processing the WM_SIZE Message

When processing the WM_SIZE message, it is convenient to adjust the scrolling range and scrolling position to reflect the dimensions of the client area as well as the number of lines of text that will be displayed.

The SetScrollRange function sets the minimum and maximum position values for a scroll bar. The SetScrollPos function adjusts the scroll box to reflect the scrolling position.


  14.2.2.3  Processing the WM_HSCROLL and WM_VSCROLL Messages

The scroll bar sends WM_HSCROLL and WM_VSCROLL messages to the window procedure whenever the user clicks the scroll bar or drags the scroll box. The low-order words of WM_VSCROLL and WM_HSCROLL each contain a notification code that indicates the direction and magnitude of the scrolling action.

When the WM_HSCROLL and WM_VSCROLL messages are processed, the scroll bar notification code is examined and the scrolling increment is calculated. After the increment is applied to the current scrolling position, the window is scrolled to the new position by using the ScrollWindow function, and the position of the scroll box is adjusted by using the SetScrollPos function.

After a window is scrolled, part of its client area is made invalid. To ensure that the invalid region is updated, the UpdateWindow function is used to generate a WM_PAINT message.


  14.2.2.4  Processing the WM_PAINT Message

When processing the WM_PAINT message, it is convenient to draw the lines of text that you want to appear in the invalid portion of the window. The example code uses the current scrolling position and the dimensions of the invalid region to determine the range of lines within the invalid region to display them.


  14.2.2.5  Example of Scrolling Text

The following example shows how to have your application scroll text in response to input from the horizontal and vertical scroll bars.

HDC hdc;

PAINTSTRUCT ps;

TEXTMETRIC tm;

/* These variables are required to display text. */

static int xClient;     /* width of client area                  */

static int yClient;     /* height of client area                 */

static int xClientMax;  /* maximum width of client area          */

static int xChar;       /* horizontal scrolling unit             */

static int yChar;       /* vertical scrolling unit               */

static int xUpper;      /* average width of uppercase letters    */

static int xPos;        /* current horizontal scrolling position */

static int yPos;        /* current vertical scrolling position   */

static int xMax;        /* maximum horiz. scrolling position     */

static int yMax;        /* maximum vert. scrolling position      */

int xInc;               /* horizontal scrolling increment        */

int yInc;               /* vertical scrolling increment          */

int i;                  /* loop counter                          */

int x, y;               /* horiz. and vert. printing coords      */

int FirstLine;          /* first line in the invalidated area    */

int LastLine;           /* last line in the invalidated area     */

/* Create an array of lines to display. */

#define LINES 27

static char *abc[] = { "anteater", "bear", "cougar", "dingo",

  "elephant", "frog", "gazelle", "hyena", "iguana", "jackal",

  "kangaroo", "llama", "moose", "newt", "octopus", "penguin",

  "quail", "rat", "squid", "tortoise", "urus", "vole",

  "walrus", "xylophone", "yak", "zebra",

  "This line contains many words, but no character. Go figure." };

switch (uMsg) {

    case WM_CREATE :

        /* Get the handle of the client area's device context. */

        hdc = GetDC (hwnd);

        /* Extract font dimensions from the text metrics. */

        GetTextMetrics (hdc, &tm);

        xChar = tm.tmAveCharWidth;

        xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;

        yChar = tm.tmHeight + tm.tmExternalLeading;

        /* Free the device context. */

        ReleaseDC (hwnd, hdc);

        /*

         * Set an arbitrary maximum width for client area.

         * (xClientMax is the sum of the widths of 48 average

         * lowercase letters and 12 uppercase letters.)

         */

        xClientMax = 48 * xChar + 12 * xUpper;

        return 0;

    case WM_SIZE:

        /* Retrieve the dimensions of the client area. */

        yClient = HIWORD (lParam);

        xClient = LOWORD (lParam);

        /*

         * Determine the maximum vertical scrolling position.

         * The two is added for extra space below the lines

         * of text.

         */

        yMax = max (0, LINES + 2 - yClient/yChar);

        /*

         * Make sure the current vertical scrolling position

         * does not exceed the maximum.

         */

        yPos = min (yPos, yMax);

        /*

         * Adjust the vertical scrolling range and scroll box

         * position to reflect the new yMax and yPos values.

         */

        SetScrollRange (hwnd, SB_VERT, 0, yMax, TRUE);

        SetScrollPos (hwnd, SB_VERT, yPos, TRUE);

        /*

         * Determine the maximum horizontal scrolling position.

         * The two is added for extra space to the right of the

         * lines of text.

         */

        xMax = max (0, 2 + (xClientMax - xClient)/xChar);

        /*

         * Make sure the current horizontal scrolling position

         * does not exceed the maximum.

         */

        xPos = min (xPos, xMax);

        /*

         * Adjust the horizontal scrolling range and scroll box

         * position to reflect the new xMax and xPos values.

         */

        SetScrollRange (hwnd, SB_HORZ, 0, xMax, TRUE);

        SetScrollPos (hwnd, SB_HORZ, xPos, TRUE);

        return 0;

    case WM_PAINT:

        /* Prepare the window for painting. */

        hdc = BeginPaint(hwnd, &ps);

        /*

         * Use the current vertical scrolling position and

         * coordinates of the invalid rectangle to determine

         * the range of new lines that should be drawn in the

         * client area.

         */

        FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);

        LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);

        /* Display these lines. */

        for (i = FirstLine;i < LastLine;i++) {

            x = xChar * (1 - xPos);

            y = yChar * (1 - yPos + i);

            TextOut (hdc, x, y, abc[i], lstrlen(abc[i]));

            }

        /* Indicate that painting is finished. */

        EndPaint(hwnd, &ps);

        break;

    case WM_HSCROLL:

        switch(LOWORD (wParam)) {

            /* User clicked shaft left of the scroll box. */

            case SB_PAGEUP:

                 xInc = -8;

                 break;

            /* User clicked shaft right of the scroll box. */

            case SB_PAGEDOWN:

                 xInc = 8;

                 break;

            /* User clicked the left arrow. */

            case SB_LINEUP:

                 xInc = -1;

                 break;

            /* User clicked the right arrow. */

            case SB_LINEDOWN:

                 xInc = 1;

                 break;

            /* User dragged the scroll box. */

            case SB_THUMBTRACK:

                 xInc = HIWORD(wParam) - xPos;

                 break;

            default:

                 xInc = 0;

        }

        /*

         * If applying the horizontal scrolling increment does not

         * take the scrolling position out of the scrolling range,

         * increment the scrolling position, adjust the position

         * of the scroll box, and update the window.

         */

        if (xInc = max (-xPos, min (xInc, xMax - xPos))) {

            xPos += xInc;

            ScrollWindow (hwnd, -xChar * xInc, 0,

                (CONST RECT *) NULL, (CONST RECT *) NULL);

            SetScrollPos (hwnd, SB_HORZ, xPos, TRUE);

            UpdateWindow (hwnd);

        }

        return 0;

    case WM_VSCROLL:

            switch(LOWORD (wParam)) {

            /* User clicked the shaft above the scroll box. */

            case SB_PAGEUP:

                 yInc = min(-1, -yClient / yChar);

                 break;

            /* User clicked the shaft below the scroll box. */

            case SB_PAGEDOWN:

                 yInc = max(1, yClient / yChar);

                 break;

            /* User clicked the top arrow. */

            case SB_LINEUP:

                 yInc = -1;

                 break;

            /* User clicked the bottom arrow. */

            case SB_LINEDOWN:

                 yInc = 1;

                 break;

            /* User dragged the scroll box. */

            case SB_THUMBTRACK:

                 yInc = HIWORD(wParam) - yPos;

                 break;

            default:

                 yInc = 0;

        }

        /*

         * If applying the vertical scrolling increment does not

         * take the scrolling position out of the scrolling range,

         * increment the scrolling position, adjust the position

         * of the scroll box, and update the window. UpdateWindow

         * sends the WM_PAINT message.

         */

        if (yInc = max(-yPos, min(yInc, yMax - yPos))) {

            yPos += yInc;

            ScrollWindow(hwnd, 0, -yChar * yInc,

                (CONST RECT *) NULL, (CONST RECT *) NULL);

            SetScrollPos(hwnd, SB_VERT, yPos, TRUE);

            UpdateWindow(hwnd);

        }

        return 0;


  14.2.3  Scrolling a Bitmap

This section describes changes you can make to an application's main window procedure to enable the user to scroll a bitmap. The example in Section 14.2.3.5, "Example of Scrolling a Bitmap," includes a menu item that copies the screen contents to a bitmap and displays the bitmap in the client area.

The example also processes the WM_HSCROLL and WM_VSCROLL messages generated by the scroll bars so that the user may scroll the bitmap horizontally and vertically. Unlike the example for scrolled text, the bitmap example employs the BitBlt function to draw the invalid portion of the client area.


  14.2.3.1  Processing the WM_CREATE Message

When the WM_CREATE message is processed, the variables required for scrolling are initialized. Then the CreateCompatibleDC function is used to create a compatible device context (DC), the CreateBitmap function is used to create a bitmap, and the SelectObject function is used to select the bitmap for the device context. Note that a compatible DC is also known as a memory DC.

The device-specific information about the display device is retrieved. If a compatible DC is created for the screen, as in the example, the GetDeviceCaps function can be used to get this information. The information includes the number of adjacent color bits per pixel, the number of color planes, and the height and width of the DC.


  14.2.3.2  Processing the WM_SIZE Message

Processing of the WM_SIZE message requires adjusting the scrolling range and position, so it reflects the dimensions of the client area and the bitmap that will be displayed.

The SetScrollRange function sets the minimum and maximum position values for a scroll bar. The SetScrollPos function adjusts the scroll box to reflect the scrolling position.


  14.2.3.3  Processing the WM_HSCROLL and WM_VSCROLL Messages

When the WM_HSCROLL and WM_VSCROLL messages are processed, the scroll bar notification code is examined and the scrolling position is set to a new value that reflects the scrolling action of the user. If the scrolling position is within the scrolling range, the window is scrolled to the new position by using the ScrollWindow function. The position of the scroll box is then adjusted by using the SetScrollPos function.

After a window is scrolled, part of its client area is made invalid. To ensure that the invalid region is updated, the UpdateWindow function is used to generate a WM_PAINT message.

»This illustration« shows the client area before the ScrollWindow function is called.

»This illustration« shows the same client area after the operating system has processed the ScrollWindow function.

When processing the WM_PAINT message, an application must repaint the invalid region at the bottom of the client area.


  14.2.3.4  Processing the WM_PAINT Message

When scrolling or resizing the client area, the example uses the BitBlt function to copy the appropriate portion of the bitmap to the invalid portion of the client area.

»This illustration« shows the client area after the application has processed the WM_PAINT message and called the BitBlt function to repaint the invalid region.


  14.2.3.5  Example of Scrolling a Bitmap

The following example enables the user to capture the screen contents into a bitmap and scroll the bitmap in the client area.

HDC hdc;

PAINTSTRUCT ps;

/* These variables are required by BitBlt. */

static HDC hdcWin;           /* window DC                       */

static HDC hdcScreen;        /* DC for entire screen            */

static HDC hdcScreenCompat;  /* memory DC for screen            */

static HBITMAP hbmpCompat;   /* bitmap handle for old DC        */

static BITMAP bmp;           /* bitmap data structure           */

static BOOL fBlt;            /* TRUE if BitBlt occurred         */

static BOOL fScroll;         /* TRUE if scrolling occurred      */

static BOOL fSize;           /* TRUE if fBlt & WM_SIZE          */

/* These variables are required for horizontal scrolling. */

static int xMinScroll;       /* minimum horizontal scroll value */

static int xCurrentScroll;   /* current horizontal scroll value */

static int xMaxScroll;       /* maximum horizontal scroll value */

/* These variables are required for vertical scrolling. */

static int yMinScroll;       /* minimum vertical scroll value   */

static int yCurrentScroll;   /* current vertical scroll value   */

static int yMaxScroll;       /* maximum vertical scroll value   */

switch (uMsg) {

    case WM_CREATE:

        /*

         * Create a normal DC and a memory DC for the entire

         * screen. The normal DC provides a snapshot of the

         * screen contents. The memory DC keeps a copy of this

         * snapshot in the associated bitmap.

         */

        hdcScreen = CreateDC("DISPLAY", (LPCSTR) NULL,

            (LPCSTR) NULL, (CONST DEVMODE *) NULL);

        hdcScreenCompat = CreateCompatibleDC(hdcScreen);

        /*

         * Retrieve the metrics for the bitmap associated with the

         * regular device context.

         */

        bmp.bmBitsPixel =

            (BYTE) GetDeviceCaps(hdcScreen, BITSPIXEL);

        bmp.bmPlanes = (BYTE) GetDeviceCaps(hdcScreen, PLANES);

        bmp.bmWidth = GetDeviceCaps(hdcScreen, HORZRES);

        bmp.bmHeight = GetDeviceCaps(hdcScreen, VERTRES);

        /* The width must be byte-aligned. */

        bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8;

        /* Create a bitmap for the compatible DC. */

        hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight,

            bmp.bmPlanes, bmp.bmBitsPixel, (CONST VOID *) NULL);

        /* Select the bitmap for the compatible DC. */

        SelectObject(hdcScreenCompat, hbmpCompat);

        /* Initialize the flags. */

        fBlt = FALSE;

        fScroll = FALSE;

        fSize = FALSE;

        /* Initialize the horizontal scrolling variables. */

        xMinScroll = 0;

        xCurrentScroll = 0;

        xMaxScroll = 0;

        /* Initialize the vertical scrolling variables. */

        yMinScroll = 0;

        yCurrentScroll = 0;

        yMaxScroll = 0;

        break;

    case WM_SIZE: {

        int xNewSize;

        int yNewSize;

        xNewSize = LOWORD(lParam);

        yNewSize = HIWORD(lParam);

        if (fBlt)

            fSize = TRUE;

        /*

         * The horizontal scrolling range is defined by

         * (bitmap_width) - (client_width).

         */

        xMaxScroll = max(bmp.bmWidth-xNewSize, 0);

        SetScrollRange(hwnd, SB_HORZ, xMinScroll, xMaxScroll,

            FALSE);

        /*

         * The current horizontal scroll value remains within the

         * horizontal scrolling range.

         */

        xCurrentScroll = min(xCurrentScroll, xMaxScroll);

        SetScrollPos(hwnd, SB_HORZ, xCurrentScroll, TRUE);

        /*

         * The vertical scrolling range is defined by

         * (bitmap_height) - (client_height).

         */

        yMaxScroll = max(bmp.bmHeight - yNewSize, 0);

        SetScrollRange(hwnd, SB_VERT,

            yMinScroll, yMaxScroll, FALSE);

        /*

         * The current vertical scroll value remains within the

         * vertical scrolling range.

         */

        yCurrentScroll = min(yCurrentScroll, yMaxScroll);

        SetScrollPos(hwnd, SB_VERT, yCurrentScroll, TRUE);

    }

        break;

    case WM_PAINT: {

        PRECT prect;

        hdc = BeginPaint(hwnd, &ps);

        /*

         * If the window has been resized and the user has

         * captured the screen, use the following call to

         * BitBlt to paint the window's client area.

         */

        if (fSize) {

            BitBlt(ps.hdc,

                0, 0,

                bmp.bmWidth, bmp.bmHeight,

                hdcScreenCompat,

                xCurrentScroll, yCurrentScroll,

                SRCCOPY);

            fSize = FALSE;

        }

        /*

         * If scrolling has occurred, use the following call to

         * BitBlt to paint the invalid rectangle.

         *

         * The coordinates of this rectangle are specified in the

         * RECT structure to which prect points.

         *

         * Note that it is necessary to increment the seventh

         * argument (prect->left) by xCurrentScroll and the

         * eighth argument (prect->top) by yCurrentScroll in

         * order to map the correct pixels from the source bitmap.

         */

        if (fScroll) {

            prect = &ps.rcPaint;

            BitBlt(ps.hdc,

                prect->left, prect->top,

                (prect->right - prect->left),

                (prect->bottom - prect->top),

                hdcScreenCompat,

                prect->left + xCurrentScroll,

                prect->top + yCurrentScroll,

                SRCCOPY);

            fScroll = FALSE;

        }

        EndPaint(hwnd, &ps);

    }

        break;

    case WM_HSCROLL: {

        int xDelta;     /* xDelta = new_pos - current_pos */

        int xNewPos;    /* new position */

        int yDelta = 0;

        switch (LOWORD(wParam)) {

            /* User clicked the shaft left of the scroll box. */

            case SB_PAGEUP:

                xNewPos = xCurrentScroll - 50;

                break;

            /* User clicked the shaft right of the scroll box. */

            case SB_PAGEDOWN:

                xNewPos = xCurrentScroll + 50;

                break;

            /* User clicked the left arrow. */

            case SB_LINEUP:

                xNewPos = xCurrentScroll - 5;

                break;

            /* User clicked the right arrow. */

            case SB_LINEDOWN:

                xNewPos = xCurrentScroll + 5;

                break;

            /* User dragged the scroll box. */

            case SB_THUMBPOSITION:

                xNewPos = HIWORD(wParam);

                break;

            default:

                xNewPos = xCurrentScroll;

        }

        /* New position must be between 0 and the screen width. */

        xNewPos = max(0, xNewPos);

        xNewPos = min(xMaxScroll, xNewPos);

        /* If the current position does not change, do not scroll.*/

        if (xNewPos == xCurrentScroll)

            break;

        /* Set the scroll flag to TRUE. */

        fScroll = TRUE;

        /* Determine the amount scrolled (in pixels). */

        xDelta = xNewPos - xCurrentScroll;

        /* Reset the current scroll position. */

        xCurrentScroll = xNewPos;

        /*

         * Scroll the window. (The system repaints most of the

         * client area when ScrollWindow is called; however, it is

         * necessary to call UpdateWindow in order to repaint the

         * rectangle of pixels that were invalidated.)

         */

        ScrollWindow(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,

            (CONST RECT *) NULL);

        UpdateWindow(hwnd);

        /* Reset the scroll bar. */

        SetScrollPos(hwnd, SB_HORZ, xCurrentScroll, TRUE);

    }

        break;

    case WM_VSCROLL: {

        int xDelta = 0;

        int yDelta;     /* yDelta = new_pos - current_pos */

        int yNewPos;    /* new position */

        switch (LOWORD(wParam)) {

            /* User clicked the shaft above the scroll box. */

            case SB_PAGEUP:

                yNewPos = yCurrentScroll - 50;

                break;

            /* User clicked the shaft below the scroll box. */

            case SB_PAGEDOWN:

                yNewPos = yCurrentScroll + 50;

                break;

            /* User clicked the top arrow. */

            case SB_LINEUP:

                yNewPos = yCurrentScroll - 5;

                break;

            /* User clicked the bottom arrow. */

            case SB_LINEDOWN:

                yNewPos = yCurrentScroll + 5;

                break;

            /* User dragged the scroll box. */

            case SB_THUMBPOSITION:

                yNewPos = HIWORD(wParam);

                break;

            default:

                yNewPos = yCurrentScroll;

        }

        /* New position must be between 0 and the screen height. */

        yNewPos = max(0, yNewPos);

        yNewPos = min(yMaxScroll, yNewPos);

        /* If the current position does not change, do not scroll.*/

        if (yNewPos == yCurrentScroll)

            break;

        /* Set the scroll flag to TRUE. */

        fScroll = TRUE;

        /* Determine the amount scrolled (in pixels). */

        yDelta = yNewPos - yCurrentScroll;

        /* Reset the current scroll position. */

        yCurrentScroll = yNewPos;

        /*

         * Scroll the window. (The system repaints most of the

         * client area when ScrollWindow is called; however, it is

         * necessary to call UpdateWindow in order to repaint the

         * rectangle of pixels that were invalidated.)

         */

        ScrollWindow(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,

            (CONST RECT *) NULL);

        UpdateWindow(hwnd);

        /* Reset the scroll bar. */

        SetScrollPos(hwnd, SB_VERT, yCurrentScroll, TRUE);

    }

        break;

    case WM_COMMAND: /* uMsg: command from app. menu */

        switch(wParam) {

            case IDM_STC:

                /*

                 * Copy the contents of the current screen

                 * into the compatible DC.

                 */

                BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth,

                    bmp.bmHeight, hdcScreen, 0, 0, SRCCOPY);

                /*

                 * Copy the compatible DC to the client area.

                 */

                hdcWin = GetDC(hwnd);

                BitBlt(hdcWin, 0, 0, bmp.bmWidth, bmp.bmHeight,

                    hdcScreenCompat, 0, 0, SRCCOPY);

                ReleaseDC(hwnd, hdcWin);

                fBlt = TRUE;

                break;

            default:

                return (DefWindowProc(hwnd, uMsg,

                    wParam, lParam));

        }

        break;


  14.2.4  Creating a Keyboard Interface for a Standard Scroll Bar

Although a scroll bar control provides a built-in keyboard interface, a standard scroll bar does not. To implement a keyboard interface for a standard scroll bar, a window procedure must process the WM_KEYDOWN message and examine the virtual-key code specified by the wParam parameter. If the virtual-key code corresponds to an arrow key, the window procedure sends itself a WM_HSCROLL or WM_VSCROLL message with the wParam parameter set to the appropriate scroll bar notification code. For example, when the user presses the UP ARROW key, the window procedure receives a WM_KEYDOWN message with wParam equal to VK_UP. In response, the window procedure sends itself a WM_VSCROLL message with the low-order word of wParam set to the SB_LINEUP notification code.

The following example shows how to include a keyboard interface for a standard scroll bar.

WORD wScrollNotify = 0xFFFF;

.

.

.

case WM_KEYDOWN:

    switch (wParam) {

        case VK_UP:

            wScrollNotify = SB_LINEUP;

            break;

        case VK_PRIOR:

            wScrollNotify = SB_PAGEUP;

            break;

        case VK_NEXT:

            wScrollNotify = SB_PAGEDOWN;

            break;

        case VK_DOWN:

            wScrollNotify = SB_LINEDOWN;

            break;

        case VK_HOME:

            wScrollNotify = SB_TOP;

            break;

        case VK_END:

            wScrollNotify = SB_BOTTOM;

            break;

    }

    if (wScrollNotify != -1)

        SendMessage(hwnd, WM_VSCROLL,

            MAKELONG(wScrollNotify, 0), 0L);

    break;

.

.

.


  14.3  Functions and Messages

Following are the functions and messages used with scroll bars.


  Functions

EnableScrollBar
ScrollWindowEx
GetScrollPos
SetScrollPos
GetScrollRange
SetScrollRange
ScrollDC
ShowScrollBar
ScrollWindow


  Messages

SBM_ENABLE_ARROWS
SBM_GETPOS
SBM_GETRANGE
SBM_SETPOS
SBM_SETRANGE
SBM_SETRANGEREDRAW
WM_CTLCOLORSCROLLBAR
WM_HSCROLL
WM_VSCROLL


15.1  About Static Controls
  Chapter 15    Static Controls

15.1  About Static Controls

Microsoft® Windows (™)  provides dialog boxes and controls to support communications between an application and the user. A static control is a control that enables an application to provide the user with certain types of text and graphics that require no response. Applications often use static controls to label other controls or to separate a group of controls. Although static controls are child windows, they cannot be selected. Therefore, they cannot receive the keyboard focus, cannot have a keyboard interface, and cannot receive user input. A static control does not send messages to its parent window. Static controls belong to the STATIC window class.

Although static controls can be used in overlapped, pop-up, and child windows, they are designed for use in dialog boxes, where Windows standardizes their behavior. If a developer uses static controls outside dialog boxes, it increases the risk that the application might behave in a nonstandard fashion. Typically, developers either use static controls in dialog boxes or use window subclassing to create customized static controls.

For more information about dialog boxes, see Chapter 18, »Dialog Boxes«. For more information about window classes, see Chapter 3, »Window Classes«. For more information about window subclassing, see Chapter 4, »Window Procedures«.


  15.1.1  Static Control Types and Styles

Windows provides four types of static controls: rectangle, frame, text, and icon. Each type has one or more styles.


  15.1.1.1  Rectangle

A rectangle static control displays a rectangle filled with color in one of three styles: black, gray, or white. These styles are defined by the constants SS_BLACKRECT, SS_GRAYRECT, and SS_WHITERECT. The following figure shows the three rectangle styles. For clarity, »this illustration« shows the white rectangle on a black background; the actual display does not contain a black rectangle.


  15.1.1.2  Frame

A frame static control displays a colored frame in one of three styles: black, gray, or white. These styles are defined by the constants SS_BLACKFRAME, SS_GRAYFRAME, and SS_WHITEFRAME. The following figure shows the three frame styles. For clarity, »this illustration« shows the white frame on a black background; the actual display does not contain a black rectangle.


  15.1.1.3  Text

A text static control displays text in a rectangle in one of five styles: centered, left aligned with word wrap, left aligned without word wrap, right aligned, or "simple." These styles are defined by the constants SS_CENTER, SS_LEFT, SS_LEFTNOWORDWRAP, SS_RIGHT, and SS_SIMPLE, respectively. Windows rearranges the text in these controls in predefined ways, except for "simple" text, which is not rearranged. The following figure shows three text styles: centered, left aligned, and right aligned. For clarity, »this illustration« shows the text inside a box; the actual display does not contain a box.

An application can change the text in a text static control at any time by using the SetWindowText function or the WM_SETTEXT message.

The system displays as much text as it can in the static control and clips whatever does not fit. Retrieve the font metrics for the text to calculate an appropriate size for the control. For more information about fonts and font metrics, see Chapter 35, »Fonts and Text«.


  15.1.1.4  Icon

An icon static control displays an icon in an icon control. There is one icon style, defined by the constant SS_ICON. An application can use this type of control only in dialog boxes. An icon is also the only type of static control that can receive messages from its parent window. »This illustration« shows a sample icon.


  15.1.1.5  Static Control Styles

Many developers develop dialog boxes by using stand-alone tools and so may not need to specify static control styles. However, if a developer uses the CreateWindow or CreateWindowEx function to create a static control for an application, the developer must use the following constants to define the style.

Style	Description
SS_BLACKFRAME	Specifies a box with a frame drawn in the same color as the window frames. This color is black in the default Windows color scheme.
SS_BLACKRECT	Specifies a rectangle filled with the current window frame color. This color is black in the default Windows color scheme.
SS_CENTER	Specifies a simple rectangle and centers the given text in the rectangle. The text is formatted before it is displayed. Words that extend past the end of a line are automatically wrapped to the beginning of the next centered line.
SS_GRAYFRAME	Specifies a box with a frame drawn with the same color as the screen background (desktop). This color is gray in the default Windows color scheme.
SS_GRAYRECT	Specifies a rectangle filled with the current screen background color. This color is gray in the default Windows color scheme.
SS_ICON	Specifies an icon displayed in the dialog box. The given text is the name of an icon (not a filename) defined elsewhere in the resource file. The style ignores the nWidth and nHeight parameters; the icon automatically sizes itself.
SS_LEFT	Specifies a simple rectangle and left-aligns the given text in the rectangle. The text is formatted before it is displayed. Words that extend past the end of a line are automatically wrapped to the beginning of the next left-aligned line.
SS_LEFTNOWORDWRAP	Specifies a simple rectangle and left-aligns the given text in the rectangle. Tabs are expanded but words are not wrapped. Text that extends past the end of a line is clipped.
SS_NOPREFIX	Prevents interpretation of any ampersand (&) characters in the control's text as accelerator prefix characters. These are displayed with the ampersand removed and the next character in the string underlined. This static control style may be included with any of the defined static controls.
	An application can combine SS_NOPREFIX with other styles by using the bitwise OR (|) operator. This can be useful when filenames or other strings that may contain an ampersand (&) must be displayed in a static control in a dialog box.
SS_RIGHT	Specifies a simple rectangle and right-aligns the given text in the rectangle. The text is formatted before it is displayed. Words that extend past the end of a line are automatically wrapped to the beginning of the next right-aligned line.
SS_SIMPLE	Specifies a simple rectangle and displays a single line of left-aligned text in the rectangle. The text line cannot be shortened or altered in any way. The control's parent window or dialog box must not process the WM_CTLCOLOR message.
SS_WHITEFRAME	Specifies a box with a frame drawn with the same color as the window backgrounds. This color is white in the default Windows color scheme.
SS_WHITERECT	Specifies a rectangle filled with the current window background color. This color is white in the default Windows color scheme.
For more information about the colors used by static controls, see Section 15.1.3, »Static Control Color Messages«.


  15.1.2  Messages for Icons

An application can retrieve the handle of the current icon or change it by sending a message to the icon control using the SendDlgItemMessage function. An icon is the only static control that can receive messages from its parent window. The following table describes these messages.

Message	Response
STM_GETICON	Returns the handle of the icon associated with the icon control.
STM_SETICON	Associates an icon with an icon control. This message returns the handle of the icon previously associated with the icon control (or zero, if an error occurs).


  15.1.3  Static Control Color Messages

Windows provides default color values for static controls. The system sends a WM_CTLCOLORSTATIC message to a static control's parent window before the control is drawn. This message contains a handle of the static control's device context (DC) and a handle of the child window. The parent window can use these handles to change the static control's text and background colors. The following table shows the default static control color messages.

Value	Use
COLOR_BACKGROUND	For coloring black rectangles and frames
COLOR_WINDOW	For coloring gray rectangles and frames
COLOR_WINDOWFRAME	For coloring white rectangles and frames
COLOR_WINDOWTEXT	For coloring text in text controls
An application can obtain the default values for these colors by calling the GetSysColor function or set the color values by calling the SetSysColor function. For more information about system colors, see Chapter 67, "System Information," in Microsoft Win32 Programmer's Reference, Volume 2. For more information about how colors are used with controls, see Chapter 9, »Controls «.

Portability Issue   In Windows NT, the WM_CTLCOLOR message has been replaced by the set of control color messages. For applications written for earlier versions of Windows, the developer must modify the code for processing the WM_CTLCOLOR message when porting the application to Windows NT.


  15.1.4  Default Message Processing

The window procedure for the predefined static control window class carries out default processing for all messages that the static control procedure does not process. When the static control returns FALSE for any message, the predefined window procedure checks the messages and carries out the default action described in the following table. In the table, a text static control is a static control with the SS_LEFT, SS_CENTER, SS_RIGHT, SS_SIMPLE, or SS_LEFTNOWORDWRAP style.

Message	Default action
STM_GETICON	Returns the handle of the icon if the static control is an icon; otherwise, returns zero.
STM_SETICON	Sets a new icon for the static control; invalidates the rectangle to draw the new icon; returns a handle of the previous icon.
WM_CREATE	Loads the icon and sizes the window to the icon size, for icon controls. Takes no action for other static controls.
WM_DESTROY	Frees and destroys any icon, for icon controls. Takes no action for other static controls.
WM_ENABLE	Repaints visible static controls.
WM_GETDLGCODE	Returns DLGC_STATIC.
WM_GETFONT	Returns the handle of the font for text static controls.
WM_GETTEXT	Returns 2 if the control is an icon that was set by using the STM_SETICON message; otherwise, copies the text of the control into an application-defined buffer.
WM_GETTEXTLENGTH	Returns the length, in characters, of the text for a text static control.
WM_NCCREATE	Sets the window text for text static controls; otherwise, returns TRUE.
WM_NCDESTROY	Takes no action if the control style is SS_LEFT, SS_CENTER, SS_RIGHT, or SS_SIMPLE; otherwise, calls the DefWindowProc function.
WM_NCHITTEST	Returns HTTRANSPARENT.
WM_PAINT	Repaints the control.
WM_SETFONT	Sets the font and repaints for text static controls.
WM_SETTEXT	Sets the text and repaints for text static controls.
The predefined window procedure passes all other messages to DefWindowProc for default processing.


  15.2  Using Static Controls

The following code example uses a timer and the STM_SETICON message to animate an icon in a dialog box. The icon handles and the icon identifier (IDI_ICON) are defined in a global header file.

LRESULT APIENTRY StaticProc(hDlg, message, wParam, lParam)

HWND hDlg;      /* window handle of dialog box           */

UINT message;   /* type of message                       */

UINT wParam;    /* message-specific information          */

LONG lParam;

{

    UINT idTimer = 1;

    static UINT i;

    static HICON aIcons[11];

    switch (message) {

        case WM_INITDIALOG: /* initialize dialog box */

            i = 0;

            /* Load icons("hinst" is defined globally). */

            hiconOne    = LoadIcon(hinst, "OneIco");

            aIcons[i]   = hiconOne;

            hiconTwo    = LoadIcon(hinst, "TwoIco");

            aIcons[++i] = hiconTwo;

                .

                . /* Continue with the remaining icons. */

                .

            i = 0;

             /*

              * Use STM_SETICON to associate an icon with the

              * IDI_ICON identifier.

              */

            SendDlgItemMessage(hDlg, /* dialog box window handle */

               IDI_ICON,             /* icon identifier          */

               STM_SETICON,          /* message to send          */

               (WPARAM) aIcons[i++], /* icon handle              */

               0);                   /* not used                 */

            /* Set a timer for 50-millisecond intervals. */

            SetTimer(hDlg, idTimer, 50, (TIMERPROC) NULL);

            return TRUE;

        case WM_TIMER:

             /*

              * Use STM_SETICON to associate a new icon with

              * the IDI_ICON identifier whenever a WM_TIMER

              * message is received.

              */

            SendDlgItemMessage(hDlg, /* dialog box window handle */

               IDI_ICON,             /* icon identifier          */

               STM_SETICON,          /* message to send          */

               (WPARAM) aIcons[i++], /* new icon handle          */

               0);                   /* not used                 */

            if (i == 10)

                i = 0;

            break;

        case WM_COMMAND:

            if (wParam == IDOK

                || wParam == IDCANCEL) {

                EndDialog(hDlg, TRUE);

                return TRUE;

            }

            return 0;

        case WM_DESTROY: /* clean up  */

            KillTimer(hDlg, idTimer);

            DeleteObject(hiconOne);

            DeleteObject(hiconTwo);

                .

                . /* Continue with the remaining icons. */

                .

            return 0;

    }

    return FALSE;

        UNREFERENCED_PARAMETER(lParam);

}


  15.3  Messages

Following are the messages used with static controls. (STM_GETICON and STM_SETICON are used only with icons.)

STM_GETICON
STM_SETICON
WM_CTLCOLORSTATIC


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


16.1  About Menus
  Chapter 16    Menus

16.1  About Menus

A menu is one or more lists of application commands. Each command, which is represented by a text string or bitmap, is called a menu item. By using the mouse or the keyboard to choose a menu item, the user directs the application to perform the command associated with that menu item. When the user chooses a menu item, Microsoft® Windows (™)  sends the application a command message that indicates which menu item the user chose.

This chapter describes menus and explains how to use them in a Win32 application.


  16.1.1  Menu Bars and Pop-up Menus

The menus in an application written for Microsoft Windows are arranged hierarchically. A menu bar (sometimes called a top-level menu) resides at the uppermost level of the hierarchy; the lower levels consist of pop-up menus (also known as submenus).

The items in a menu bar represent the main categories of commands provided by an application. Selecting an item from the menu bar typically activates a pop-up menu whose items correspond to the commands in a given category. For example, a menu bar might contain a File item that, when the user selects it, activates a pop-up menu with menu items such as New, Open, Save, and so on. »This illustration« shows the menu bar and the pop-up menu for the file command in Windows Notepad.

Only an overlapped or pop-up window can contain a menu bar; a child window cannot contain one. A menu bar is always visible. If the window has a title bar, Windows positions the menu bar just below it. By contrast, a pop-up menu is not visible until the user selects a menu item that activates it. When this menu is displayed, it is attached to the title bar.

Every menu must have an owner window. Windows sends messages to a menu's owner window when the user selects the menu or chooses a command from the menu. These messages are described in Section 16.1.9, Menu Messages.


  16.1.1.1  Floating Pop-up Menus

Windows provides a special type of pop-up menu called a floating pop-up menu. A floating pop-up menu is not attached to the menu bar; it can appear anywhere on the screen. An application typically associates a floating pop-up menu with a portion of a window such as the client area or with a specific object such as an icon.

A floating pop-up menu remains hidden until the user selects it (for example, by clicking the appropriate screen location with the mouse.) A floating pop-up menu is typically displayed at the position of the caret or mouse cursor.


  16.1.1.2  The System Menu

A System menu (also known as the Control menu) is a pop-up menu defined and managed almost exclusively by the system. It is represented by a small box containing a horizontal line that is displayed at the left end of the title bar. When the user clicks the box, Windows displays the System menu. Windows also displays the System menu when the user clicks the icon of a minimized application.

A System menu provides a standard set of menu items the user can choose to change a window's size or position, close the application, or activate the Windows Task List. Items in a System menu can be added, deleted, and modified, but most applications just use the standard set of menu items. »This illustration« shows a System Menu with the standard menu items.

An overlapped, pop-up, or child window can have a System menu. It is uncommon for an overlapped or pop-up window not to include a System menu.

When the user chooses a command from a System menu, Windows sends a WM_SYSCOMMAND message to the menu's owner window. In most applications, the window procedure does not process messages from a System menu. Instead, it simply passes the messages to the DefWindowProc function for system-default processing of the message. If a command is added to a System menu, the window procedure must process the command.


  16.1.2  Menu Handles

The system generates a unique handle for each menu. A menu handle is a value of the HMENU type. An application must specify a menu handle in many of the Windows menu functions. The developer receives the handle of a menu bar when he or she creates the menu or loads a menu resource. For information about creating menus and loading menus, see Section 16.1.6, »Menu Creation«.

The GetMenu or GetSubMenu function is used to retrieve the handle of a menu that has been created or loaded. GetMenu returns the handle of the menu bar assigned to the specified window. GetSubMenu returns the handle of a pop-up menu within the specified menu bar or pop-up menu. The GetSystemMenu function is used to retrieve the handle of a window's System menu.


  16.1.3  Class Menus

When registering a window class, the developer can specify a default menu for that class. This default menu is known as the class menu. To specify a class menu, the developer must assign the name of the menu, as given in your application's resource-definition file, to the lpszMenuName member of the WNDCLASS structure used to register the window class. After the window class has been registered, each window of that class will have the specified class menu. The developer can override the class menu by specifying the handle of a different menu when creating a window of that class. For more information about window classes, see Chapter 3, »Window Classes«.


  16.1.4  Menu Items

There are two kinds of menu items in Win32 applications: command items and pop-up items. When the user chooses a command item, Windows sends a WM_COMMAND or WM_SYSCOMMAND message to the window procedure of the menu's owner window. A command item on a System menu generates a WM_SYSCOMMAND message; command items in other menus generate WM_COMMAND messages. When the user selects a pop-up item, Windows displays a pop-up menu but doesn't send a command message to the window procedure.

As a rule, menu items in a menu bar consist of pop-up items; menu items in a pop-up menu consist of command items. Because a pop-up menu can contain pop-up items, pop-up menus can originate from within pop-up menus, producing a cascading effect as shown in »this illustration«.

When a pop-up item is included in a pop-up menu, Windows automatically adds a small arrow to the right of the menu item's text string or bitmap (see the Word Processing and Spreadsheet items in »the illustration«). The arrow is a visual cue to the user that Windows will display another pop-up menu when the item is selected.


  16.1.4.1  Menu-Item Identifier

Each command item has an identifier associated with it. An identifier is an application-defined integer value that Windows sends to the window procedure of the menu's owner window when the user chooses a command item. Windows sends the identifier as part of a WM_COMMAND message. The window procedure examines the identifier to determine the source of the message, and then processes the message accordingly.

A menu identifier must be a value from 0 to 65,535, even though it is a 32-bit integer. This is because the WM_COMMAND message passes a menu identifier as the low-order word of its wParam parameter.

A pop-up item has no identifier. A pop-up item does not need an identifier, because Windows does not send a WM_COMMAND message when the user selects a pop-up item. Instead, Windows activates the pop-up menu associated with the pop-up item.


  16.1.4.2  Checked and Unchecked Menu Items

A menu item can be either checked or unchecked. When a menu item is checked, Windows uses a bitmap to display a check mark to the left of the menu item. When the menu item is unchecked, Windows does not display the check mark. Only menu items in a pop-up menu can be checked; menu items in a menu bar can not be checked.

An application typically uses check marks to indicate menu options that are in effect. For example, when the user selects paragraph formatting options from a menu in a word processing application, the application places check marks next to the selected options. »This illustration« shows check marks next to the Left and Single Space options in a word processing application's Paragraph menu.

A check mark attribute controls whether a menu item is checked or not. A menu item's check mark attribute can be set by using the CheckMenuItem function. The GetMenuState function is used to determine whether a menu item is currently checked or unchecked.

Windows provides a default bitmap for displaying check marks. The developer, however, can substitute other bitmaps and direct Windows to use them instead of the default. Windows requires, however, that these check mark bitmaps have the same dimensions as the default check mark bitmap. The GetMenuCheckMarkDimensions function can be used to retrieve the default dimensions.

Two bitmaps can be associated with each menu item: one for when the menu item is checked and another for when it is unchecked. The SetMenuItemBitmaps function can be used to associate bitmaps with a menu item.

The developer can either provide check mark bitmaps as bitmap resources or create the bitmaps at run time by using graphic device interface (GDI) bitmap functions. A bitmap resource, however, isn't suitable for all video resolutions and aspect ratios, so the bitmap must be sized appropriately. The check mark bitmaps can be either monochrome or color. However, on a color screen the bitmap colors are inverted when the menu item is highlighted, and this result may be undesirable. For more information about bitmaps, see Chapter 29, »Bitmaps«.


  16.1.4.3  Enabled, Disabled, and Grayed Menu Items

A menu item can be enabled, disabled, or grayed. By default, a menu item is enabled. When the user chooses an enabled menu item, Windows sends a command message to the corresponding window procedure or displays the corresponding pop-up menu, depending on whether the menu item is a command item or a pop-up item.

When menu items are not available to the user, they should be disabled or grayed. Disabled or grayed menu items do not generate a command message or display a pop-up menu when a user chooses them. Typically, applications gray an unavailable menu item to provide a visual clue to the user that a command is not available. A disabled menu item does not provide this visual clue. A disabled item can serve as a heading for group related menu items. (For example, a Save heading can be listed and then a series of commands such as Save File, Save All, and Save As). A grayed item can be used when an action is not appropriate. (For example, the Print command in the File menu can be grayed when the system does not have a printer installed.) »This illustration« shows grayed items in an Edit menu.

The EnableMenuItem function is used to enable, disable, or gray a menu item, and the GetMenuState function is used to determine whether a menu item is enabled, disabled, or grayed.


  16.1.4.4  Menu-Item Separators and Line Breaks

Windows provides a special type of menu item, called a separator, that consists of a horizontal line. A separator menu item can be used in a pop-up menu to divide a menu into groups of related items. A separator item cannot be used in a menu bar. The user cannot select a separator menu item, and a separator does not send command messages to the window procedure.

When a menu bar contains more items than will fit on one line, Windows automatically breaks it into two or more lines. You can force a line break at a specific item on a menu bar by assigning the MF_MENUBREAK flag to the item. Windows places that item and all remaining items on a new line.

The MF_MENUBREAK and MF_MENUBARBREAK flags are used to divide items in a pop-up menu into multiple columns. When MF_MENUBREAK flag is assigned to an item, Windows places it and all remaining items in a new column. The MF_MENUBARBREAK flag creates a similar effect, except Windows includes a vertical line in the menu to separate the new column from the old one.


  16.1.4.5  Menu-Item Position

Windows assigns an integer position value to each item on a menu and uses the value to keep track of each item's position in the menu. Position values are zero-based; that is, the first item on a menu occupies position zero, the next position one, and so on. In a menu bar, the leftmost menu item is considered the first item, so it occupies position zero; in a pop-up menu, the uppermost menu item occupies position zero. Windows assigns position values to menu-item separators. »This illustration« shows the position values of both items and separators in a menu bar and a pop-up menu.

A number of functions are used to add an item to a menu, delete an item from a menu, or modify an existing item on a menu. When one of these functions is called, the item to be modified is identified either by its position value or, if it is a command item, by its identifier. Either the MF_BYPOSITION or MF_BYCOMMAND flag is also specified. For more information about modifying the contents of a menu, see Section 16.1.10, »Menu Modifications«.


  16.1.4.6  Highlighted Menu Items

Windows automatically highlights menu items as the user selects them. Highlighting can, however, be explicitly added or removed from a menu item on the menu bar by calling the HiliteMenuItem function. This function has no effect on menu items in pop-up menus. When you use HiliteMenuItem to highlight a menu item, however, the menu item only appears to be selected; if the user presses the ENTER key, the highlighted item is not chosen.


  16.1.4.7  Owner-drawn Menu Items

An application can completely control the appearance of a menu item by using an owner-drawn item. Owner-drawn items require an application to take total responsibility for drawing selected (highlighted), checked, and unchecked states. For example, if an application provided a font menu it could draw each menu item by using the corresponding font; the item for roman would be drawn with a roman font, the item for italic would be drawn in italic, and so on.

For information on how to create owner-drawn menu items, see Section 16.2.4, »Creating Owner-drawn Menu Items«.


  16.1.4.8  Help Item

The developer should provide a standard interface for the user, including a Help item on an application's menu bars. The item should read "Help," and it should be the rightmost item on the menu bar.


  16.1.5  Keyboard Access to Menus

Windows provides a standard keyboard interface for menus. You can enhance this interface by including mnemonics and accelerator keys for your menu items. The following three sections describe the standard keyboard interface, mnemonics, and accelerator keys.


  16.1.5.1  Standard Keyboard Interface

Windows is designed to work with or without a mouse or other pointing device. Because Windows provides a standard keyboard interface the user can use the keyboard to select menu items. Special code is not needed to support this keyboard interface. An application receives a command message whether a menu item is selected through the keyboard or by using a mouse. The standard keyboard interface processes the following keystrokes.

Keystroke	Action
ALT	Toggles in and out of menu bar mode.
ALT+SPACEBAR	Displays the System menu.
ESC	Exits menu mode.
RIGHT ARROW	Cycles to the next top-level menu item. This keystroke cycles between the application and System menus. If the selected item is in a pop-up menu, the next column in the pop-up menu is selected or the next top-level menu item is selected.
LEFT ARROW	Works like the RIGHT ARROW key, except in the opposite direction. In pop-up menus, this keystroke backs up one column; when the currently selected item is in the far-left column, the previous pop-up menu is selected.
UP or DOWN ARROWS	Activate a pop-up menu when pressed in a top-level menu. When pressed in a pop-up menu, either keystroke selects the next or previous item.
ENTER	Activates a pop-up menu and highlights the first item if an item has a pop-up menu associated with it; otherwise, this keystroke chooses the item as if the user released the mouse button while the item was selected.
Alphabetic character	Selects the first menu item with the specified character as its mnemonic. If the selected item onvokes a pop-up menu, the menu is displayed and the first item is highlighted; otherwise, the item is chosen.


  16.1.5.2  Mnemonics

The standard keyboard interface for menus can be enhanced by adding mnemonics to menu items. A mnemonic is a underlined letter in the text of a menu item. When a menu is active, the user can select a menu item by pressing the key that corresponds to the item's underlined letter. The menu bar is active when the user presses and releases the ALT key and the first item on the menu bar is highlighted. A pop-up menu is active when it is displayed.

A mnemonic keystroke for a menu item is created by preceding a character in the item's text string with an ampersand. For example, "&Move" causes Windows to underline the "M" character. »This illustration« shows the mnemonics in the System menu.


  16.1.5.3   Keyboard Accelerators

In addition to having a mnemonic, a menu item can have a keyboard accelerator associated with it. A keyboard accelerator is different from a mnemonic in that the menu need not be active for the accelerator key to work. Also, a mnemonic is always associated with a menu item, while a keyboard accelerator is usually associated with a menu item, but it does not have to be.

Text to identify the keyboard accelerator is added to the menu-item text string. The accelerator text appear to the right of the menu-item name after a backslash and tab character. For example, "$ClosetF4" represents a Close item with the F4 key as its keyboard accelerator and with C as its mnemonic. For more information on accelerators, see Chapter 17, »Keyboard Accelerators«. »This illustration« shows accelerators in the System menu.


  16.1.6  Menu Creation

The developer can use the following methods to create a menu for use in an application:

•	Load a menu from a menu-template resource.

•	Build a menu from a menu template created at run time.

•	Use the menu creation functions to build a menu at run time.

The following sections describe how to use these three methods to create menus.


  16.1.6.1  Menu-Template Resources

Most developers implement menus by creating a menu-template resource that is loaded at run time. A menu template defines a menu, including the items in the menu bar and all pop-up menus.

The first step in using a menu-template resource is to define a menu template in the resource-definition file for an application. Then a resource compiler is used to create the resource and add it to the application's executable file. At run time, the LoadMenu function is called to load the menu-template resource into memory and to retrieve the handle of the menu. Then a call the SetMenu function assigns the menu to a window.

Implementing menus as resources makes an application easier to localize for use in other countries. The resource-definition file is edited and recompiled, and the new resources are added to the application's executable file. For more information on creating a menu resource, see Section 16.2.1, »Using a Menu-Template Resource«.


  16.1.6.2  Menu Template in Memory

A menu can be created from a menu template that is built in memory at run time. A menu is created from the menu template by passing the address of the MENUITEMTEMPLATEHEADER structure to the LoadMenuIndirect function. The last member of the MENUITEMTEMPLATEHEADER structure specifies the offset of the array of MENUITEMTEMPLATE structures. Each member of the array describes a menu item. LoadMenuIndirect returns the handle of the menu.


  16.1.6.3  Menu-Creation Functions

Another way to create a menu at run time is to use the CreateMenu and CreatePopupMenu functions to create empty menus. CreateMenu creates an empty menu bar; CreatePopupMenu creates an empty pop-up menu. Then menu items are added to the menus by using the AppendMenu or InsertMenu functions.


  16.1.7  Menu Display

After a menu has been loaded or created, it must be assigned to a window before Windows can display it. This can be done by creating a class menu (see Section 16.1.3, »Class Menus«), by specifying the handle of the menu as the hmenu parameter of the CreateWindowEx function, or by calling the SetMenu function.

The TrackPopupMenu function can be used to display a pop-up menu. To do so, the handle of a pop-up menu is passed to the function. The menu's owner window, the screen position where Windows should display the menu, and the mouse button the user must use to choose an item must also be specified.


  16.1.8  Menu Destruction

If a menu is assigned to a window and that window is destroyed, Windows automatically destroys the menu, freeing the menu's handle and the memory occupied by the menu. Windows does not automatically destroy a menu that is not assigned to a window. An application must destroy the unassigned menu by calling the DestroyMenu function; otherwise, the menu continues to exist in memory even after the application closes.


  16.1.9  Menu Messages

Windows reports menu-related activity by sending messages to the window procedure of the window that owns the menu. The first menu-related message the window procedure receives is WM_SYSCOMMAND. Windows sends this message when the user activates the menu by clicking the menu bar or by pressing a key that activates the menu (for more information, see Section 16.1.5.1, »Standard Keyboard Interface«). The WM_SYSCOMMAND message includes a flag, either SC_KEYMENU or SC_MOUSEMENU, that indicates the hardware device used to activate the menu.

Next, Windows sends the WM_INITMENU message to the window procedure before Windows displays any pop-up menus, so an application can modify the menus before the user sees them. Windows sends the WM_INITMENU message only once per menu activation.

When the user selects a pop-up item, Windows sends the owner window the WM_INITMENUPOPUP message before displaying the pop-up menu. This message gives the application a second opportunity to modify the pop-up menu before it is displayed.

Each time the user moves the highlighting from one item to another, Windows sends a WM_MENUSELECT message to the window procedure of the menu's owner window. This message identifies the currently selected menu item. Many applications provide an information area at the bottom of their main windows and use this message to display additional information about the selected menu item.

Windows sends a WM_COMMAND message to the window procedure when the user chooses a command item from a menu. The low-order word of the WM_COMMAND message's wParam parameter contains the identifier of the chosen item. The window procedure should examine the identifier and process the message accordingly.


  16.1.10  Menu Modifications

A number of functions can be used to modify a menu after it has been loaded or created. The AppendMenu and InsertMenu functions are used to add items to a menu. AppendMenu appends a menu item to the end of a menu; InsertMenu inserts a menu item at a specified position in a menu. Both functions permit the attributes of the menu item to be specified, including whether the menu item is enabled, checked, grayed, and so on.

The ModifyMenu function is used to change the appearance or attributes of an existing menu item. For example, the text string or bitmap of a menu item can be enabled, disabled, grayed, checked, or unchecked. ModifyMenu replaces the specified menu item with a new item.

The DeleteMenu or RemoveMenu functions are used to delete a menu item from a menu. If the item being deleted is a pop-up item, DeleteMenu deletes the associated pop-up menu, discarding the menu handle and freeing the memory used by the pop-up menu. The RemoveMenu function deletes a menu item, but if the item activates a pop-up menu, it does not destroy the pop-up menu or its handle, allowing the menu to be reused.

After a menu bar has been modified, the DrawMenuBar function must be called to redraw the menu bar. Otherwise, the modifications will not appear until Windows redraws the owner window.


  16.2  Using Menus

This section explains how to perform the following tasks:

•	Use a menu-template resource.

•	Create a floating pop-up menu.

•	Use menu-item bitmaps.

•	Create owner-drawn menu items.

•	Use bitmaps to display custom check marks.


  16.2.1  Using a Menu-Template Resource

The developer typically includes a menu in an application by defining a menu template in the application's resource-definition file and then loading the menu at run time. This section describes how to define and load a menu-template resource.


  16.2.1.1  Defining a Menu-Template Resource

A menu-template resource represents an application's menu bar and all the related pop-up menus. The MENU statement marks the beginning of a menu template and provides the identifier used to load the menu. The identifier must be either a unique string or a unique integer.

The POPUP statement defines a pop-up item. A top-level pop-up item appears in the menu bar and activates a pop-up menu when it is selected. A nested pop-up item appears in a pop-up menu and activates a cascaded pop-up menu when it is selected.

The MENUITEM statement defines a command item. A top-level command item appears in the menu bar and generates a command message when it is selected. A nested command item appears in a pop-up menu and also generates a command message.

To define a string for a pop-up item or command item, enclose it in quotation marks and place it immediately to the right of the POPUP statement. You should include an ampersand (&) in the string to specify the mnemonic for the menu item. You should also include a keyboard accelerator, if applicable, and use the "\t" escape sequence to separate the accelerator text from the menu-item text.

The command identifier for a command item must appear immediately to the right of the menu-item text string. Use a named constant as the identifier and define the constant in your application's header file.

A number of options control the appearance and behavior of pop-up and command items. You can specify these options to the right of the menu-item text string (for a pop-up item) or to the right of the menu-item identifier (for a command item). The following menu-item options can be specified:

Option	Description
CHECKED	Item has a check mark next to it. This option is not valid for a top-level pop-up menu.
GRAYED	Item is disabled and its text string appears on the menu in a dimmed (grayed) shade of the menu-text color.
INACTIVE	Item is disabled and its text string appears in the normal menu-text color.
MENUBARBREAK	Same as MENUBREAK except that in pop-up menus, it separates the new column from the old column with a vertical line.
MENUBREAK	Menu-bar item is placed on a new line. An item on a pop-up menu is placed in a new column with no dividing line between the columns.
You can use the bitwise OR operator to combine these options. The INACTIVE and GRAYED options cannot be used together.

Here is a resource-definition file defining a menu bar with three pop-up items: File, Edit, and Font. The File and Edit pop-up items each activates a pop-up menu containing several command items. The Font pop-up menu has two other pop-up menus (Style and Size) within it.

MyMenuResource MENU

BEGIN

    POPUP "&File"

    BEGIN

        MENUITEM "&Open...",            IDM_FI_OPEN

        MENUITEM "&Close\tF3",          IDM_FI_CLOSE, GRAYED

        MENUITEM "&Quit",               IDM_FI_QUIT

        MENUITEM SEPARATOR

        MENUITEM "&About Sample...",    IDM_FI_ABOUT

    END

    POPUP "&Edit"

    BEGIN

        MENUITEM "&Undo",   IDM_ED_UNDO, GRAYED

        MENUITEM SEPARATOR

        MENUITEM "&Cut",    IDM_ED_CUT

        MENUITEM "C&opy",   IDM_ED_COPY

        MENUITEM "&Paste",  IDM_ED_PASTE

        MENUITEM "C&lear",  IDM_ED_ABOUT

    END

    POPUP "Fo&nt"

    BEGIN

        POPUP "&Style"

        BEGIN

            MENUITEM "&Regular\tF5",        IDM_FNT_STY_REGULAR

            MENUITEM SEPARATOR

            MENUITEM "&Bold\tCtrl+B",       IDM_FNT_STY_BOLD

            MENUITEM "&Italic\tCtrl+I",     IDM_FNT_STY_ITALIC

            MENUITEM "&Underline\tCtrl+U",  IDM_FNT_STY_ULINE

        END

        POPUP "Si&ze"

        BEGIN

            MENUITEM "10",  IDM_FNT_SZ_10

            MENUITEM "12",  IDM_FNT_SZ_12

            MENUITEM "14",  IDM_FNT_SZ_14

        END

    END

END


  16.2.1.2  Loading a Menu-Template Resource

You can load a menu-template resource for your application by calling the LoadMenu function, specifying the handle of the module that contains the resource and the menu-template's identifier. LoadMenu returns a menu handle that you can use to assign the menu to a window. This window becomes the menu's owner window, receiving all the messages generated by the menu.

Use the SetMenu function to assign a menu to a window, or specify the menu's handle in the hmenu parameter of the CreateWindowEx function when you create a window. Another way that you can assign a menu to a window is to specify a menu template when you register a window class. This identifies the menu as the class menu for the given window class. Whenever you create a window of the given class, Windows automatically assigns the given menu to the window.

You can create a class menu by including the identifier of the menu-template resource as the lpszMenuName member of a WNDCLASS structure and then passing the address of the structure to the RegisterClass function.


  16.2.1.3  Creating a Class Menu

The following example shows how to create a class menu for an application, how to create a window that uses the class menu, and how to process menu commands in the window procedure.

HINSTANCE hinst;

int APIENTRY WinMain(hinstance, hPrevInstance, lpCmdLine, nCmdShow)

HINSTANCE hinstance;

HINSTANCE hPrevInstance;

LPSTR lpCmdLine;

int nCmdShow;

{

    MSG msg;        /* message               */

    WNDCLASS wc;    /* window-class data     */

    HWND hwnd;      /* handle of main window */

    /*

     * Create the window class for the main window. Specify

     * the identifier of the menu-template resource as the

     * lpszMenuName member of the WNDCLASS structure to create

     * the class menu.

     */

    wc.style = 0;

    wc.lpfnWndProc = (WNDPROC) MainWndProc;

    wc.cbClsExtra = 0;

    wc.cbWndExtra = 0;

    wc.hInstance = hinstance;

    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

    wc.hCursor = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground = GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName =  "MyMenuResource";

    wc.lpszClassName = "MainWClass";

    if (!RegisterClass(&wc))

        return FALSE;

    hinst = hinstance;

    /*

     * Create the main window. Set the hmenu parameter to NULL so

     * that Windows uses the class menu for the window.

     */

    hwnd = CreateWindow("MainWClass", "Sample Application",

        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,

        CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinstance,

        NULL);

    if (hwnd == NULL)

        return FALSE;

    /*

     * Make the window visible and send a WM_PAINT message to the

     * window procedure.

     */

    ShowWindow(hwnd, nCmdShow);

    UpdateWindow(hwnd);

    /* Start the main message loop. */

    while (GetMessage(&msg, NULL, 0, 0)) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return msg.wParam;

        UNREFERENCED_PARAMETER(hPrevInstance);

}

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    switch (uMsg) {

        .

        . /* Process other window messages. */

        .

        case WM_COMMAND:

            /* Test for the identifier of a command item. */

            switch(LOWORD(wParam)) {

                case IDM_FI_OPEN:

                    DoFileOpen();   /* application-defined */

                    break;

                case IDM_FI_CLOSE:

                    DoFileClose();  /* application-defined */

                    break;

                .

                . /* Process other menu commands. */

                .

                default:

                    break;

            }

            return 0;

        .

        . /* Process other window messages. */

        .

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return NULL;

}


  16.2.2  Creating a Floating Pop-up Menu

To use a floating pop-up menu in an application, pass the handle of a pop-up menu to the TrackPopupMenu function. An application typically calls TrackPopupMenu in a window procedure in response to a user-generated message, such as WM_LBUTTONDOWN or WM_KEYDOWN.

In addition to the pop-up menu handle, TrackPopupMenu requires that you specify the handle of the owner window, the position of the floating pop-up menu (in screen coordinates), and the mouse button the user can use to choose an item.

Specify the position by providing x- and y-coordinates along with the TPM_CENTERALIGN, TPM_LEFTALIGN, or TPM_RIGHTALIGN flag. The flag specifies the position of the menu relative to the x- and y-coordinates.

You should permit the user to choose an item from a pop-up menu by using the same mouse button used to display the menu. To do this, specify either TPM_LEFTBUTTON or TPM_RIGHTBUTTON flags to indicate which mouse button the user can use to select a menu item.


  16.2.2.1  Creating a Floating Font-Attributes Menu

The example in this section contains portions of code from an application that creates and displays a floating pop-up menu that enables the user to set fonts and font attributes. The application displays the menu in the client area of its main window whenever the user clicks the left mouse button.

Here is the menu template for the pop-up menu that is provided in the application's resource-definition file.

PopupMenu MENU

BEGIN

  POPUP "Dummy Popup"

    BEGIN

      POPUP "Fonts"

        BEGIN

          MENUITEM "Courier",     IDM_FONT_COURIER

          MENUITEM "Times Roman", IDM_FONT_TMSRMN

          MENUITEM "Swiss",       IDM_FONT_SWISS

          MENUITEM "Helvetica",   IDM_FONT_HELV

          MENUITEM "Old English", IDM_FONT_OLDENG

        END

      POPUP "Sizes"

        BEGIN

          MENUITEM "7",  IDM_SIZE_7

          MENUITEM "8",  IDM_SIZE_8

          MENUITEM "9",  IDM_SIZE_9

          MENUITEM "10", IDM_SIZE_10

          MENUITEM "11", IDM_SIZE_11

          MENUITEM "12", IDM_SIZE_12

          MENUITEM "14", IDM_SIZE_14

        END

      POPUP "Styles"

        BEGIN

          MENUITEM "Bold",        IDM_STYLE_BOLD

          MENUITEM "Italic",      IDM_STYLE_ITALIC

          MENUITEM "Strike Out",  IDM_STYLE_SO

          MENUITEM "Superscript", IDM_STYLE_SUPER

          MENUITEM "Subscript",   IDM_STYLE_SUB

        END

    END

END

The following example gives the window procedure and supporting functions used to create and display the floating pop-up menu.

LRESULT APIENTRY MenuWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    RECT rc;    /* client area             */

    POINT pt;   /* location of mouse click */

    switch (uMsg) {

        case WM_LBUTTONDOWN:

            /* Get the bounding rectangle of the client area. */

            GetClientRect(hwnd, (LPRECT) &rc);

            /* Get the client coordinates for the mouse click. */

            pt.x = LOWORD(lParam);

            pt.y = HIWORD(lParam);

            /*

             * If the mouse click took place inside the client

             * area, execute the application-defined function

             * that displays the floating pop-up menu.

             */

            if (PtInRect((LPRECT) &rc, pt))

                HandlePopupMenu(hwnd, pt);

            break;

        .

        . /* Process other window messages. */

        .

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return NULL;

}

VOID APIENTRY HandlePopupMenu(hwnd, pt)

HWND hwnd;

POINT pt;

{

    HMENU hmenu;            /* menu template         */

    HMENU hmenuTrackPopup;  /* floating pop-up menu  */

    /*

     * Load the menu template containing the pop-up menu from the

     * application's resources.

     */

    hmenu = LoadMenu(hinst, "PopupMenu");

    if (hmenu == NULL)

        return;

    /*

     * Get the first pop-up menu in the menu template. This is the

     * menu that TrackPopupMenu displays.

     */

    hmenuTrackPopup = GetSubMenu(hmenu, 0);

    /*

     * TrackPopup uses screen coordinates, so convert the

     * coordinates of the mouse click to screen coordinates.

     */

    ClientToScreen(hwnd, (LPPOINT) &pt);

    /* Draw and track the floating pop-up menu. */

    TrackPopupMenu(hmenuTrackPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON,

        pt.x, pt.y, 0, hwnd, NULL);

    /* Destroy the menu.*/

    DestroyMenu(hmenu);

}


  16.2.3  Using Menu-Item Bitmaps

Windows can use a bitmap instead of a text string to display a menu item. To use a bitmap, you must set the MF_BITMAP flag for the menu item and specify the handle of the bitmap that Windows should display for the menu item. This section describes how to set the MF_BITMAP flag and retrieve the handle of a bitmap.


  16.2.3.1  Setting the MF_BITMAP Flag

The MF_BITMAP flag tells Windows to use a bitmap rather than a text string to display a menu item. A menu item's MF_BITMAP flag must be set at run time; you cannot set it in the resource-definition file.

You can use the ModifyMenu, InsertMenu, or AppendMenu function to set the MF_BITMAP flag. To convert a menu item from a text string item to a bitmap item, use ModifyMenu. To add a new bitmap item to a menu, use the MF_BITMAP flag with the InsertMenu or AppendMenu function.


  16.2.3.2  Creating the Bitmap

When you set the MF_BITMAP flag for a menu item, you must also specify the handle of the bitmap that Windows should display for the menu item. You can provide the bitmap as a bitmap resource or create the bitmap at run time.

To provide a bitmap resource, use a resource editor, such as ImageEdit, to create a bitmap resource, and then use a resource compiler to add the bitmap to your application's executable file. At run time, use the LoadBitmap function to load the bitmap and obtain its handle.

To create the bitmap at run time, use GDI functions. GDI provides several ways to create a bitmap at run time, but developers typically use the following method:

•	Use the CreateCompatibleDC function to create a device context compatible with the device context used by the application's main window.

•	Use the CreateCompatibleBitmap function to create a bitmap compatible with the application's main window.

•	Use the SelectObject function to select the bitmap into the compatible device context.

•	Use GDI drawing functions, such as Ellipse and LineTo, to draw an image into the bitmap.

•	Pass the handle of the bitmap to the ModifyMenu, InsertMenu, or AppendMenu function.

For more information about bitmaps, see Chapter 29, »Bitmaps«.


  16.2.3.3  Adding Lines and Graphs to a Menu

The following code sample shows how to create a menu that contains menu-item bitmaps. It creates two pop-up menus shown in »this illustration«. The first is a Chart menu that contains three menu-item bitmaps: a pie chart, a line chart, and a bar chart. The example demonstrates how to load these bitmaps from the application's resource file, and then use the CreatePopupMenu and AppendMenu functions to create the menu and menu items.

The second pop-up menu is a Lines menu. It contains bitmaps showing the line styles provided by the predefined pen in Windows. The line-style bitmaps are created at run time by using GDI functions.

Here are the definitions of the bitmap resources in the application's resource-definition file.

PIE BITMAP pie.bmp

LINE BITMAP line.bmp

BAR BITMAP bar.bmp

Here are the relevant portions of the application's header file.

/* Menu-item identifiers */

#define IDM_SOLID       PS_SOLID

#define IDM_DASH        PS_DASH

#define IDM_DASHDOT     PS_DASHDOT

#define IDM_DASHDOTDOT  PS_DASHDOTDOT

#define IDM_PIE  1

#define IDM_LINE 2

#define IDM_BAR  3

/* Line-type flags */

#define SOLID       0

#define DOT         1

#define DASH        2

#define DASHDOT     3

#define DASHDOTDOT  4

/* Count of pens */

#define CPENS 5

/* Chart-type flags */

#define PIE  1

#define LINE 2

#define BAR  3

/* Function prototypes */

LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);

VOID MakeChartMenu(HWND);

VOID MakeLineMenu(HWND, HPEN, HBITMAP);

The following example shows how menus and menu-item bitmaps are created in an application.

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    static HPEN hpen[CPENS];

    static HBITMAP hbmp[CPENS];

    int i;

    switch (uMsg) {

        case WM_CREATE:

            /* Create the Chart and Line menus. */

            MakeChartMenu(hwnd);

            MakeLineMenu(hwnd, hpen, hbmp);

            return 0;

        .

        . /* Process other window messages. */

        .

        case WM_DESTROY:

            for (i = 0; i < CPENS; i++) {

                DeleteObject(hbmp[i]);

                DeleteObject(hpen[i]);

            }

            PostQuitMessage(0);

            break;

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return NULL;

}

VOID MakeChartMenu(hwnd)

HWND hwnd;              /* handle of owner window      */

{

    HBITMAP hbmpPie;    /* handle of pie chart bitmap  */

    HBITMAP hbmpLine;   /* handle of line chart bitmap */

    HBITMAP hbmpBar;    /* handle of bar chart bitmap  */

    HMENU hmenuMain;    /* handle of main menu         */

    HMENU hmenuChart;   /* handle of chart pop-up menu */

    /*

     * Load the pie, line, and bar chart bitmaps from the

     * resource-definition file.

     */

    hbmpPie = LoadBitmap(hinst, MAKEINTRESOURCE(PIE));

    hbmpLine = LoadBitmap(hinst, MAKEINTRESOURCE(LINE));

    hbmpBar = LoadBitmap(hinst, MAKEINTRESOURCE(BAR));

    /*

     * Create the Chart pop-up menu and add it to the menu bar.

     * Append the Pie, Line, and Bar menu items to the Chart

     * pop-up menu.

     */

    hmenuMain = GetMenu(hwnd);

    hmenuChart = CreatePopupMenu();

    AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (UINT) hmenuChart,

        "Chart");

    AppendMenu(hmenuChart, MF_BITMAP, IDM_PIE, (LPCTSTR) hbmpPie);

    AppendMenu(hmenuChart, MF_BITMAP, IDM_LINE,

        (LPCTSTR) hbmpLine);

    AppendMenu(hmenuChart, MF_BITMAP, IDM_BAR, (LPCTSTR) hbmpBar);

    return;

}

VOID MakeLineMenu(hwnd, phpen, phbmp)

HWND hwnd;

HPEN *phpen;

HBITMAP *phbmp;

{

    HMENU hmenuLines;       /* handle of Lines pop-up menu     */

    HMENU hmenu;            /* handle of main menu             */

    COLORREF crMenuClr;     /* menu-item background color      */

    HBRUSH hbrBackground;   /* handle of background brush      */

    HBRUSH hbrOld;          /* handle of previous brush        */

    LONG lCheckXY;          /* dimensions of check mark bitmap */

    WORD wLineX;            /* width of line bitmaps           */

    WORD wLineY;            /* height of line bitmaps          */

    HDC hdcMain;            /* handle of main window's DC      */

    HDC hdcLines;           /* handle of compatible DC         */

    HBITMAP hbmpOld;        /* handle of previous bitmap       */

    int i;                  /* loop counter                    */

    /* Create the Lines pop-up menu. Add it to the menu bar. */

    hmenu = GetMenu(hwnd);

    hmenuLines = CreatePopupMenu();

    AppendMenu(hmenu, MF_STRING | MF_POPUP,

        (UINT) hmenuLines, "&Lines");

    /* Create a brush for the menu-item background color. */

    crMenuClr = GetSysColor(COLOR_MENU);

    hbrBackground = CreateSolidBrush(crMenuClr);

    /*

     * Create a compatible device context for the line bitmaps,

     * and then select the background brush into it.

     */

    hdcMain = GetDC(hwnd);

    hdcLines = CreateCompatibleDC(hdcMain);

    hbrOld = SelectObject(hdcLines, hbrBackground);

    /*

     * Get the dimensions of the check mark bitmap. The width of

     * the line bitmaps will be five times the width of the

     * check mark bitmap.

     */

    lCheckXY = GetMenuCheckMarkDimensions();

    wLineX = LOWORD(lCheckXY) * (WORD) 5;

    wLineY = HIWORD(lCheckXY);

    /*

     * Create the bitmaps and select them, one at a time, into the

     * compatible device context. Initialize each bitmap by

     * filling it with the menu-item background color.

     */

    for (i = 0; i < CPENS; i++) {

        phbmp[i] = CreateCompatibleBitmap(hdcMain, wLineX, wLineY);

        if (i == 0)

            hbmpOld = SelectObject(hdcLines, phbmp[i]);

        else

            SelectObject(hdcLines, phbmp[i]);

        ExtFloodFill(hdcLines, 0, 0, crMenuClr, FLOODFILLBORDER);

    }

    /* Create the pens. */

    phpen[0] = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));

    phpen[1] = CreatePen(PS_DOT, 1, RGB(0, 0, 0));

    phpen[2] = CreatePen(PS_DASH, 1, RGB(0, 0, 0));

    phpen[3] = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0));

    phpen[4] = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 0));

    /*

     * Select a pen and a bitmap into the compatible device

     * context, draw a line into the bitmap, and then append

     * the bitmap as an item in the Lines menu.

     */

    for (i = 0; i < CPENS; i++) {

        SelectObject(hdcLines, phbmp[i]);

        SelectObject(hdcLines, phpen[i]);

        MoveToEx(hdcLines, 0, wLineY / 2, NULL);

        LineTo(hdcLines, wLineX, wLineY / 2);

        AppendMenu(hmenuLines, MF_BITMAP, i + 1,

            (LPCTSTR) phbmp[i]);

    }

    /*

     * Release the main window's device context and destroy the

     * compatible device context. Also, destroy the background

     * brush.

     */

    ReleaseDC(hwnd, hdcMain);

    SelectObject(hdcLines, hbrOld);

    DeleteObject(hbrBackground);

    SelectObject(hdcLines, hbmpOld);

    DeleteDC(hdcLines);

    return;

}


  16.2.4  Creating Owner-drawn Menu Items

If you need complete control over the appearance of a menu item, you can use an owner-drawn menu item on your application. This section describes the steps involved in creating and using an owner-drawn menu item.


  16.2.4.1  Setting the MF_OWNERDRAW Flag

You cannot define an owner-drawn menu item on your application's resource-definition file. Instead, you must create a new menu item or modify an existing one by using the MF_OWNERDRAW menu flag.

You can use the AppendMenu, InsertMenu, or ModifyMenu function to specify an owner-drawn menu item. Use AppendMenu to add a new item to the end of the given menu. Use InsertMenu to place a new item onto a menu, moving the other items down. Use ModifyMenu to change the contents of a menu.

When you call any of these three functions, you can pass a 32-bit value as the lpNewItem parameter. This value can represent any information that is meaningful to your application, and that will be available to your application when the item is to be displayed. For example, the value could contain a pointer to a structure; the structure, in turn, might contain a text string and the handle of a logical font that your application will use to draw the string.


  16.2.4.2  Responding to the WM_MEASUREITEM Message

Before Windows displays an owner-drawn menu item for the first time, it sends the WM_MEASUREITEM message to the window procedure of the window that owns the item's menu. This message contains a pointer to a MEASUREITEMSTRUCT structure that identifies the item and contains an optional 32-bit value for the item. When the window procedure receives the WM_MEASUREITEM message, it must fill the itemWidth and itemHeight members of the structure before returning from processing the message. Windows uses the information in these members when creating the bounding rectangle in which your application draws the menu item. It also uses the information to detect when the user chooses the item.


  16.2.4.3  Responding to the WM_DRAWITEM Message

Whenever the item must be drawn (for example, when it is first displayed or when the user chooses it as a command), Windows sends the WM_DRAWITEM message to the window procedure of the menu's owner window. This message contains a pointer to a DRAWITEMSTRUCT structure. Like the MEASUREITEMSTRUCT structure, DRAWITEMSTRUCT contains information about the item and its optional 32-bit data. In addition, DRAWITEMSTRUCT contains flags that indicate the state of the item (such as whether it is grayed or checked) as well as a bounding rectangle and a device context that the application uses to draw the item.

In response to the WM_DRAWITEM message, your application must perform the following actions before returning from processing the message:

1.	Determine the type of drawing that is necessary. To do so, check the itemAction member of the DRAWITEMSTRUCT structure.

2.	Draw the menu item appropriately, using the bounding rectangle and device context obtained from the DRAWITEMSTRUCT structure. Your application must draw only within the bounding rectangle. For performance reasons, Windows doesn't clip portions of the image that are drawn outside the rectangle.

3.	Restore all GDI objects selected for the menu item's device context.

If the menu item is selected, Windows sets the itemAction member of the DRAWITEMSTRUCT structure to ODA_SELECT and sets the ODS_SELECTED flag in the itemState member. This is an application's cue to redraw the menu item to indicate that it is selected.


  16.2.4.4  Setting Fonts for Menu-Item Text Strings

This section contains an example from an application that uses owner-drawn menu items in a pop-up menu. The pop-up menu contains items that set the attributes of the current font, and the items are displayed using the appropriate font attribute, as shown in »this illustration«.

Here is how the menu is defined in the resource-definition file. Note that the strings for the Regular, Bold, Italic, and Underline items are assigned at run time, so their strings are empty in the resource-definition file.

MainMenu MENU

BEGIN

    POPUP   "&Character"

    BEGIN

        MENUITEM    "",    IDM_REGULAR

        MENUITEM SEPARATOR

        MENUITEM    "",    IDM_BOLD

        MENUITEM    "",    IDM_ITALIC

        MENUITEM    "",    IDM_ULINE

    END

END

The application's window procedure processes the messages involved in using owner-drawn menu items. The application uses the WM_CREATE message to do the following:

•	Set the MF_OWNERDRAW flag for the menu items.

•	Set the text strings for the menu items.

•	Obtain handles of the fonts used to draw the items.

•	Obtain the text and background color values for selected menu items.

The text strings and font handles are stored in an array of application-defined MYITEM structures. The application-defined GetAFont function creates a font that corresponds to the given font attribute and returns the handle of the font. The handles are destroyed during the processing of the WM_DESTROY message.

During the processing of the WM_MEASUREITEM message, the example gets the width and height of a menu-item string and copies these values into the MEASUREITEMSTRUCT structure. Windows uses the width and height values to calculate the size of the pop-up menu.

During the processing of the WM_DRAWITEM message, the menu item's string is drawn with room left next to the string for the check mark bitmap. If the user selects the item, the selected text and background colors are used to draw the item.

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    typedef struct _MYITEM {

        HFONT hfont;

        LPSTR psz;

    } MYITEM;             /* structure for item font and string */

    MYITEM *pmyitem;      /* pointer to item's font and string       */

    static MYITEM myitem[CITEMS];   /* array of MYITEMS              */

    static HMENU hmenu;             /* handle of main menu           */

    static COLORREF crSelText;  /* text color of selected item       */

    static COLORREF crSelBkgnd; /* background color of selected item */

    COLORREF crText;            /* text color of unselected item     */

    COLORREF crBkgnd;           /* background color unselected item  */

    LPMEASUREITEMSTRUCT lpmis;  /* points to item of data            */

    LPDRAWITEMSTRUCT lpdis;     /* points to item drawing data       */

    HDC hdc;                    /* handle of screen DC               */

    SIZE size;                  /* menu-item text extents            */

    DWORD dwCheckXY;            /* check mark dimensions             */

    WORD wCheckX;               /* check mark width                  */

    int nTextX;                 /* width of menu item                */

    int nTextY;                 /* height of menu item               */

    int i;                      /* loop counter                      */

    HFONT hfontOld;             /* handle of old font                */

    BOOL fSelected = FALSE;     /* menu-item selection flag          */

    switch (uMsg) {

        case WM_CREATE:

            /*

             * Modify the Regular, Bold, Italic, and Underline

             * menu items to make them owner-drawn items. Associate

             * a MYITEM structure with each item to contain the

             * string and font handle for each item.

             */

            hmenu = GetMenu(hwnd);

            ModifyMenu(hmenu, IDM_REGULAR, MF_BYCOMMAND |

                MF_CHECKED | MF_OWNERDRAW, IDM_REGULAR,

                (LPTSTR) &myitem[REGULAR]);

            ModifyMenu(hmenu, IDM_BOLD, MF_BYCOMMAND |

                MF_OWNERDRAW, IDM_BOLD, (LPTSTR) &myitem[BOLD]);

            ModifyMenu(hmenu, IDM_ITALIC, MF_BYCOMMAND |

                MF_OWNERDRAW, IDM_ITALIC,

                (LPTSTR) &myitem[ITALIC]);

            ModifyMenu(hmenu, IDM_ULINE, MF_BYCOMMAND |

                MF_OWNERDRAW, IDM_ULINE, (LPTSTR) &myitem[ULINE]);

            /*

             * Retrieve each item's font handle and copy it into

             * the hfont member of each item's MYITEM structure.

             * Also, copy each item's string into the structures.

             */

            myitem[REGULAR].hfont = GetAFont(REGULAR);

            myitem[REGULAR].psz = "Regular";

            myitem[BOLD].hfont = GetAFont(BOLD);

            myitem[BOLD].psz = "Bold";

            myitem[ITALIC].hfont = GetAFont(ITALIC);

            myitem[ITALIC].psz = "Italic";

            myitem[ULINE].hfont = GetAFont(ULINE);

            myitem[ULINE].psz = "Underline";

            /*

             * Retrieve the text and background colors of the

             * selected menu text.

             */

            crSelText = GetSysColor(COLOR_HIGHLIGHTTEXT);

            crSelBkgnd = GetSysColor(COLOR_HIGHLIGHT);

            return 0;

        case WM_MEASUREITEM:

            /* Retrieve a device context for the main window. */

            hdc = GetDC(hwnd);

            /*

             * Retrieve pointers to the menu item's

             * MEASUREITEMSTRUCT structure and MYITEM structure.

             */

            lpmis = (LPMEASUREITEMSTRUCT) lParam;

            pmyitem = (MYITEM *) lpmis->itemData;

            /*

             * Select the font associated with the item into

             * the main window's device context.

             */

            hfontOld = SelectObject(hdc, pmyitem->hfont);

            /*

             * Retrieve the width and height of the item's string,

             * and then copy the width and height into the

             * MEASUREITEMSTRUCT structure's itemWidth and

             * itemHeight members.

             */

            GetTextExtentPoint(hdc, pmyitem->psz,

                lstrlen(pmyitem->psz), &size);

            lpmis->itemWidth = size.cx;

            lpmis->itemHeight = size.cy;

            /*

             * Select the old font back into the device context,

             * and then release the device context.

             */

            SelectObject(hdc, hfontOld);

            ReleaseDC(hwnd, hdc);

            return TRUE;

            break;

        case WM_DRAWITEM:

            /*

             * Get pointers to the menu item's DRAWITEMSTRUCT

             * structure and MYITEM structure.

             */

            lpdis = (LPDRAWITEMSTRUCT) lParam;

            pmyitem = (MYITEM *) lpdis->itemData;

            /*

             * If the user has selected the item, use the selected

             * text and background colors to display the item.

             */

            if (lpdis->itemState & ODS_SELECTED) {

                crText = SetTextColor(lpdis->hDC, crSelText);

                crBkgnd = SetBkColor(lpdis->hDC, crSelBkgnd);

                fSelected = TRUE;

            }

            /*

             * Remember to leave space in the menu item for the

             * check mark bitmap. Retrieve the width of the bitmap

             * and add it to the width of the menu item.

             */

            dwCheckXY = GetMenuCheckMarkDimensions();

            wCheckX = LOWORD(dwCheckXY);

            nTextX = wCheckX + lpdis->rcItem.left;

            nTextY = lpdis->rcItem.top;

            /*

             * Select the font associated with the item into the

             * item's device context, and then draw the string.

             */

            hfontOld = SelectObject(lpdis->hDC, pmyitem->hfont);

            ExtTextOut(lpdis->hDC, nTextX, nTextY, ETO_OPAQUE,

                &lpdis->rcItem, pmyitem->psz,

                lstrlen(pmyitem->psz), NULL);

            /*

             * Select the previous font back into the device

             * context.

             */

            SelectObject(lpdis->hDC, hfontOld);

            /*

             * Return the text and background colors to their

             * normal state (not selected).

             */

            if (fSelected) {

                SetTextColor(lpdis->hDC, crText);

                SetBkColor(lpdis->hDC, crBkgnd);

            }

            return TRUE;

        .

        . /* Process other messages. */

        .

        case WM_DESTROY:

            /* Destroy the menu items' font handles. */

            for (i = 0; i < CITEMS; i++)

                DeleteObject(myitem[i].hfont);

            PostQuitMessage(0);

            break;

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return NULL;

}

HFONT GetAFont(fnFont)

int fnFont;             /* font-attribute flag            */

{

    static LOGFONT lf;  /* structure for font information */

    /*

     * Get a handle to the ANSI fixed-pitch font, and copy

     * information about the font to a LOGFONT structure.

     */

    GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT),

        &lf);

    /* Set the font attributes, as appropriate. */

    if (fnFont == BOLD)

        lf.lfWeight = FW_BOLD;

    else

        lf.lfWeight = FW_NORMAL;

    lf.lfItalic = (fnFont == ITALIC);

    lf.lfItalic = (fnFont == ULINE);

    /* Create the font, and then return its handle. */

    return CreateFont(lf.lfHeight, lf.lfWidth,

        lf.lfEscapement, lf.lfOrientation, lf.lfWeight,

        lf.lfItalic, lf.lfUnderline, lf.lfStrikeOut, lf.lfCharSet,

        lf.lfOutPrecision, lf.lfClipPrecision, lf.lfQuality,

        lf.lfPitchAndFamily, lf.lfFaceName);

}


  16.2.5  Using Custom Check Mark Bitmaps

A Windows video device driver provides a default check mark bitmap that Windows displays next to a menu item that is checked. You can customize an individual menu item by providing a pair of bitmaps to replace the default check mark bitmap. Windows displays one bitmap when the item is checked and the other when it is unchecked. This section describes the steps involved in creating and using custom check mark bitmaps.


  16.2.5.1  Creating Custom Check Mark Bitmaps

A custom check mark bitmap must be the same size as the default check mark bitmap. You can retrieve the default check mark bitmap's size by calling the GetMenuCheckMarkDimensions function. The low-order word of this function's return value specifies the width; the high-order word specifies the height.

Bitmap resources can be used to provide check mark bitmaps. However, a bitmap resource is not suitable for all screen resolutions and aspect ratios, so you'll need to use the StretchBlt function to size the bitmap, as appropriate. Depending on the bitmap being sized, the result of the sizing may not be acceptable, because stretching may distort the bitmap.

Instead of using a bitmap resource, GDI functions can be used to provide check mark bitmaps at run time. This involves the following steps, which an application typically performs during the WM_CREATE message:

1.	Create a device context in memory that is compatible with the screen.

2.	Create a bitmap that is compatible with the display.

3.	Select the bitmap into the device context.

4.	Draw or copy an image into the bitmap.

Call the CreateCompatibleDC function to create a device context that is compatible with the screen. The function's hdc parameter can specify either NULL or the return value from the GetDC function. CreateCompatibleDC returns the handle of the compatible device context.

Call the CreateCompatibleBitmap function to create an "empty" bitmap that is compatible with the screen. This function's nWidth and nHeight parameters set the size of the bitmap; they should specify the width and height information returned by the GetMenuCheckMarkDimensions function.

The CreateCompatibleBitmap function returns the handle of the bitmap. Pass this handle of the SelectObject function to select the bitmap into the compatible device context. Afterward, you can use the GDI drawing functions such as Rectangle and Ellipse to draw into the bitmap, or you can use functions such as BitBlt and StretchBlt to copy an image into the bitmap.

GDI provides several other ways to create bitmaps. For more information about bitmaps, see Chapter 29, »Bitmaps«.


  16.2.5.2  Associating Bitmaps with a Menu Item

You associate a pair of check mark bitmaps with a menu item by passing the handles of the bitmaps to the SetMenuItemBitmaps function. The hbmUnchecked parameter identifies the unchecked bitmap; the hbmChecked parameter identifies the checked bitmap. If you want to remove one or both check marks from a menu item, you can set the hbmUnchecked or hbmChecked parameter, or both, to NULL.


  16.2.5.3  Setting the Check Mark Attribute

The CheckMenuItem function sets a menu item's check mark attribute to either checked or unchecked. Specify the MF_CHECKED flag to set the check mark attribute to checked, or specify MF_UNCHECKED to set it to unchecked.


  16.2.5.4  Simulating Check Boxes in a Menu

This section contains an example that shows how to simulate check boxes in a pop-up menu. The example contains a Character menu whose items allow the user to set the bold, italic, and underline attributes of the current font. When a font attribute is in effect, a check mark is displayed in the check box next to the corresponding menu item; otherwise, it is displayed in an empty check box next to the item. »This illustration« shows both kinds of check boxes.

The example in this section replaces the default check mark bitmap with two bitmaps: a bitmap with a checked box and the bitmap with an empty box. The checked check box bitmap is displayed next to the Bold, Italic, or Underline menu item when the item's check mark attribute is set to MF_CHECKED. The unchecked or empty check box bitmap is displayed when the check mark attribute is set to MF_UNCHECKED.

Windows provides a predefined bitmap that contains the images used for check boxes and radio buttons (as shown in »this illustration«). The example in this section isolates the checked and empty check boxes, copies them to two separate bitmaps, and then uses them as the checked and unchecked bitmaps for items in the Character menu.

To retrieve the handle of the system-defined check box bitmap, the example in this section calls the LoadBitmap function, specifying NULL as the hinst parameter and OBM_CHECKBOXES as the lpBitmapName parameter. Because the images in the bitmap are all the same size, the example can isolate them by dividing the bitmap's width and height by the number of images in its rows and columns.

The following portion of a resource-definition file shows how the menu items in the Character menu are defined. Note that no font attributes are in effect initially, so the check mark attribute for the Regular item is set to checked and, by default, the check mark attribute of the remaining items is set to unchecked.

#include "men3.h"

MainMenu MENU

BEGIN

    POPUP   "&Character"

    BEGIN

        MENUITEM    "&Regular",     IDM_REGULAR, CHECKED

        MENUITEM SEPARATOR

        MENUITEM    "&Bold",        IDM_BOLD

        MENUITEM    "&Italic",      IDM_ITALIC

        MENUITEM    "&Underline",   IDM_ULINE

    END

END

Here is the relevant contents of the application's header file.

/* Menu-item identifiers */

#define IDM_REGULAR 0x1

#define IDM_BOLD    0x2

#define IDM_ITALIC  0x4

#define IDM_ULINE   0x8

/* Check mark flags */

#define CHECK   1

#define UNCHECK 2

/* Font-attribute mask */

#define ATTRIBMASK 0xe

/* Function prototypes */

LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);

HBITMAP GetMyCheckBitmaps(UINT);

BYTE CheckOrUncheckMenuItem(BYTE, HMENU);

The following example shows the portions of the window procedure that create the check mark bitmaps, set the check mark attribute of the Bold, Italic, and Underline menu items, and destroy check mark bitmaps.

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)

HWND hwndMain;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    static HBITMAP hbmpCheck;   /* handle of checked bitmap   */

    static HBITMAP hbmpUncheck; /* handle of unchecked bitmap */

    static HMENU hmenu;         /* handle of main menu        */

    BYTE fbFontAttrib;          /* font-attribute flags       */

    switch (uMsg) {

        case WM_CREATE:

            /*

             * Call the application-defined GetMyCheckBitmaps

             * function to get the predefined checked and

             * unchecked check box bitmaps.

             */

            hbmpCheck = GetMyCheckBitmaps(CHECK);

            hbmpUncheck = GetMyCheckBitmaps(UNCHECK);

            /*

             * Set the checked and unchecked bitmaps for the menu

             * items.

             */

            hmenu = GetMenu(hwndMain);

            SetMenuItemBitmaps(hmenu, IDM_BOLD, MF_BYCOMMAND,

                hbmpUncheck, hbmpCheck);

            SetMenuItemBitmaps(hmenu, IDM_ITALIC, MF_BYCOMMAND,

                hbmpUncheck, hbmpCheck);

            SetMenuItemBitmaps(hmenu, IDM_ULINE, MF_BYCOMMAND,

                hbmpUncheck, hbmpCheck);

            return 0;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                /* Process the menu commands. */

                case IDM_REGULAR:

                case IDM_BOLD:

                case IDM_ITALIC:

                case IDM_ULINE:

                    /*

                     * CheckOrUncheckMenuItem is an application-

                     * defined function that sets the menu item

                     * check marks and returns the user-selected

                     * font attributes.

                     */

                    fbFontAttrib = CheckOrUncheckMenuItem(

                        (BYTE) LOWORD(wParam), hmenu);

                    .

                    . /* Set the font attributes. */

                    .

                    return 0;

                .

                . /* Process other command messages. */

                .

                default:

                    break;

            }

            break;

        .

        . /* Process other window messages. */

        .

        case WM_DESTROY:

            /* Destroy the checked and unchecked bitmaps. */

            DeleteObject(hbmpCheck);

            DeleteObject(hbmpUncheck);

            PostQuitMessage(0);

            break;

        default:

            return DefWindowProc(hwndMain, uMsg, wParam, lParam);

    }

    return NULL;

}

HBITMAP GetMyCheckBitmaps(fuCheck)

UINT fuCheck;               /* CHECK or UNCHECK flag            */

{

    COLORREF crBackground;  /* background color                 */

    HBRUSH hbrBackground;   /* background brush                 */

    HBRUSH hbrTargetOld;    /* original background brush        */

    HDC hdcSource;          /* source device context            */

    HDC hdcTarget;          /* target device context            */

    HBITMAP hbmpCheckboxes; /* handle of check box bitmap       */

    BITMAP bmCheckbox;      /* structure for bitmap data        */

    HBITMAP hbmpSourceOld;  /* handle of original source bitmap */

    HBITMAP hbmpTargetOld;  /* handle of original target bitmap */

    HBITMAP hbmpCheck;      /* handle of check mark bitmap      */

    RECT rc;                /* rectangle for check box bitmap   */

    DWORD dwCheckXY;        /* dimensions of check mark bitmap  */

    WORD wBitmapX;          /* width of check mark bitmap       */

    WORD wBitmapY;          /* height of check mark bitmap      */

    /*

     * Get the menu background color and create a solid brush

     * with that color.

     */

    crBackground = GetSysColor(COLOR_MENU);

    hbrBackground = CreateSolidBrush(crBackground);

    /*

     * Create memory device contexts for the source and

     * destination bitmaps.

     */

    hdcSource = CreateCompatibleDC((HDC) NULL);

    hdcTarget = CreateCompatibleDC(hdcSource);

    /*

     * Get the size of the Windows default check mark bitmap and

     * create a compatible bitmap of the same size.

     */

    dwCheckXY = GetMenuCheckMarkDimensions();

    wBitmapX = LOWORD(dwCheckXY);

    wBitmapY = LOWORD(dwCheckXY);

    hbmpCheck = CreateCompatibleBitmap(hdcSource, wBitmapX,

        wBitmapY);

    /*

     * Select the background brush and bitmap into the target DC.

     */

    hbrTargetOld = SelectObject(hdcTarget, hbrBackground);

    hbmpTargetOld = SelectObject(hdcTarget, hbmpCheck);

    /*

     * Use the selected brush to initialize the background color

     * of the bitmap in the target device context.

     */

    PatBlt(hdcTarget, 0, 0, wBitmapX, wBitmapY, PATCOPY);

    /*

     * Load the predefined check box bitmaps and select it

     * into the source DC.

     */

    hbmpCheckboxes = LoadBitmap((HINSTANCE) NULL,

        (LPTSTR) OBM_CHECKBOXES);

    hbmpSourceOld = SelectObject(hdcSource, hbmpCheckboxes);

    /*

     * Fill a BITMAP structure with information about the

     * check box bitmaps, and then find the upper-left corner of

     * the unchecked check box or the checked check box.

     */

    GetObject(hbmpCheckboxes, sizeof(BITMAP), &bmCheckbox);

    if (fuCheck == UNCHECK) {

        rc.left = 0;

        rc.right = (bmCheckbox.bmWidth / 4);

    }

    else {

        rc.left = (bmCheckbox.bmWidth / 4);

        rc.right = (bmCheckbox.bmWidth / 4) * 2;

    }

    rc.top = 0;

    rc.bottom = (bmCheckbox.bmHeight / 3);

    /*

     * Copy the appropriate bitmap into the target DC. If the

     * check box bitmap is larger than the default check mark

     * bitmap, use StretchBlt to make it fit; otherwise, just

     * copy it.

     */

    if (((rc.right - rc.left) > (int) wBitmapX) ||

            ((rc.bottom - rc.top) > (int) wBitmapY))

        StretchBlt(hdcTarget, 0, 0, wBitmapX, wBitmapY,

            hdcSource, rc.left, rc.top, rc.right - rc.left,

            rc.bottom - rc.top, SRCCOPY);

    else

        BitBlt(hdcTarget, 0, 0, rc.right - rc.left,

            rc.bottom - rc.top,

            hdcSource, rc.left, rc.top, SRCCOPY);

    /*

     * Select the old source and destination bitmaps into the

     * source and destination DCs, and then delete the DCs and

     * the background brush.

     */

    SelectObject(hdcSource, hbmpSourceOld);

    SelectObject(hdcTarget, hbrTargetOld);

    hbmpCheck = SelectObject(hdcTarget, hbmpTargetOld);

    DeleteObject(hbrBackground);

    DeleteObject(hdcSource);

    DeleteObject(hdcTarget);

    /* Return the handle of the new check mark bitmap. */

    return hbmpCheck;

}

BYTE CheckOrUncheckMenuItem(bMenuItemID, hmenu)

BYTE bMenuItemID;

HMENU hmenu;

{

    DWORD fdwMenu;

    static BYTE fbAttributes;

    switch (bMenuItemID) {

        case IDM_REGULAR:

            /*

             * Whenever the Regular menu item is selected, add a

             * check mark to it and then remove check marks from

             * any font-attribute menu items.

             */

            CheckMenuItem(hmenu, IDM_REGULAR, MF_BYCOMMAND |

                MF_CHECKED);

            if (fbAttributes & ATTRIBMASK) {

                CheckMenuItem(hmenu, IDM_BOLD, MF_BYCOMMAND |

                    MF_UNCHECKED);

                CheckMenuItem(hmenu, IDM_ITALIC, MF_BYCOMMAND |

                    MF_UNCHECKED);

                CheckMenuItem(hmenu, IDM_ULINE, MF_BYCOMMAND |

                    MF_UNCHECKED);

            }

            fbAttributes = IDM_REGULAR;

            return fbAttributes;

        case IDM_BOLD:

        case IDM_ITALIC:

        case IDM_ULINE:

            /*

             * Toggle the check mark for the selected menu item and

             * set the font attribute flags appropriately.

             */

            fdwMenu = GetMenuState(hmenu, (UINT) bMenuItemID,

                MF_BYCOMMAND);

            if (!(fdwMenu & MF_CHECKED)) {

                CheckMenuItem(hmenu, (UINT) bMenuItemID,

                    MF_BYCOMMAND | MF_CHECKED);

                fbAttributes |= bMenuItemID;

            } else {

                CheckMenuItem(hmenu, (UINT) bMenuItemID,

                    MF_BYCOMMAND | MF_UNCHECKED);

                fbAttributes ^= bMenuItemID;

            }

            /*

             * If any font attributes are currently selected,

             * remove the check mark from the Regular menu item;

             * if no attributes are selected, add a check mark

             * to the Regular menu item.

             */

            if (fbAttributes & ATTRIBMASK) {

                CheckMenuItem(hmenu, IDM_REGULAR,

                    MF_BYCOMMAND | MF_UNCHECKED);

                fbAttributes &= (BYTE) ~IDM_REGULAR;

            } else {

                CheckMenuItem(hmenu, IDM_REGULAR,

                    MF_BYCOMMAND | MF_CHECKED);

                fbAttributes = IDM_REGULAR;

            }

            return fbAttributes;

    }

}


  16.3  Functions and Messages

Following are the Windows functions and messages used with menus.


  Functions

AppendMenu
ChangeMenu
CheckMenuItem
CreateMenu
CreatePopupMenu
DeleteMenu
DestroyMenu
DrawMenuBar
EnableMenuItem
GetMenu
GetMenuCheckMarkDimensions
GetMenuItemCount
GetMenuItemID
GetMenuState
GetMenuString
GetSubMenu
GetSystemMenu
HiliteMenuItem
InsertMenu
LoadMenu
LoadMenuIndirect
ModifyMenu
RemoveMenu
SetMenu
SetMenuItemBitmaps
TrackPopupMenu


  Messages

WM_COMMAND
WM_DRAWITEM
WM_ENTERIDLE
WM_ENTERMENULOOP
WM_EXITMENULOOP
WM_INITMENU
WM_INITMENUPOPUP
WM_MEASUREITEM
WM_MENUCHAR
WM_MENUSELECT
WM_NCHITTEST
WM_SYSCOMMAND


17.1  About Keyboard Accelerators
  Chapter 17    Keyboard Accelerators

17.1  About Keyboard Accelerators

In Microsoft® Windows (™) , a keyboard accelerator (or, simply, accelerator) is a keystroke or combination of keystrokes that generates a WM_COMMAND or WM_SYSCOMMAND message for an application. Accelerators are closely related to menus — both provide the user with access to an application's command set. Typically, users rely on an application's menus to learn the command set and then switch over to using accelerators as they become more proficient with the application. Accelerators provide faster, more direct access to commands than menus do. At a minimum, an application should provide accelerators for the more commonly used commands. Although accelerators typically generate commands that exist as menu items, they can also generate commands that have no equivalent menu items.


  17.1.1  Accelerator Tables

An accelerator table consists of an array of ACCEL structures, each defining an individual accelerator. Each ACCEL structure includes the following information:

•	The accelerator's keystroke combination

•	The accelerator's identifier

•	Various flags. This includes one that specifies whether Windows is to provide visual feedback by highlighting the corresponding menu item, if any, when the accelerator is used

To process accelerator keystrokes for a given thread, the developer must call the TranslateAccelerator function in the message loop associated with the thread's message queue. The TranslateAccelerator function monitors keyboard input to the message queue, checking for key combinations that match an entry in the accelerator table. When TranslateAccelerator finds a match, it translates the keyboard input (that is, the WM_KEYUP and WM_KEYDOWN messages) into a WM_COMMAND or WM_SYSCOMMAND message and then sends the message to the window procedure of the specified window. »This illustration« shows how accelerators are processed.

The WM_COMMAND message includes the identifier of the accelerator that caused TranslateAccelerator to generate the message. The window procedure examines the identifier to determine the source of the message and then processes the message accordingly.

Accelerator tables exist at two different levels in Windows. Windows maintains a single, system-wide accelerator table that applies to all applications. An application cannot modify the system accelerator table. For a description of the accelerators provided by the system accelerator table, see Section 17.1.3, »Accelerator Keystroke Assignments«.

Windows also maintains accelerator tables for each application. An application can define any number of accelerator tables for use with its own windows. A unique 32-bit handle (HACCEL) identifies each table. However, only one accelerator table can be active at a time for a given thread. The handle of the accelerator table passed to the TranslateAccelerator function determines which accelerator table is active for a thread. The active accelerator table can be changed at any time by passing a different accelerator-table handle to TranslateAccelerator.


  17.1.2  Accelerator-Table Creation

Several steps are required to create an accelerator table for an application. First, a resource compiler is used to create accelerator-table resources and to add them to the application's executable file. At run time, the LoadAccelerators function is used to load the accelerator table into memory and retrieve the handle of the accelerator table. This handle is passed to the TranslateAccelerator function to activate the accelerator table.

An accelerator table can also be created for an application at run time by passing an array of ACCEL structures to the CreateAcceleratorTable function. This method supports user-defined accelerators in the application. Like the LoadAccelerators function, CreateAcceleratorTable returns an accelerator-table handle that can be passed to TranslateAccelerator to activate the accelerator table.

Windows automatically destroys accelerator tables loaded by the LoadAccelerators function. An accelerator table created by the CreateAcceleratorTable function must be destroyed before an application closes; otherwise, the table continues to exist in memory after the application has closed. An accelerator table is destroyed by calling the DestroyAcceleratorTable function.

An existing accelerator table can be copied and modified. The existing accelerator table is copied by using the CopyAcceleratorTable function. After the copy is modified, a handle of the new accelerator table is retrieved by calling CreateAcceleratorTable. Finally, the handle is passed to the TranslateAccelerator function to activate the new table.


  17.1.3  Accelerator Keystroke Assignments

An ASCII character code or a virtual-key code can be used to define the accelerator. An ASCII character code makes the accelerator case sensitive. The ASCII "C" character can define the accelerator as ALT+c rather than ALT + C. Case-sensitive accelerators can, however, be confusing to use. For example, the ALT+C accelerator will be generated if the CAPS LOCK key is down or if the SHIFT key is down, but not if both are down.

Typically, accelerators don't need to be case sensitive, so most applications use virtual-key codes for accelerators rather than ASCII character codes. For a list of virtual-key codes, see Appendix B, "Virtual-Key Codes," in Microsoft Win32 Programmer's Reference, Volume 2.

Avoid accelerators that conflict with an application's menu mnemonics because the accelerator overrides the mnemonic, and this can confuse the user. For more information about menu mnemonics, see Chapter 16, »Menus«.

If an application defines an accelerator that is also defined in the system accelerator table, the application-defined accelerator overrides the system accelerator, but only within the context of the application. Avoid this practice, however, because it prevents the system accelerator from performing its standard role in the Windows user interface. The system-wide accelerators are described in the following list:

Accelerator	Description
ALT+ESC	Switches to the next application.
ALT+F4	Closes an application or a window.
ALT+HYPHEN	Opens the System menu for a document window.
ALT+PRINT SCREEN	Copies an image in the active window onto the Clipboard.
ALT+SPACEBAR	Opens the System menu for an application window.
ALT+TAB	Switches to the next application.
CTRL+ESC	Switches to Windows Task List.
CTRL+F4	Closes the active group or document window.
F1	Starts Help if the application has Help.
PRINT SCREEN	Copies an image on the screen onto the Clipboard.
SHIFT+ALT+TAB	Switches to the previous application. The user must press and hold down ALT+SHIFT while pressing TAB.


  17.1.4  Accelerators and Menus

Using an accelerator is the same as choosing a menu item: both actions cause Windows to send a WM_COMMAND or WM_SYSCOMMAND message to the corresponding window procedure. The WM_COMMAND message includes an identifier that the window procedure examines to determine the source of the message. If an accelerator generated the WM_COMMAND message, the identifier is that of the accelerator. Similarly, if a menu item generated the WM_COMMAND message, the identifier is that of the menu item. Because an accelerator provides a shortcut for choosing a command from a menu, an application usually assigns the same identifier to the accelerator and the corresponding menu item.

An application processes an accelerator WM_COMMAND message in exactly the same way as the corresponding menu item WM_COMMAND message. However, the WM_COMMAND message contains a flag that specifies whether the message originated from an accelerator or a menu item, in case accelerators need to be processed differently from their corresponding menu items. The WM_SYSCOMMAND message does not contain this flag.

The identifier determines whether an accelerator generates a WM_COMMAND or WM_SYSCOMMAND message. If the identifier has the same value as a menu item in the System menu, the accelerator generates a WM_SYSCOMMAND message. Otherwise, the accelerator generates a WM_COMMAND message.

If an accelerator has the same identifier as a menu item and the menu item is grayed or disabled, the accelerator is disabled and does not generate a WM_COMMAND or WM_SYSCOMMAND message. Also, an accelerator does not generate a command message if the corresponding window is minimized.

When the user uses an accelerator that corresponds to a menu item, the window procedure receives the WM_INITMENU and WM_INITMENUPOPUP messages as though the user had selected the menu item. For information on how to process these messages, see Chapter 16, »Menus«.

An accelerator that corresponds to an item in a menu should be included in the text of the menu item. In »this example«, the Windows Write includes accelerators in the text of the first four items in its Edit menu:


  17.2  Using Keyboard Accelerators

This section explains how to perform the following tasks:

•	Use an accelerator-table resource.

•	Use an accelerator table created at run time.


  17.2.1  Using an Accelerator-Table Resource

The most common way to add accelerator support to a Windows-based application is to include an accelerator-table resource with the application's executable file and then load the resource at run time. The steps involved in using an accelerator-table resource are as follows:

•	Create an accelerator table in a resource-definition file. Then compile it and add the resulting resource to your application's executable file.

•	Include a call to the LoadAccelerators function to load the accelerator-table resource and receive a handle of the accelerator table.

•	Add the TranslateAccelerator function to the message loop associated with the accelerator table.

•	Process the WM_COMMAND messages generated when the user uses the accelerator.


  17.2.1.1  Creating the Accelerator-Table Resource

You create an accelerator-table resource by using the ACCELERATORS statement in your application's resource-definition file. You must assign a name or resource identifier to the accelerator table, preferably unlike that of any other resource. Windows uses this identifier to load the resource at run time.

Each accelerator that you define requires a separate entry in the accelerator table. In each entry, you define the keystroke (either an ASCII character code or virtual-key code) that generates the accelerator and the accelerator's identifier. You also need to specify whether the keystroke must be used in some combination with the ALT, SHIFT, or CTRL keys. For more information about virtual keys, see Chapter 5, »Keyboard Input«.

An ASCII keystroke is specified either by enclosing the ASCII character in double quotation marks or by using the integer value of the character in combination with the ASCII flag. The following examples show how to define ASCII accelerators.

"A", ID_ACCEL1         ; SHIFT+A

65,  ID_ACCEL2, ASCII  ; SHIFT+A

A virtual-key code keystroke is specified differently depending on whether the keystroke is an alphanumeric key or a non-alphanumeric key. For an alphanumeric key, the key's letter or number, enclosed in double quotation marks, is combined with the VIRTKEY flag. For a non-alphanumeric key, the Windows virtual-key code for the specific key is combined with the VIRTKEY flag. The following examples show how to define virtual-key code accelerators.

"a",       ID_ACCEL3, VIRTKEY   ; A (caps-lock on) or a

VK_INSERT, ID_ACCEL4, VIRTKEY   ; INSERT key

The following example shows an accelerator-table resource that defines accelerators for file operations. The name of the resource is FileAccel.

FileAccel ACCELERATORS

BEGIN

    VK_F12, IDM_OPEN, CONTROL, VIRTKEY  ; CTRL+F12

    VK_F4,  IDM_CLOSE, ALT, VIRTKEY     ; ALT+F4

    VK_F12, IDM_SAVE, SHIFT, VIRTKEY    ; SHIFT+F12

    VK_F12, IDM_SAVEAS, VIRTKEY         ; F12

END

If you want the user to press the ALT, SHIFT, or CTRL keys in some combination with the accelerator keystroke, specify the ALT, SHIFT, and CONTROL flags in the accelerator's definition. Following are some examples.

"B",   ID_ACCEL5, ALT                   ; ALT_SHIFT+B

"I",   ID_ACCEL6, CONTROL, VIRTKEY      ; CTRL+I

VK_F5, ID_ACCEL7, CONTROL, ALT, VIRTKEY ; CTRL+ALT+F5

By default, when an accelerator key corresponds to a menu item, Windows highlights the menu item. You can use the NOINVERT flag to prevent highlighting for an individual accelerator. The following example shows how to use the NOINVERT flag.

VK_DELETE, ID_ACCEL8, VIRTKEY, SHIFT, NOINVERT  ; SHIFT+DELETE

To define accelerators that correspond to menu items in your application, include the accelerators in the text of the menu items. The following example shows how to include accelerators in menu-item text in a resource-definition file.

FilePopup MENU

BEGIN

    POPUP   "&File"

    BEGIN

        MENUITEM    "&New..",           IDM_NEW

        MENUITEM    "&Open\tCtrl+F12",  IDM_OPEN

        MENUITEM    "&Close\tAlt+F4"    IDM_CLOSE

        MENUITEM    "&Save\tShift+F12", IDM_SAVE

        MENUITEM    "Save &As...\tF12", IDM_SAVEAS

    END

END


  17.2.1.2  Loading the Accelerator-Table Resource

An application loads an accelerator-table resource by calling the LoadAccelerators function and specifying the instance handle of the application whose executable file contains the resource and the name or identifier of the resource. LoadAccelerators loads the specified accelerator table into memory and returns the handle of the accelerator table.

An application can load an accelerator-table resource at any time. Usually, a single-threaded application loads its accelerator table before entering its main message loop. An application that uses multiple threads typically loads the accelerator-table resource for a thread before entering the message loop for the thread. An application or thread might also use multiple accelerator tables, each associated with a particular window in the application. Such an application would load the accelerator table for the window each time the user activated the window. For more information about threads, see Chapter 43, "Processes and Threads," in Microsoft Win32 Programmer's Reference, Volume 2.


  17.2.1.3  Calling the TranslateAccelerator Function

To process accelerators, an application's (or thread's) message loop must contain a call to the TranslateAccelerator function. TranslateAccelerator compares keystrokes to an accelerator table and, if it finds a match, translates the keystrokes into a WM_COMMAND (or WM_SYSCOMMAND) message and then sends the message to a window procedure. The parameters of the TranslateAccelerator function include the handle of the window that is to receive the WM_COMMAND messages, the handle of the accelerator table used to translate accelerators, and a pointer to an MSG structure containing a message from the queue. The following example shows how to call TranslateAccelerator from within a message loop.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

    /* Check for accelerator keystrokes. */

    if (!TranslateAccelerator(

            hwndMain,      /* handle of receiving window    */

            haccel,        /* handle of active accel. table */

            &msg)) {       /* address of message data       */

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

}


  17.2.1.4  Processing WM_COMMAND Messages

When an accelerator is used, the window specified in the TranslateAccelerator function receives a WM_COMMAND or WM_SYSCOMMAND message. The low-order word of the wParam parameter contains the identifier of the accelerator. The window procedure examines the identifier to determine the source of the WM_COMMAND message and process the message accordingly.

Typically, if an accelerator corresponds to a menu-item in the application, the accelerator and menu item are assigned the same identifier. If you need to know whether a given WM_COMMAND message was generated by an accelerator or by a menu item, you can examine the high-order word of the wParam parameter. If an accelerator generated the message, the high-order word is 1, but if a menu item generated the message, it is 0.


  17.2.1.5  Destroying the Accelerator-Table Resource

Windows automatically destroys accelerator-table resources loaded by the LoadAccelerators function, removing the resource from memory after the application closes.


  17.2.1.6  Creating Accelerators for Font Attributes

The example in this section shows how to perform the following tasks:

•	Create an accelerator-table resource.

•	Load the accelerator table at run time.

•	Translate accelerators in a message loop.

•	Process WM_COMMAND messages generated by the accelerators.

These tasks are demonstrated in the context of an application that includes a Character menu and corresponding accelerators that allow the user to select attributes of the current font.

The following portion of a resource-definition file defines the Character menu and the associated accelerator table. Note that the menu items show the accelerator keystrokes and that each accelerator has the same identifier as its associated menu item.

#include <windows.h>

#include "acc.h"

MainMenu MENU

BEGIN

    POPUP   "&Character"

    BEGIN

        MENUITEM    "&Regular\tF5",         IDM_REGULAR

        MENUITEM    "&Bold\tCtrl+B",        IDM_BOLD

        MENUITEM    "&Italic\tCtrl+I",      IDM_ITALIC

        MENUITEM    "&Underline\tCtrl+U",   IDM_ULINE

    END

END

FontAccel ACCELERATORS

BEGIN

    VK_F5,  IDM_REGULAR,    VIRTKEY

    "B",    IDM_BOLD,       CONTROL, VIRTKEY

    "I",    IDM_ITALIC,     CONTROL, VIRTKEY

    "U",    IDM_ULINE,      CONTROL, VIRTKEY

END

The following sections from the application's source file show how to implement the accelerators.

HWND hwndMain;      /* handle of main window          */

HANDLE hinstAcc;    /* handle of application instance */

int WINAPI WinMain(hinst, hinstPrev, lpCmdLine, nCmdShow)

HINSTANCE hinst;

HINSTANCE hinstPrev;

LPSTR lpCmdLine;

int nCmdShow;

{

    MSG msg;            /* application messages              */

    HACCEL haccel;      /* handle of accelerator table       */

    .

    . /* Perform the initialization procedure. */

    .

    /* Create a main window for this application instance. */

    hwndMain = CreateWindowEx(0L, "MainWindowClass",

        "Sample Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,

        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,

        hinst, NULL );

    /* If a window cannot be created, return "failure." */

    if (!hwndMain)

        return FALSE;

    /* Make the window visible and update its client area. */

    ShowWindow(hwndMain, nCmdShow);

    UpdateWindow(hwndMain);

    /* Load the accelerator table. */

    haccel = LoadAccelerators(hinstAcc, "FontAccel");

    if (haccel == NULL)

        HandleAccelErr(ERR_LOADING);     /* application defined */

    /*

     * Get and dispatch messages until a WM_QUIT message is

     * received.

     */

    while (GetMessage(&msg, NULL, NULL, NULL)) {

        /* Check for accelerator keystrokes. */

        if (!TranslateAccelerator(

                hwndMain,      /* handle of receiving window    */

                haccel,        /* handle of active accel. table */

                &msg)) {       /* address of message data       */

            TranslateMessage(&msg);

            DispatchMessage(&msg);

        }

    }

    return msg.wParam;

}

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)

HWND hwndMain;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    BYTE fbFontAttrib;        /* array of font-attribute flags  */

    static HMENU hmenu;       /* handle of main menu            */

    switch (uMsg) {

        case WM_CREATE:

            /*

             * Add a check mark to the Regular menu item to

             * indicate that it is the default.

             */

            hmenu = GetMenu(hwndMain);

            CheckMenuItem(hmenu, IDM_REGULAR, MF_BYCOMMAND |

                MF_CHECKED);

            return 0;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                /* Process the accelerator and menu commands. */

                case IDM_REGULAR:

                case IDM_BOLD:

                case IDM_ITALIC:

                case IDM_ULINE:

                    /*

                     * GetFontAttributes is an application-defined

                     * function that sets the menu-item check marks

                     * and returns the user-selected font attributes.

                     */

                    fbFontAttrib = GetFontAttributes(

                        (BYTE) LOWORD(wParam), hmenu);

                     /*

                     * SetFontAttributes is an application-defined

                     * function that creates a font with the

                     * user-specified attributes the font with

                     * the main window's device context.

                     */

                    SetFontAttributes(fbFontAttrib);

                    break;

                default:

                    break;

            }

            break;

            .

            . /* Process other messages. */

            .

        default:

            return DefWindowProc(hwndMain, uMsg, wParam, lParam);

    }

    return NULL;

}


  17.2.2  Using an Accelerator Table Created at Run Time

The Win32 application programming interface (API) allows you to create accelerator tables at run time. The steps involved in creating and using an accelerator table at run time are as follows:

•	Define the accelerators by filling an array of ACCEL structures and then create an accelerator table by passing the array to the CreateAcceleratorTable function.

•	Activate the accelerator table and process WM_COMMAND messages generated by the accelerators.

•	Destroy the accelerator table before the application closes.


  17.2.2.1  Creating the Accelerator Table

The first step in creating an accelerator table at run time is filling an array of ACCEL structures. Each structure in the array defines an accelerator in the table. An accelerator's definition includes its flags, its key, and its identifier. The ACCEL structure has the following form.

typedef struct tagACCEL { /* accl */

    BYTE   fVirt;

    WORD   key;

    WORD   cmd;

} ACCEL;

You define an accelerator's keystroke by specifying an ASCII character code or a virtual-key code in the key member of the ACCEL structure. If you specify a virtual-key code, you must first include the FVIRTKEY flag in the fVirt member; otherwise, Windows interprets the code as an ASCII character code. You can include the FCONTROL, FALT, or FSHIFT flag, or all three, to combine the CTRL, ALT, or SHIFT key with the keystroke.

To create the accelerator table, pass the address of the array of ACCEL structures to the CreateAcceleratorTable function. CreateAcceleratorTable creates the accelerator table and returns the handle of the table.


  17.2.2.2  Processing Accelerators

The process of loading and calling accelerators provided by an accelerator table created at run time is the same as processing those provided by an accelerator table resource. For more information, see Section 17.2.1.2, »Loading the Accelerator-Table Resource«, Section 17.2.1.3, »Calling the TranslateAccelerator Function«, and Section 17.2.1.4, »Processing WM_COMMAND Messages«.


  17.2.2.3  Destroying the Accelerator Table

Before an application closes, it must destroy accelerator tables created at run time. You can destroy an accelerator table and remove it from memory by passing the table's handle to the DestroyAcceleratorTable function.


  17.2.2.4  Creating User-Editable Accelerators

This example shows how to construct a dialog box that allows the user to change the accelerator associated with a menu item. The dialog box consists of a combo box containing menu items, a combo box containing the names of keys, and check boxes for selecting the CTRL, ALT, and SHIFT keys. »This illustration« shows the dialog box.

The following example shows how the dialog box is defined in the resource-definition file.

EdAccelBox DIALOG 5, 17, 193, 114

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION

CAPTION "Edit Accelerators"

BEGIN

    COMBOBOX        IDD_MENUITEMS, 10, 22, 52, 53,

                        CBS_SIMPLE | CBS_SORT | WS_VSCROLL |

                        WS_TABSTOP

    CONTROL         "Control", IDD_CNTRL, "Button",

                        BS_AUTOCHECKBOX | WS_TABSTOP,

                        76, 35, 40, 10

    CONTROL         "Alt", IDD_ALT, "Button",

                        BS_AUTOCHECKBOX | WS_TABSTOP,

                        76, 48, 40, 10

    CONTROL         "Shift", IDD_SHIFT, "Button",

                        BS_AUTOCHECKBOX | WS_TABSTOP,

                        76, 61, 40, 10

    COMBOBOX        IDD_KEYSTROKES, 124, 22, 58, 58,

                        CBS_SIMPLE | CBS_SORT | WS_VSCROLL |

                        WS_TABSTOP

    PUSHBUTTON      "Ok", IDOK, 43, 92, 40, 14

    PUSHBUTTON      "Cancel", IDCANCEL, 103, 92, 40, 14

    LTEXT           "Select Item:", 101, 10, 12, 43, 8

    LTEXT           "Select Keystroke:", 102, 123, 12, 60, 8

END

The dialog box uses an array of application-defined VKEY structures, each containing a keystroke-text string and an accelerator-text string. When the dialog box is created, it parses the array and adds each keystroke-text string to the Select Keystroke combo box. When the user clicks the Ok button, the dialog box looks up the selected keystroke-text string and retrieves the corresponding accelerator-text string. The dialog box appends the accelerator-text string to the text of the menu item that the user selected. The following example shows the array of VKEY structures:

/* VKey Lookup Support */

#define MAXKEYS 26

typedef struct _VKEYS {

    char *pKeyName;

    char *pKeyString;

} VKEYS;

VKEYS vkeys[MAXKEYS] = {

    "BkSp",     "Back Space",

    "PgUp",     "Page Up",

    "PgDn",     "Page Down",

    "End",      "End",

    "Home",     "Home",

    "Lft",      "Left",

    "Up",       "Up",

    "Rgt",      "Right",

    "Dn",       "Down",

    "Ins",      "Insert",

    "Del",      "Delete",

    "Mult",     "Multiply",

    "Add",      "Add",

    "Sub",      "Subtract",

    "DecPt",    "Decimal Point",

    "Div",      "Divide",

    "F2",       "F2",

    "F3",       "F3",

    "F5",       "F5",

    "F6",       "F6",

    "F7",       "F7",

    "F8",       "F8",

    "F9",       "F9",

    "F11",      "F11",

    "F12",      "F12"

};

The dialog box's initialization procedure fills the Select Item and Select Keystroke combo boxes. After the user selects a menu item and associated accelerator, the dialog box examines the controls in the dialog box to get the user's selection, updates the text of the menu item, and then creates a new accelerator table that contains the user-defined new accelerator. The following example shows the dialog-box procedure.

/* Global variables */

HWND hwndMain;      /* handle of main window          */

HANDLE hinstAcc;    /* handle of application instance */

HACCEL haccel;      /* handle of accelerator table    */

.

.

.

/* Dialog-box procedure */

LRESULT CALLBACK EdAccelProc(hwndDlg, uMsg, wParam, lParam)

HWND hwndDlg;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    int nCurSel;            /* index of list box item          */

    UINT idItem;            /* menu-item identifier            */

    UINT uItemPos;          /* menu-item position              */

    UINT i, j = 0;          /* loop counters                   */

    static UINT cItems;     /* count of items in menu          */

    char szTemp[32];        /* temporary buffer                */

    char szAccelText[32];   /* buffer for accelerator text     */

    char szKeyStroke[16];   /* buffer for keystroke text       */

    static char szItem[32]; /* buffer for menu-item text       */

    HWND hwndCtl;           /* handle of control window        */

    static HMENU hmenu;     /* handle of "Character" menu      */

    PCHAR pch, pch2;        /* pointers for string copying     */

    WORD wVKCode;           /* accelerator virtual-key code    */

    BYTE fAccelFlags;       /* fVirt flags for ACCEL structure */

    LPACCEL lpaccelNew;     /* address of new accel. table     */

    HACCEL haccelOld;       /* handle of old accel. table      */

    int cAccelerators;      /* number of accelerators in table */

    static BOOL fItemSelected = FALSE; /* item selection flag  */

    static BOOL fKeySelected = FALSE;  /* key selection flag   */

    switch (uMsg) {

        case WM_INITDIALOG:

            /* Get the handle of the menu-item combo box. */

            hwndCtl = GetDlgItem(hwndDlg, IDD_MENUITEMS);

            /*

             * The application's menu bar contains a "Character"

             * submenu whose items have accelerators associated

             * with them. Get the handle of the "Character"

             * submenu (its position within the main menu is 2),

             * and count the number of items it has.

             */

            hmenu = GetSubMenu(GetMenu(hwndMain), 2);

            cItems = GetMenuItemCount(hmenu);

            /*

             * Get the text of each item, strip out the '&' and

             * the accelerator text, and add the text to the

             * menu-item combo box.

             */

            for (i = 0; i < cItems; i++) {

                if (!(GetMenuString(hmenu, i, szTemp,

                        sizeof(szTemp), MF_BYPOSITION)))

                    continue;

                for (pch = szTemp, pch2 = szItem;

                       *pch != '\0'; ) {

                    if (*pch != '&') {

                        if (*pch == '\t') {

                            *pch = '\0';

                            *pch2 = '\0';

                        }

                        else

                            *pch2++ = *pch++;

                    }

                    else

                        pch++;

                }

                SendMessage(hwndCtl, CB_ADDSTRING, 0,

                    (LONG) (LPSTR) szItem);

            }

            /*

             * Now fill the keystroke combo box with the list of

             * keystrokes that will be allowed for accelerators.

             * The list of keystrokes is in the application-defined

             * structure called "vkeys".

             */

            hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES);

            for (i = 0; i < MAXKEYS; i++)

                SendMessage(hwndCtl, CB_ADDSTRING, 0,

                    (LONG) (LPSTR) vkeys[i].pKeyString);

            return TRUE;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                case IDD_MENUITEMS:

                    /*

                     * The user must select an item from the menu-

                     * item combo box. This flag is checked during

                     * IDOK processing to be sure a selection was made.

                     */

                    fItemSelected = TRUE;

                    return 0;

                case IDD_KEYSTROKES:

                    /*

                     * The user must select an item from the menu-

                     * item combo box. This flag is checked during

                     * IDOK processing to be sure a selection was made.

                     */

                    fKeySelected = TRUE;

                    return 0;

                case IDOK:

                    /*

                     * If the user has not selected a menu item

                     * and a keystroke, display a reminder in a

                     * message box.

                     */

                    if (!fItemSelected || !fKeySelected) {

                        MessageBox(hwndDlg,

                            "Item or key not selected.", NULL,

                            MB_OK);

                        return 0;

                    }

                    /*

                     * Determine whether the CTRL, ALT, and SHIFT

                     * keys are selected. Concatenate the

                     * appropriate strings to the accelerator-

                     * text buffer, and set the appropriate

                     * accelerator flags.

                     */

                    szAccelText[0] = '\0';

                    hwndCtl = GetDlgItem(hwndDlg, IDD_CNTRL);

                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0)

                            == 1) {

                        lstrcat(szAccelText, "Ctl+");

                        fAccelFlags |= FCONTROL;

                    }

                    hwndCtl = GetDlgItem(hwndDlg, IDD_ALT);

                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0)

                            == 1) {

                        lstrcat(szAccelText, "Alt+");

                        fAccelFlags |= FALT;

                    }

                    hwndCtl = GetDlgItem(hwndDlg, IDD_SHIFT);

                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0)

                            == 1) {

                        lstrcat(szAccelText, "Shft+");

                        fAccelFlags |= FSHIFT;

                    }

                    /*

                     * Get the selected keystroke, and look up the

                     * accelerator text and the virtual-key code

                     * for the keystroke in the vkeys structure.

                     */

                    hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES);

                    nCurSel = (int) SendMessage(hwndCtl,

                        CB_GETCURSEL, 0, 0);

                    SendMessage(hwndCtl, CB_GETLBTEXT,

                        nCurSel, (LONG) (LPSTR) szKeyStroke);

                    for (i = 0; i < MAXKEYS; i++) {

                        if(lstrcmp(vkeys[i].pKeyString,

                                szKeyStroke) == 0) {

                            lstrcpy(szKeyStroke,

                                vkeys[i].pKeyName);

                            break;

                        }

                    }

                    /*

                     * Concatenate the keystroke text to the

                     * "Ctl+","Alt+", or "Shft+" string.

                     */

                    lstrcat(szAccelText, szKeyStroke);

                    /*

                     * Determine the position in the menu of the

                     * selected menu item. Menu items in the

                     * "Character" menu have positions 0,2,3, and 4.

                     */

                    if (lstrcmp(szItem, "Regular") == 0)

                        uItemPos = 0;

                    else if (lstrcmp(szItem, "Bold") == 0)

                        uItemPos = 2;

                    else if (lstrcmp(szItem, "Italic") == 0)

                        uItemPos = 3;

                    else if (lstrcmp(szItem, "Underline") == 0)

                        uItemPos = 4;

                    /*

                     * Get the string that corresponds to the

                     * selected item.

                     */

                    GetMenuString(hmenu, uItemPos, szItem,

                        sizeof(szItem), MF_BYPOSITION);

                    /*

                     * Append the new accelerator text to the

                     * menu-item text.

                     */

                    for (pch = szItem; *pch != '\t'; pch++);

                    ++pch;

                    for (pch2 = szAccelText; *pch2 != '\0';

                            pch2++)

                        *pch++ = *pch2;

                    *pch = '\0';

                    /*

                     * Modify the menu item to reflect the new

                     * accelerator text.

                     */

                    idItem = GetMenuItemID(hmenu, uItemPos);

                    ModifyMenu(hmenu, idItem, MF_BYCOMMAND |

                        MF_STRING, idItem, szItem);

                    /* Reset the selection flags. */

                    fItemSelected = FALSE;

                    fKeySelected = FALSE;

                    /* Save the current accelerator table. */

                    haccelOld = haccel;

                    /*

                     * Count the number of entries in the current

                     * table, allocate a buffer for the table, and

                     * then copy the table into the buffer.

                     */

                    cAccelerators = CopyAcceleratorTable(

                        haccelOld, NULL, 0);

                    lpaccelNew = (LPACCEL) LocalAlloc(LPTR,

                        cAccelerators * sizeof(ACCEL));

                    if (lpaccelNew != NULL)

                        CopyAcceleratorTable(haccel, lpaccelNew,

                            cAccelerators);

                    /*

                     * Find the accelerator that the user modified

                     * and change its flags and virtual-key code

                     * as appropriate.

                     */

                    for (i = 0; (lpaccelNew[i].cmd ==

                                (WORD) idItem)

                            && (i < (UINT) cAccelerators); i++) {

                        lpaccelNew[i].fVirt = fAccelFlags;

                        lpaccelNew[i].key = wVKCode;

                    }

                    /*

                     * Create the new accelerator table, and

                     * destroy the old one.

                     */

                    DestroyAcceleratorTable(haccelOld);

                    haccel = CreateAcceleratorTable(lpaccelNew,

                        cAccelerators);

                    /* Destroy the dialog box. */

                    EndDialog(hwndDlg, TRUE);

                    return 0;

                case IDCANCEL:

                    EndDialog(hwndDlg, TRUE);

                    return TRUE;

                default:

                    break;

            }

        default:

            break;

    }

    return FALSE;

}


  17.3  Functions and Messages

Following are the functions and messages used with accelerators.


  Functions

CopyAcceleratorTable
CreateAcceleratorTable
DestroyAcceleratorTable
LoadAccelerators
TranslateAccelerator


  Messages

WM_COMMAND
WM_INITMENU
WM_INITMENUPOPUP
WM_MENUCHAR
WM_MENUSELECT
WM_SYSCHAR
WM_SYSCOMMAND


18.1  About Dialog Boxes
  Chapter 18    Dialog Boxes

18.1  About Dialog Boxes

In Microsoft® Windows (™) , a dialog box is a temporary window an application creates to retrieve user input. An application typically uses dialog boxes to prompt the user for additional information for commands. A dialog box usually contains one or more controls (child windows) with which the user enters text, chooses options, or directs the action of the command.

Windows provides many functions, messages, and predefined controls to help create and manage dialog boxes, thus making it easier to develop the user interface for an application. This chapter describes the dialog box functions and messages and explains how to use them create and use dialog boxes.

Windows also provides many predefined or "common" dialog boxes that support commands, such as File Open and File Print. Applications that use these commands should use the common dialog boxes to prompt for the same user input, regardless of the type of application carrying out the commands. For more information about using common dialog boxes in your applications, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.


  18.1.1  When to Use a Dialog Box

Most applications use dialog boxes to prompt for additional information for commands that require user input. Using a dialog box is the only recommended way for an application to retrieve the input. For example, the File Open command requires the name of a file to open, so an application should use a dialog box to prompt the user for the name. In such cases, the application creates the dialog box when the user chooses the command and destroys the dialog box immediately after the user supplies the information.

Many applications also use dialog boxes to display information or options while the user works in another window. For example, word processing applications often use a dialog box with a text search command. While the application searches for the text, the dialog box remains on the screen. The user can then return to the dialog box and search for the same word again, or change the entry in the dialog box and search for a new word. Applications that use dialog boxes in this way typically create one when the user chooses a command and continue to display it for as long as the application runs or until the user explicitly closes the dialog box.

To support the different ways applications use dialog boxes, Windows provides two types of dialog box: modal and modeless. A modal dialog box requires the user to supply information or cancel the dialog box before allowing the application to continue. Applications use modal dialog boxes in conjunction with commands that require additional information before they can proceed. A modeless dialog box allows the user to supply information and return to the previous task without closing the dialog box. Modal dialog boxes are simpler to manage than modeless dialog boxes because they are created, perform their task, and are destroyed by calling a single function.

To create either a modal or modeless dialog box, an application must supply a dialog box template to describe the dialog box style and content and a dialog box procedure to carry out tasks. The dialog box template is a binary description of the dialog box and the controls it contains. The developer can create this template as a resource to be loaded from the application's executable file, or created in memory while the application runs. The dialog box procedure is an application-defined callback function that Windows calls when it has input for the dialog box or tasks for the dialog box to carry out. Although a dialog box procedure is similar to a window procedure, it does not have the same responsibilities.

An application typically creates a dialog box by using either the DialogBox or CreateDialog function. DialogBox creates a modal dialog box; CreateDialog creates a modeless dialog box. These functions load a dialog box template from the application's executable file and create a pop-up window that matches the template's specifications. There are other functions that create dialog boxes by using templates in memory and pass additional information to the dialog box procedure as the dialog box is created.

Dialog boxes usually belong to a predefined, exclusive window class. Windows uses this window class and its corresponding window procedure for both modal and modeless dialog boxes. When the function is called, it creates the window for the dialog box, as well as the windows for all controls in the dialog box, then sends selected messages to the dialog box procedure. While the dialog box is visible, the predefined window procedure manages all messages, processing some messages and passing others to the dialog box procedure so that the procedure can carry out tasks. Applications do not have direct access to the predefined window class or window procedure, but they can use the dialog box template and dialog box procedure to modify the style and behavior of a dialog box.


  18.1.2  Owner Window

Most dialog boxes have an owner window (or more simply, an owner). When creating the dialog box, the application sets the owner by specifying the owner's window handle. Windows uses the owner to determine the position of the dialog box in the Z order so that a dialog box is always positioned above its owner. Also, Windows can send messages to the window procedure of the owner, notifying it of events in the dialog box.

Windows automatically hides or destroys the dialog box whenever its owner is hidden or destroyed. This means the dialog box procedure requires no special processing to detect changes to the state of the owner window.

Because the typical dialog box is used in conjunction with a command in a menu, the owner window is usually the window containing the menu. Although it is possible to create a dialog box that has no owner, it is not recommended. For example, when a modal dialog box has no owner, Windows does not disable any of the application's other windows and allows the user to continue to carry out work in the other windows, defeating the purpose of the modal dialog box.

When a modeless dialog box has no owner, Windows neither hides nor destroys the dialog box when other windows in the application are hidden or destroyed. Although this does not defeat the purpose of the modeless dialog box, it requires that the application carry out special processing to ensure the dialog box is hidden and destroyed at appropriate times.


  18.1.3  Message Boxes

A message box is a special dialog box that an application can use to display messages and prompt for simple input. A message box typically contains a text message and one or more push buttons. An application creates the message box by using the MessageBox function, specifying the text and the number and types of buttons to display.

Although the message box is a dialog box, Windows takes complete control of the creation and management of the message box. This means the application does not provide a dialog box template and dialog box procedure. Windows creates its own template based on the text and buttons specified for the message box and supplies its own dialog box procedure.

A message box is a modal dialog box and Windows creates it by using the same internal functions that the DialogBox function uses. If the application specifies an owner window when calling MessageBox, Windows disables the owner. An application can also direct Windows to disable all top-level windows belonging to the current task by specifying the MB_TASKMODAL value when creating the dialog box.

Windows can send messages to the owner, such as the WM_CANCELMODE and WM_ENABLE, just as it does when creating a modal dialog box. The owner window should carry out any actions requested by these messages.


  18.1.4  Modal Dialog Boxes

A modal dialog box should be a pop-up window having a System menu, a title bar, and a thick border; that is, the dialog box template should specify the WS_POPUP, WS_SYSMENU, WS_CAPTION, and DS_MODALFRAME styles. Although an application can designate the WS_VISIBLE style, Windows always displays a modal dialog box regardless of whether the dialog box template specifies the WS_VISIBLE style. An application must not create a modal dialog box having the WS_CHILD style. A modal dialog box with this style disables itself, preventing any subsequent input from reaching the application.

An application creates a modal dialog box by using the DialogBox or DialogBoxIndirect function. DialogBox requires the name or identifier of a resource containing a dialog box template; DialogBoxIndirect requires the handle of a memory object containing a dialog box template. The DialogBoxParam and DialogBoxIndirectParam functions also create modal dialog boxes; they are identical to the previously mentioned functions but pass a specified parameter to the dialog box procedure when the dialog box is created.

When creating the modal dialog box, Windows makes it the active window. The dialog box remains active until the dialog box procedure calls the EndDialog function or Windows activates a window in another application. Neither the user nor the application can make the owner window active until the modal dialog box is destroyed.

When the owner window is not already disabled, Windows automatically disables the window and any child windows belonging to it when it creates the modal dialog box. The owner window remains disabled until the dialog box is destroyed. Although a dialog box procedure could potentially enable the owner window at any time, enabling the owner defeats the purpose of the modal dialog box and is not recommended. When the dialog box procedure is destroyed, Windows enables the owner window again, but only if the modal dialog box caused the owner to be disabled.

As Windows creates the modal dialog box, it sends the WM_CANCELMODE message to the window (if any) currently capturing mouse input. An application that receives this message should release the mouse capture so that the user can move the mouse in the modal dialog box. Because Windows disables the owner window, all mouse input is lost if the owner fails to release the mouse upon receiving this message.

To process messages for the modal dialog box, Windows starts its own message loop, taking temporary control of the message queue for the entire application. When Windows retrieves a message that is not explicitly for the dialog box, it dispatches the message to the appropriate window. If it retrieves a WM_QUIT message, it posts the message back to the application message queue so that the application's main message loop can eventually retrieve the message.

Windows sends the WM_ENTERIDLE message to the owner window whenever the application message queue is empty. The application can use this message to carry out a background task while the dialog box remains on the screen. When an application uses the message in this way, the application must frequently yield control (for example, by using the PeekMessage function) so that the modal dialog box can receive any user input. An application can prevent the modal dialog box from sending the WM_ENTERIDLE messages by specifying the DS_NOIDLEMSG style when creating the dialog box.

An application destroys a modal dialog box by using the EndDialog function. In most cases, the dialog box procedure calls EndDialog when the user chooses the Close command from the dialog box's System menu or presses the OK or Cancel button in the dialog box. The dialog box can return a value through the DialogBox function (or other creation function) by specifying a value when it calls the EndDialog function. Windows returns this value after destroying the dialog box. Most applications use this return value to determine whether the dialog box completed its task successfully or was canceled by the user. Windows does not return control from the function that creates the dialog box until the dialog box procedure has called the EndDialog function.


  18.1.5  Modeless Dialog Boxes

A modeless dialog box should be a pop-up window having a System menu, a title bar, and a thin border; that is, the dialog box template should specify the WS_POPUP, WS_CAPTION, WS_BORDER, and WS_SYSMENU styles. Windows does not automatically display the dialog box unless the template specifies the WS_VISIBLE style.

An application creates a modeless dialog box using the CreateDialog or CreateDialogIndirect function. CreateDialog requires the name or identifier of a resource containing a dialog box template; CreateDialogIndirect requires the handle of a memory object containing a dialog box template. The CreateDialogParam and CreateDialogIndirectParam functions also create modeless dialog boxes; they pass a specified parameter to the dialog box procedure when the dialog box is created.

CreateDialog and other creation functions return a window handle for the dialog box. The application and the dialog box procedure can use this handle to manage the dialog box. For example, if WS_VISIBLE is not given in the dialog box template, the application can display the dialog box by passing the window handle to the ShowWindow function.

A modeless dialog box neither disables the owner window nor sends messages to it. When creating the dialog box, Windows makes it the active window, but the user or the application can change the active window at any time. If the dialog box becomes inactive, it remains above the owner window in the Z order, even if the owner window is active.

The application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and select controls by using the keyboard, the application must call the IsDialogMessage function. For more information about this function, see Section 18.1.8, »Dialog Box Keyboard Interface«.

A modeless dialog box cannot return a value to the application as a modal dialog box does, but the dialog box procedure can send information to the owner window by using the SendMessage function.

An application must destroy all modeless dialog boxes before terminating. It can destroy a modeless dialog box by using the DestroyWindow function. In most cases, the dialog box procedure calls DestroyWindow in response to user input, such as clicking the Cancel button. If the user never closes the dialog box in this way, the application must call DestroyWindow.

The DestroyWindow function invalidates the window handle for the dialog box, so any subsequent calls to functions that use the handle return error values. To prevent errors, the dialog box procedure should notify the owner that the dialog box has been destroyed. Many applications maintain a global variable containing the handle for the dialog box . When the dialog box procedure destroys the dialog box, it also sets the global variable to NULL, indicating that the dialog box is no longer valid.

The dialog box procedure must not call the EndDialog function to destroy a modeless dialog box.


  18.1.6  Dialog Box Template

A dialog box template is binary data that describes the dialog box, defining its height, width, style, and the controls it contains. To create a dialog box, Windows either loads a dialog box template from the resources in the application's executable file or uses the template passed to it in global memory by the application. In either case, the application is responsible for supplying a template when it creates a dialog box.

A developer creates template resources by using a resource compiler or a dialog box editor. A resource compiler converts a text description into a binary resource, and a dialog box editor saves an interactively constructed dialog box as a binary resource.

Note   An explanation of how to create template resources and add them to the application's executable file is beyond the scope of this book. For more information, see the documentation provided with your application development tools.

Applications that create dialog boxes without using template resources must create templates in memory and pass the templates to the DialogBoxIndirect or CreateDialogIndirect function. An application creates a memory template by allocating a global memory object and filling it with a DLGTEMPLATE structure and one or more DLGITEMTEMPLATE structures. A memory template is identical in form and content to a template resource. Many applications that use memory templates first load a template resource into memory by using the the LoadResource function, then modify the loaded resource to create a new memory template.

The following sections describe the styles, measurements, and other values used in a dialog box template.


  18.1.6.1  Styles

Every dialog box template specifies a combination of style values that define the appearance and features of the dialog box. The style values can be window styles, such as WS_POPUP and WS_SYSMENU, and dialog box styles, such as DS_MODALFRAME. The number and type of styles for a template depends on the type and purpose of the dialog box.

Windows passes all window styles given in the template to the CreateWindowEx function when it creates the dialog box. Windows may pass one or more extended styles depending on the given dialog box styles. For example, when the template specifies the DS_MODALFRAME style, Windows uses the WS_EX_DLGMODALFRAME style when creating the dialog box. When the template specifies the DS_SYSMODAL style, Windows uses the WS_EX_TOPMOST style. All other dialog box styles affect how Windows manages the dialog box.

Most dialog boxes are pop-up windows that have a system menu and a title bar. Therefore, the typical template specifies the WS_POPUP, WS_SYSMENU, and WS_CAPTION styles. The template also specifies a border style: DS_MODALFRAME for modal dialog boxes, and WS_BORDER for modeless dialog boxes. A template may specify a window type other than pop-up (such as WS_OVERLAPPED) if it creates a customized window instead of a dialog box.

Windows always displays a modal dialog box regardless of whether the WS_VISIBLE style is given. When the template for a modeless dialog box specifies the WS_VISIBLE style, Windows automatically displays the dialog box when it is created. Otherwise, the application is responsible for displaying the dialog box by using the ShowWindow function.

The template can specify the DS_SETFOREGROUND style to force Windows to bring the dialog box to the foreground. This is especially useful for modal dialog boxes that require immediate attention from the user regardless of whether the owner window is the foreground window. This style is available in Windows NT only.

The DS_ABSALIGN style causes Windows to interpret dialog box measurements as screen coordinates; DS_SETFONT causes Windows to use a given font, instead of the system font, to draw text in the dialog box client area and in the controls in the dialog box; and DS_NOIDLEMSG prevents a modal dialog box from sending WM_ENTERIDLE messages to the owner window. These styles are described in more detail in later sections in this chapter.

The DS_SYSMODAL and DS_LOCALEDIT styles apply to applications written for Windows 3.x. Windows NT does not allow system modal dialog boxes but does ensure that dialog boxes with this style receive the WS_EX_TOPMOST style. Windows NT ignores the DS_LOCALEDIT style.

Portability Issue   Windows NT does not support system modal dialog boxes. When creating modal dialog boxes, Windows NT ignores the DS_SYSMODAL style if it is given in the dialog box template. Applications should not depend on the behavior of a system modal dialog box.


  18.1.6.2  Dialog Box Measurements

Every dialog box template contains measurements that specify the position, width, and height of the dialog box and the controls it contains. These measurements are device independent, so an application can use a single template to create the same dialog box for all types of display devices. This ensures that a dialog box will have the same proportions and appearance on all screens despite differing resolutions and aspect ratios between screens.

Dialog box measurements are given in dialog base units. One horizontal unit is equal to one-fourth of the average character width for the system font. One vertical unit is equal to one-eighth of the average character height for the system font. An application can retrieve the number of pixels per base unit for the current display by using the GetDialogBaseUnits function. An application can convert measurements from dialog base units to pixels by using the MapDialogRect function.

The template must specify the initial coordinates of the upper left corner of the dialog box. Usually the coordinates are relative to the upper left corner of the owner window's client area. When the template specifies the DS_ABSALIGN style or the dialog box has no owner, the position is relative to the upper left corner of the screen. Windows sets this initial position when it creates the dialog box, but permits an application to adjust the position before displaying the dialog box. For example, an application can retrieve the dimensions of the owner window, calculate a new position that centers the dialog box in the owner window, then set the position by using the SetWindowPos function.

The template should specify a dialog box width and height that does not exceed the width and height of the screen and ensures that all controls and are within the client area of the dialog box. Although Windows permits a dialog box to be any size, creating one that is too small or too large can prevent the user from providing input, defeating the purpose of the dialog box. Many applications use more than one dialog box when there are a large number of controls. In such cases, the initial dialog box usually contains one or more push buttons that the user can click to display the next dialog box.


  18.1.6.3  Controls

The template specifies the position, width, height, style, identifier, and window class for each control in the dialog box. Windows creates each control by passing this data to the CreateWindowEx function. Controls are created in the order they are given in the template. The template should specify the appropriate number, type, and order of controls to ensure that the user can enter the input needed to complete the command associated with the dialog box.

For each control, the template specifies style values that define the appearance and operation of the control. Every control is a child window and therefore must have the WS_CHILD style. To ensure that the control is visible when the dialog box is displayed, each control must also have the WS_VISIBLE style. Other commonly used window styles are WS_BORDER for controls that have optional borders, WS_DISABLED for controls that should be disabled when the dialog box is initially created, and WS_TABSTOP and WS_GROUP for controls that can be accessed using the keyboard. The WS_TABSTOP and WS_GROUP styles are used in conjunction with the dialog keyboard interface described later in this chapter.

The template may also specify control style values that are specific to the control's window class. For example, a template that specifies a button control must give a button control style such as BS_PUSHBUTTON or BS_CHECKBOX. Windows passes the control styles to the control window procedure through the WM_CREATE message, allowing the procedure to adapt the appearance and operation of the control.

Windows converts the position coordinates and the width and height measurements from dialog base units to pixels, before passing these to the CreateWindowEx function. When Windows creates a control, it specifies the dialog box as the parent window. This means Windows always interprets the position coordinates of the control as client coordinates, relative to the upper left corner of the dialog box's client area.

The template specifies the window class for each control. A typical dialog box contains controls belonging to the predefined control window classes, such as the button and edit control window classes. In this case, the template specifies window classes by giving the corresponding predefined atom values for the classes. When a dialog box contains a control belonging a custom control window class, the template gives the name of that registered window class or the atom value currently associated with the name.

Each control in a dialog box must have a unique identifier to distinguish it from other controls. Controls send information to the dialog box procedure through WM_COMMAND messages, so the control identifiers are essential for the procedure to determine which control sent a given message. The only exception to this rule are control identifiers for static controls. Static controls do not require unique identifiers because they send no WM_COMMAND messages.

To permit the user to close the dialog box, the template should specify at least one push button and give it the control identifier IDCANCEL. To permit the user to choose between completing or canceling the command associated with the dialog box, the template should specify two push buttons, labeled OK and Cancel. In this case, the control identifier for the OK button should be IDOK and, for the Cancel button, IDCANCEL.

A template also specifies optional text and creation data for a control. The text typically provides labels for button controls or specifies the initial content of a static text control. The creation data is one or more bytes of data that Windows passes to the control window procedure when creating the control. Creation data is useful for controls that require more information about their initial content or style than is given by other data. For example, an application can use creation data to set the initial setting and range for a scroll bar control.


  18.1.6.4  System Menu

Windows gives a dialog box a System menu when the template specifies the WS_SYSMENU style. To prevent inappropriate command input, Windows automatically disables all commands in the menu except the Move and Close commands. The user can use the Move command to move the dialog box. When the user chooses the Close command, Windows sends a WM_COMMAND message to the dialog box procedure with the wParam parameter set to IDCANCEL. This is identical to the message sent by the Cancel button when the user chooses it. The recommended action for this message is to close the dialog box and cancel the requested command or task.

Although other menus in dialog boxes are not recommended, a dialog box template can specify a menu by supplying the identifier or the name of a menu resource. In this case, Windows loads the resource and creates the menu for the dialog box. Applications typically use menu identifiers or names in templates when using the templates to create custom windows rather than dialog boxes.


  18.1.6.5  Fonts

Windows draws all text in dialog box using the system font by default. An application can direct Windows to use another font by setting the DS_SETFONT style for the dialog box and specifying a point size and typeface name. Although a dialog box template can specify a font, Windows always uses the system font for the title and menus of the dialog box; the DS_SETFONT style does not change this.

When the DS_SETFONT style is specified, the system sends a WM_SETFONT message to the dialog box procedure and to each control as it creates the control. The dialog box procedure is responsible for saving the font handle passed with the WM_SETFONT message and selecting the handle into the display device context whenever it writes text to the window. Predefined controls do this by default.

When the DS_SETFONT style is given, Windows uses the average character width of the font to calculate the position and dimensions of the dialog box. Otherwise, it uses the average character width of the system font.


  18.1.6.6  Templates in Memory

A template in memory consists of a DLGTEMPLATE structure and related data followed by one or more DLGITEMTEMPLATE structures and related data. There is one DLGITEMTEMPLATE structure for each control in the dialog box.

The DLGTEMPLATE structure specifies the position, width, height, style, and number of controls in the dialog box. Additional data following the structure specifies the optional menu, class, title, and font for the dialog box. The DLGTEMPLATE structure has the following form.

typedef struct { /* dltt */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  cdit;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

} DLGTEMPLATE;

The style member specifies the window and dialog box styles for the dialog box. Windows does not use the dwExtendedStyle member when creating a dialog box. An application that uses templates to create other types of windows can use this member to specify extended window styles for the other windows. The x and y members specify the dialog box position; cx and cy specify the width and height. The cdit member specifies the number of controls in the dialog box and is the same as the number of DLGITEMTEMPLATE structures in the template.

The DLGTEMPLATE structure is immediately followed by a 16-bit value that specifies whether the dialog box has a menu. When the value is 0x0000, the dialog box has no menu. When the value is 0xFFFF, the subsequent 16-bit value specifies the identifier of the menu resource that describes the dialog box's menu. When the initial value is neither 0x0000 nor 0xFFFF, Windows assumes it is the start of a null-terminated string specifying the name of the menu resource that describes the dialog box's menu.

The first 16-bit value following the menu identifier or name specifies the window class to which the dialog box belongs. When the value is 0x0000, Windows uses the predefined dialog box class for the dialog box. When the value is 0xFFFF, the subsequent 16-bit value is an atom value identifying a registered window class. When the initial value is neither 0x0000 nor 0xFFFF, Windows assumes it is the start of a null-terminated string identifying a registered window class.

The dialog box title immediately follows the class atom or name. The title is a null-terminated string. When the string is empty, Windows leaves the title bar for the dialog box blank. When the dialog box does not have the WS_CAPTION style, Windows sets the title to the given string but does not display it.

When the dialog box has the DS_SETFONT style, the dialog box title is immediately followed by a 16-bit value specifying the point size and by a null-terminated string specifying the typeface for the font. Windows uses this data to create a font for use when writing text in the dialog box client area and in each control. When the dialog box does not have the DS_SETFONT style, the 16-bit value and string are not part of the template.

Each DLGITEMTEMPLATE structure in the template contains data specifying the position, width, height, style, and identifier of the control. Additional information follows each structure, specifying the window class to which the control belongs, the initial text for the control, and any other creation data needed to create the control. A DLGITEMTEMPLATE structure has the following form:

typedef struct { /* dlit */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

    WORD  id;

} DLGITEMTEMPLATE;

The style member specifies the control style. This member is a combination of window-style flags, such as BS_PUSHBUTTON and WS_VISIBLE. Windows does not use the dwExtendedStyle member to create controls for dialog boxes. Applications that use templates to create other types of windows can use this member to specify extended window styles for those controls. The x and y members specify the coordinates of the upper-left corner of the control; cx and cy specify the width and height of the control. The id member is the control identifier.

The control's window class is specified by an atom or name immediately following the DLGITEMTEMPLATE structure. When the first 16-bit value after the structure is 0xFFFF, the subsequent 16-bit value is an atom value identifying a registered window class. Otherwise, the first value is the start of a null-terminated string specifying the name of a registered window class.

The control text starts on the first 16-bit boundary after the class atom or name. This text is either two 16-bit values specifying a resource identifier or a null- terminated string specifying the initial text for the control. If this member is a resource identifier, the first 16-bit value is 0xFFFF and the second is the identifier. Resource identifiers are usually given for controls, such as static icon controls, that load and display icons or other resources rather than displaying text.

Any additional creation data required by the control follows the control text. Windows passes this data to the control as the creation parameters when it calls the CreateWindowEx function.


  18.1.7  Dialog Box Procedure

A dialog box procedure is similar to a window procedure in that Windows sends messages to the procedure when it has information to give or tasks to carry out. Unlike a window procedure, a dialog box procedure never calls the DefWindowProc function. Instead, it returns the Boolean value TRUE if it processes a message or FALSE if it does not.

Every dialog box procedure has the following form:

BOOL APIENTRY DlgProc(hwndDlg, message, wParam, lParam)

HWND hwndDlg;

UINT message;

WPARAM wParam;

LPARAM lParam;

{

    switch (message) {

        /* Place message cases here. */

        default:

            return FALSE;

    }

}

The procedure parameters serve the same purpose as in a window procedure, with the hwndDlg parameter receiving the window handle of the dialog box.

Most dialog box procedures process the WM_INITDIALOG message and the WM_COMMAND messages sent by the controls, but process few if any other messages. If a dialog box procedure does not process a message, it must return FALSE to direct Windows to process the messages internally. The only exception to this rule is the WM_INITDIALOG message. The dialog box procedure must return TRUE to direct Windows to further process the WM_INITDIALOG message. In any case, the procedure must not call DefWindowProc.


  18.1.7.1  The WM_INITDIALOG Message

Windows does not send a WM_CREATE message to the dialog box procedure. Instead it sends a WM_INITDIALOG message when it creates the dialog box and all its controls, but before it displays the dialog box. The procedure should carry out any initialization required to ensure that the dialog box displays the current settings associated with the command or task. For example, when a dialog box contains a control to show the current drive and directory, the procedure must determine the current drive and directory and set the control to that value.

The procedure can initialize controls by using functions such as SetDlgItemText and CheckDlgButton. Because controls are windows, the procedure can also manipulate them by using window-management functions such as EnableWindow and SetFocus. The procedure can retrieve the window handle for a control by using the GetDlgItem function.

The dialog box procedure can change the contents, state, and position of any control as needed. For example, in a dialog box that contains a list box of filenames and an Open button, the procedure can disable the Open button until the user selects a file from the list. In this example, the dialog box template specifies the WS_DISABLED style for the Open button and Windows automatically disables the button when creating it. When the dialog box procedure receives a notification message from the list box indicating that the user has selected a file, the procedure calls the EnableWindow function to enable the Open button.

If the application creates the dialog box by using the DialogBoxParam, DialogBoxIndirectParam, CreateDialogParam, or CreateDialogIndirectParam function, the lParam parameter for the WM_INITDIALOG message contains the extra parameter passed to the function. Applications typically use this extra parameter to pass the address of additional initialization information to the dialog box procedure, but the dialog box procedure must determine the meaning of the parameter. If the application uses another function to create the dialog box, Windows sets the lParam parameter to NULL.

Before returning from the WM_INITDIALOG message, the procedure should determine whether it should set the input focus to a given control. If the dialog box procedure returns TRUE, Windows automatically sets the input focus to the control whose window handle is in the wParam parameter. If the control receiving the default focus is not appropriate, it can set the focus to the appropriate control by using the SetFocus function. If the procedure sets the input focus, it must return FALSE to prevent Windows from setting the default focus. The control receiving the default input focus is always the first control given in the template that is visible, not disabled, and has the WS_TABSTOP style. If no such control exists, Windows sets the default input focus to the first control in the template.


  18.1.7.2  The WM_COMMAND Message

A control can send a WM_COMMAND message to the dialog box procedure when the user carries out an action in the control. These messages, called notification messages, inform the procedure of user input and permit it to carry out appropriate responses.

All predefined controls, except static controls, send notification messages for selected user actions. For example, a push button sends the BN_CLICKED notification message whenever the user chooses the button. In all cases, the low word of the wParam parameter contains the control identifier, the high word of wParam contains the notification code, and the lParam parameter contains the control window handle.

Portability Issue   In Windows NT, the placement of the notification code has moved from the lParam parameter to the wParam parameter. When porting your Windows 3.x−applications to Windows NT, modify the code that processes notification messages to accommodate this change in placement.

The dialog box procedure should monitor and process notification messages. In particular, the procedure must process messages having the IDOK or IDCANCEL identifiers; these messages represent a request by the user to close the dialog box. The procedure should close the dialog box by using the EndDialog function for modal dialog boxes and the DestroyWindow function for modeless dialog boxes.

Windows also sends WM_COMMAND messages to the dialog box procedure if the dialog box has a menu, such as the System menu, and the user chooses a command. In particular, Windows sends a WM_COMMAND message with the wParam parameter set to IDCANCEL whenever the user chooses the Close command in the dialog box's System menu. The message is nearly identical to the notification message sent by the Cancel button and should be processed in exactly the same way.


  18.1.7.3  The WM_PARENTNOTIFY Message

A control sends a WM_PARENTNOTIFY message whenever the user presses a mouse button while pointing to the control. Some applications interpret this message as a signal to carry out an action related to the control, such as displaying a line of text describing to purpose of the control.

Ordinarily, Windows also sends WM_PARENTNOTIFY messages when it creates and destroys a window, but not for controls created from a dialog box template. Windows prevents these messages by specifying the WS_EX_NOPARENTNOTIFY style when creating the controls. An application cannot override this default behavior unless it creates its own controls for the dialog box.


  18.1.7.4  The Control-Color Messages

Controls and Windows can send control-color messages when they want the dialog box procedure to paint the background of a control or other window by using a specific brush and colors. This can be useful when applications override the default colors used in dialog boxes and their controls. Following are the control-color messages.

WM_CTLCOLORBTN
WM_CTLCOLORDLG
WM_CTLCOLOREDIT
WM_CTLCOLORLISTBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC

A control sends a control-color message to the dialog box procedure just before it paints its own background. The message allows the procedure to specify which brush to use and to set the background and foreground colors. The procedure specifies a brush by returning the brush handle. To set the background and foreground colors, the procedure uses the SetBackgroundColor and SetTextColor functions with the control's display device context. The control-color message passes a handle of the display device context to the procedure in the message's wParam parameter.

Windows sends a WM_CTLCOLORDLG message to the dialog box procedure if the dialog procedure does not process the WM_ERASEBKGND message. The predefined dialog box class does not have a class background brush, so this message lets the procedure define its own background without having to include the code to carry out the work.

In any case, when a dialog box procedure does not process a control-color message, Windows uses a brush with the default window color to paint the background for all controls and windows except scroll bars. An application can retrieve the default window color by passing the COLOR_WINDOW value to the GetSysColor function. While the background is painted, the foreground color for the display device context is set to the default text color (COLOR_WINDOWTEXT). For scroll bars, Windows uses a brush having the default scroll bar color (COLOR_SCROLLBAR). In this case, the background and foreground colors for the display device context are set to white and black, respectively.

Portability Issue   In Windows NT, the WM_CTLCOLOR message has been replaced by the set of control-color messages. When porting your Windows 3.x−based application to Windows NT, remember to modify the code to accommodate this change.


  18.1.7.5  Default Message Processing

The window procedure for the predefined dialog box class carries out default processing for all messages that the dialog box procedure does not process. When the dialog box procedure returns FALSE for any message, the predefined window procedure checks the messages and carries out the following default actions:

Message	Default action
DM_GETDEFID	Returns the control identifier of the default push button if it exists. Otherwise, return zero.
DM_SETDEFID	Sets the control specified by the control identifier in the wParam parameter to the default push button.
WM_ACTIVATE	Restores the input focus to the control identified by the previously saved handle if the dialog box is activated. Otherwise, the procedure saves the handle of the control having the input focus.
WM_CHARTOITEM	Returns zero.
WM_CLOSE	Posts the BN_CLICKED notification message to the dialog box, specifying IDCANCEL as the control identifier. If the dialog box has an IDCANCEL control identifier and the control is currently disabled, the procedure sounds a warning and does not post the message.
WM_COMPAREITEM	Returns zero.
WM_ERASEBKGND	Fills the dialog box client area using the brush returned from the WM_CTLCOLORDLG message or with the default window color.
WM_GETFONT	Returns the handle of the application-defined dialog box font.
WM_INITDIALOG	Returns zero.
WM_LBUTTONDOWN	Sends a CB_SHOWDROPDOWN message to the combo box having the input focus, directing the control to hide its dropdown list box. The procedure calls the DefWindowProc function to complete the default action.
WM_NCDESTROY	Releases global memory allocated for edit controls in the dialog box (applies to dialog boxes in Windows 3.x applications that specify the DS_LOCALEDIT style) and frees any application-defined font (applies to dialog boxes that specify the DS_SETFONT style). The procedure calls the DefWindowProc function to complete the default action.
WM_NCLBUTTONDOWN	Sends a CB_SHOWDROPDOWN message to the combo box having the input focus, directing the control to hide its dropdown list box. The procedure calls the DefWindowProc function to complete the default action.
WM_NEXTDLGCTL	Sets the input focus to the next or previous control in the dialog box, or sets the focus to the control identified by the handle in the wParam parameter, or sets the focus to the first control in the dialog box that is visible, not disabled, and has the WS_TABSTOP style. The procedure ignores this message if the current window with the input focus is not a control.
WM_SETFOCUS	Sets the input focus to the control identified by a previously saved control window handle. If no such handle exists, the procedure sets the input focus to the first control in the dialog box template that is visible, not disabled, and has the WS_TABSTOP style. If no such control exists, the procedure sets the input focus to the first control in the template.
WM_SHOWWINDOW	Saves the handle of the control having the input focus if the dialog box is being hidden, then calls the DefWindowProc function to complete the default action.
WM_SYSCOMMAND	Saves the handle of the control having the input focus if the dialog box is being minimized, then calls the DefWindowProc function to complete the default action.
WM_VKEYTOITEM	Returns zero.
The predefined window procedure passes all other messages to the DefWindowProc function for default processing.


  18.1.8  Dialog Box Keyboard Interface

Windows provides a special keyboard interface for dialog boxes that carries out special processing for several keys. The interface generates messages that correspond to certain buttons in the dialog box or changes the input focus from one control to another. Following are the keys used in this interface and the respective actions.

Key	Action
ALT+mnemonic	Moves the input focus to the first control (having the WS_TABSTOP style) after the static control containing the given mnemonic.
DOWN	Moves the input focus to the next control in the group.
ENTER	Sends a WM_COMMAND message to the dialog box procedure. The wParam parameter is set to IDOK or control identifier of the default push button.
ESC	Sends a WM_COMMAND message to the dialog box procedure. The wParam parameter is set to IDCANCEL.
LEFT	Moves the input focus to the previous control in the group.
mnemonic	Moves the input focus to the first control (having the WS_TABSTOP style) after the static control containing the given mnemonic.
RIGHT	Moves the input focus to the next control in the group.
SHIFT+TAB	Moves the input focus to the previous control that has the WS_TABSTOP style.
TAB	Moves the input focus to the next control that has the WS_TABSTOP style.
UP	Moves the input focus to the previous control in the group.
The Win32 application programming interface (API) automatically provides the keyboard interface for all modal dialog boxes. It does not provide the interface for modeless dialog boxes unless the application calls the IsDialogMessage function to filter messages in its main message loop. This means that the application must pass the message to IsDialogMessage immediately after retrieving the message from the message queue. The function processes the messages if it is for the dialog box and returns a nonzero value to indicate that the message has been processed and must not be passed to the TranslateMessage or DispatchMessage function.

Because the dialog box keyboard interface uses direction keys to move between controls in a dialog box, an application cannot use these keys to scroll the contents of any modal dialog box or any modeless dialog box for which the IsDialogMessage function is called. When a dialog box has scroll bars, the application must provide an alternate keyboard interface for the scroll bars. Note that the mouse interface for scrolling is available when the system includes a mouse.


  18.1.8.1  The WS_TABSTOP Style

The TAB key and SHIFT+TAB keys have no effect when the controls in the dialog box do not have the WS_TABSTOP style. Windows looks for these styles as it searches for the next control in the dialog box to receive the input focus.

When the user presses TAB or SHIFT+TAB, Windows first determines whether the control having the input focus processes these keys. It sends a WM_GETDLGCODE message to the control, and if the control returns the DLGC_WANTTAB value, Windows passes the keys to the control. Otherwise, Windows uses the GetNextDlgTabItem function to locate the next control that is visible, not disabled, and has the WS_TABSTOP style. The search starts with the control currently having the input focus and proceeds in the order in which the controls were created — that is, the order in which they are defined in the dialog box template. When the system locates a control having the required characteristics, Windows moves the input focus to it.

An application can also use GetNextDlgTabItem to locate controls having the WS_TABSTOP style. The function retrieves the window handle of the next or previous control having the WS_TABSTOP style without moving the input focus.


  18.1.8.2  The WS_GROUP Style

By default, Windows moves the input focus to the next or previous control whenever the user presses a direction key. As long as the current control with the input focus does not process these keys and the next or previous control is not a static control, Windows continues to move the input focus through all controls in the dialog box as the user continues to press the direction keys.

An application can use the WS_GROUP style to modify this default behavior. The style marks the beginning of a group of controls. If a control in the group has the input focus when the user begins pressing direction keys, the focus remains in the group. In general, the first control in a group must have the WS_GROUP style and all other controls in the group must not have this style. All controls in the group must be contiguous; that is, they must have been created consecutively with no intervening controls.

When the user presses a direction key, Windows first determines whether the current control having the input focus processes the direction keys. Windows sends a WM_GETDLGCODE message to the control and if the control returns the DLGC_WANTARROWS value, passes the key to the control. Otherwise, Windows uses the GetNextDlgGroupItem function to determine the next control in the group.

The GetNextDlgGroupItem function searches controls in the order (or reverse order) they were created. If the user presses the RIGHT or DOWN keys, GetNextDlgGroupItem returns the next control if that control does not have WS_GROUP style. Otherwise, the function reverses the order of the search and returns the first control that has the WS_GROUP style. If the user presses the LEFT or UP keys, GetNextDlgGroupItem returns the previous control unless the current control already has the WS_GROUP style. If the current control has this style, the function reverses the order of the search, locates the first control having the WS_GROUP style, and returns the control that immediately precedes the located control.

Once Windows has the next or previous control, it sends a WM_GETDLGCODE message to the control to determine the control type. Windows then moves the input focus to control if it is not a static control. If the control is an automatic radio button, Windows sends a BM_CLICK message to it. An application can also use the GetNextDlgGroupItem function to locate controls in a group.

Generally, the first control in the group combines the WS_GROUP and WS_TABSTOP styles so that the user can move from group to group by using the TAB key. If the group contains radio buttons, the application should apply the WS_TABSTOP style only to the first control in the group. Windows automatically moves the style when the user moves between controls in the group. This ensures that the input focus will always be on the most recently selected control when the user moves to the group using the TAB key.


  18.1.8.3  Mnemonics

A mnemonic is a selected letter or digit in the label of a button or in the text of a static control. Windows moves the input focus to the control associated with the mnemonic whenever the user either presses the key that corresponds to the mnemonic or presses this key and the ALT key in combination. Mnemonics provide a quick way for the user to move to a given control by using the keyboard.

An application creates a mnemonic for a control by inserting the ampersand (&) immediately before the selected letter or digit in the label or text for the control. In most cases, the null-terminated string provided with the control in the dialog box template contains the ampersand. However, an application can create a mnemonic at any time by replacing a control's existing label or text by using the SetDlgItemText function. Only one mnemonic can be given for each control. Although it is recommended, mnemonics in a dialog box need not be unique.

When the user presses a letter or digit key, Windows first determines whether the current control having the input focus processes the key. Windows sends a WM_GETDLGCODE message to the control, and if the control returns the DLGC_WANTALLKEYS or DLG_WANTMESSAGE values, Windows passes the key to the control. Otherwise, it searches for a control whose mnemonic matches the given letter or digit. It continues to search until it locates a control or has examined all controls. During the search, it skips any static controls that have the SS_NOPREFIX style.

If Windows locates a static control and the control is not disabled, Windows moves the input focus to the first control after the static control that is visible, not disabled, and that has the WS_TABSTOP style. If Windows locates some other control that has a matching mnemonic, it moves the input focus to that control. If the control is a default push button, Windows sends a BN_CLICKED notification message to the dialog box procedure. If the control is another style of button and there is no other control in the dialog box having the same mnemonic, Windows sends the BM_CLICK message to the control.


  18.1.9  Dialog Box Settings

The dialog box settings are the current selections and values for the controls in the dialog box. The dialog box procedure is responsible for initializing the controls to these settings when creating the dialog box. It is also responsible for retrieving the current settings from the controls before destroying the dialog box. The methods used to initialize and retrieve settings depend on the type of control.


  18.1.9.1  Radio Buttons and Check Boxes

Dialog boxes use radio buttons and check boxes to let the user choose from a list of options. Radio buttons let the user choose from mutually exclusive options; check boxes let the user pick a combination of options.

The dialog box procedure can set the initial state of a check box by using the CheckDlgButton function, which sets or clears the check box. For radio buttons in a group of mutually exclusive radio buttons, the dialog box procedure can use the CheckRadioButton function to set the appropriate radio button and automatically clear any other radio button.

Before a dialog box terminates, the dialog box procedure can check the state of each radio button and check box by using the IsDlgButtonChecked function, which returns the current state of the button. A dialog box typically saves this information to initialize the buttons the next time it creates the dialog box.


  18.1.9.2  Edit Controls

Many dialog boxes have edit controls that let the user supply text as input. Most dialog box procedures initialize an edit control when the dialog box first starts. For example, the dialog box procedure may place a proposed filename in the control that the user can then select, modify, or replace. The dialog box procedure can set the text in an edit control by using the SetDlgItemText function, which copies text from a given buffer to the edit control. When the edit control receives the input focus, it automatically selects the complete text for editing.

Because edit controls do not automatically return their text to the dialog box, the dialog box procedure must retrieve the text before it terminates. It can retrieve the text by using the GetDlgItemText function, which copies the edit control text to a buffer. The dialog box procedure typically saves this text to initialize the edit control later or passes it on to the parent window for processing.

Some dialog boxes use edit controls that let the user enter numbers. The dialog box procedure can retrieve a number from an edit control by using the GetDlgItemInt function, which retrieves the text from the edit control and converts the text to a decimal value. The user types the number in decimal digits. It can be either signed or unsigned. The dialog box procedure can display an integer by using the SetDlgItemInt function. SetDlgItemInt converts a signed or unsigned integer to a string of decimal digits.


  18.1.9.3  List Boxes, Combo Boxes, and Directory Listings

Some dialog boxes display lists of names from which the user can select one or more names. To display a list of filenames, for example, a dialog box typically uses a list box and the DlgDirList and DlgDirSelect functions. The DlgDirList function automatically fills a list box with the filenames in the current directory. The DlgDirSelect function retrieves the selected filename from the list box. Together, these two functions provide a convenient way for a dialog box to display a directory listing so the user can select a file without having to type the location and name of the file.

A dialog box can also use a combo box to display a list of filenames. The DlgDirListComboBox function automatically fills a list box portion of the combo box with the filenames in the current directory. The DlgDirSelectComboBox function retrieves the selected filename from the list box portion.


  18.1.9.4  Control Messages

Many controls recognize predefined messages that, when received by controls, cause them to carry out some action. For example, the BM_SETCHECK message sets the check in a check box and the EM_GETSEL message retrieves the portion of the control's text that is currently selected. The control messages give a dialog procedure greater and more flexible access to the controls than the standard functions, so they are often used when the dialog box requires complex interactions with the user.

A dialog box procedure can send a message to a control by supplying the control identifier and using the SendDlgItemMessage function, which is identical to the SendMessage function, except that it uses a control identifier instead of a window handle to identify the control that is to receive the message. A given message may require that the dialog procedure send parameters with the message and the message may have corresponding return values. The operation and requirements of each control message depends on the purpose of the message and the control that processes it.

For more information about the control messages, see Chapter 9, »Controls«.


  18.1.10  Custom Dialog Boxes

An application can create custom dialog boxes by using an application-defined window class for the dialog boxes instead of the predefined dialog box class. Applications typically use this method when a dialog box is their main window, but it is also useful for creating modal and modeless dialog boxes for applications that have standard overlapping windows.

The application-defined window class allows the application to define a window procedure for the dialog box and process messages before sending them to the dialog box procedure. It also lets the application define a class icon, class background brush, and a class menu for the dialog box. The application must register the window class before attempting to create a dialog box and must provide the dialog box template with the atom value or name of the window class.

Many applications create a new dialog box class by first retrieving the class information for the predefined dialog box class, and passing it to the GetClassInfo function, which fills a WNDCLASS structure with the information. The application modifies individual members of the structure, such as the class name, brush, and icon, then registers the new class by using the RegisterWindow function. If an application fills the WNDCLASS structure on its own, it must set the cbWndExtra member to the value DLGWINDOWEXTRA, which is the number of extra bytes Windows requires for each dialog box. If an application also uses extra bytes for each dialog box, they must be beyond the extra bytes required by Windows.

The window procedure for the custom dialog box has the same parameters and requirements as any other window procedure. Unlike other window procedures, however, the window procedure for this dialog box should call the DefDlgProc function instead of the DefWindowProc function for any messages it does not process. DefDlgProc carries out the same default message processing as the window procedure for the predefined dialog box, which includes calling the dialog box procedure.

An application can also create custom dialog boxes by subclassing the window procedure of the predefined dialog box. The SetWindowLong function lets an application set the address of the window procedure for a given window. The application may also attempt to subclass by using the SetClassLong function, but doing so affects all dialog boxes in the system, not just those belonging to the application.

Applications that create custom dialog boxes sometimes provide an alternate keyboard interface for the dialog boxes. For modeless dialog boxes, this may mean the application does not call the IsDialogMessage function and instead processes all keyboard input in the custom window procedure. In such cases, the application can use the WM_NEXTDLGCTL message to minimize the code needed to move the input focus from one control to another. This message, when passed to the DefDlgProc function, moves the input focus to a specified control and updates the appearance of the controls, such as moving the default push button border or setting an automatic radio button.


  18.2  Using Dialog Boxes

You use dialog boxes to display information and prompt for input from the user. Your application loads and initializes the dialog box, processes user input, and destroys the dialog box when the user finishes the task. The process for handling dialog boxes varies, depending on whether the dialog box is modal or modeless. A modal dialog box requires the user to close the dialog box before activating another window in the application. However, the user can activate windows in different applications. A modeless dialog box does not require an immediate response from the user. It is similar to a main window containing controls. The following sections discuss how to use both types of dialog boxes.


  18.2.1  Displaying a Message Box

The simplest form of modal dialog box is the message box. Most applications use message boxes to warn the user of errors and to prompt for directions on how to proceed after an error. You create a message box by using the MessageBox function, specifying the message and the number and type of buttons to display. Windows creates a modal dialog box, providing its own dialog box template and procedure. After the user closes the message box, MessageBox returns a value identifying the button chosen by the user to close the message box.

In the following example, the application displays a message box if the fError variable is TRUE. The message box displays the message describing the error. The MB_OKCANCEL style directs MessageBox to provide two buttons with which the user can choose how to proceed.

if (fError) {

    if (MessageBox(hwndDlg, SZNOTFOUND, SZDELETEITEM,

        MB_OKCANCEL)==IDOK)

        .

        . /* Prompt for a new item name and repeat the command. */

        .

    else

        .

        . /* Cancel the command. */

        .

}

In this example, SZNOTFOUND and SZDELETEITEM are application-defined, null-terminated strings that represent the message text and the title for the message box.


  18.2.2  Creating a Modal Dialog Box

You create a modal dialog box by using the DialogBox function. You must specify the identifier or name of a dialog box template resource and the address of the dialog box procedure. The DialogBox function loads the template, displays the dialog box, and processes all user input until the user closes the dialog box.

In the following example, the application displays a modal dialog box when the user chooses a Delete Item command from an application menu. The dialog box contains an edit control (in which the user enters the name of an item) and OK and Cancel buttons. The control identifiers for these controls are ID_ITEMNAME, IDOK, and IDCANCEL, respectively.

The first part of the example consists of the statements that create the modal dialog box. These statements, in the window procedure for the application's main window, create the dialog box when the system receives a WM_COMMAND message having the IDM_DELETEITEM command identifier. The second part of the example is the dialog box procedure. The procedure retrieves the contents of the edit control and closes the dialog box upon receiving a WM_COMMAND message.

The following statements create the modal dialog box. The dialog box template is a resource in the application's executable file and has the resource identifier DLG_DELETEITEM.

case WM_COMMAND:

    switch (LOWORD(wParam)) {

        case IDM_DELETEITEM:

            if (DialogBox(hinst, MAKEINTRESOURCE(DLG_DELETEITEM),

                 hwnd, (DLGPROC)DeleteItemProc)==IDOK)

                .

                . /*

                . * Complete the command; szItemName contains

                . * the name of the item to delete.

                . */

                .

             else

                .

                . /* Cancel the command. */

                .

        break;

    }

    return 0L;

In this example, the application identifies its main window as the owner window for the dialog box. When Windows initially displays the dialog box, its position is relative to the upper left corner of the owner window's client area. The application uses the return value from DialogBox to determine whether to proceed with the command or cancel it. The following statements define the dialog box procedure.

char szItemName[80]; /* receives name of item to delete. */

BOOL CALLBACK DeleteItemProc(hwndDlg, message, wParam, lParam)

HWND hwndDlg;

UINT message;

WPARAM wParam;

LPARAM lParam;

{

    switch (message) {

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                case IDOK:

                    if (!GetDlgItemText(hwndDlg, ID_ITEMNAME,

                             szItemName, 80))

                         *szItemName=0;

                    /* Fall through. */

                case IDCANCEL:

                    EndDialog(hwndDlg, wParam);

                    return TRUE;

            }

    }

    return FALSE;

}

In this example, the procedure uses the GetDlgItemText function to retrieve the current text from the edit control identified by ID_ITEMNAME. The procedure then calls the EndDialog function to set the dialog box's return value to either IDOK or IDCANCEL depending on message received and to begin the process of closing the dialog box. The IDOK and IDCANCEL identifiers correspond to the OK and Cancel buttons. After the procedure calls EndDialog, Windows sends additional messages to the procedure to destroy the dialog box and returns the dialog box's return value back to the function that created the dialog box.


  18.2.3  Creating a Modeless Dialog Box

You create a modeless dialog box by using the CreateDialog function, specifying the identifier or name of a dialog box template resource and the address of the dialog box procedure. CreateDialog loads the loads the template, creates the dialog box, and optionally displays it. Your application is responsible for retrieving and dispatching user input messages to the dialog box procedure.

In the following example, the application displays a modeless dialog box — if it is not already displayed — when the user chooses a Go To command from an application menu. The dialog box contains an edit control, a check box, and OK and Cancel buttons. The dialog box template is a resource in the application's executable file and has the resource identifier DLG_GOTO. The user enters a line number in the edit control and checks the check box to specify that the line number is relative to the current line. The control identifiers are ID_LINE, ID_ABSREL, IDOK, and IDCANCEL.

The statements in the first part of the example create the modeless dialog box. These statements, in the window procedure for the application's main window, create the dialog box when the window procedure receives a WM_COMMAND message having the IDM_GOTO command identifier, but only if the global variable hwndGoto does not already contain a valid handle. The second part of the example is the application's main message loop. The loop includes the IsDialogMessage function to ensure that the user can use the dialog box keyboard interface in this modeless dialog box. The third part of the example is the dialog box procedure. The procedure retrieves the contents of the edit control and check box when the user chooses the OK button. The procedure destroys the dialog box when the user chooses the Cancel button.

HWND hwndGoto = NULL;  /* window handle of dialog box */

    .

    .

    .

    case WM_COMMAND:

        switch (LOWORD(wParam)) {

            case IDM_GOTO:

                if (!IsWindow(hwndGoto)) {

                    hwndGoto = CreateDialog(hinst,

                         MAKEINTRESOURCE(DLG_GOTO),

                         hwnd, (DLGPROC) GoToProc);

                    ShowWindow(hwndGoto, SW_SHOW);

                }

                break;

        }

        return 0L;

In the preceding statements, the CreateDialog function is called only if the hwndGoto variable does not contain a valid window handle. This ensures that the application does not display two dialog boxes at the same time. To support this method of checking, the dialog procedure must set the hwndGoto variable to NULL when it destroys the dialog box.

The message loop for an application consists of the following statements.

while (GetMessage(&msg, NULL, NULL, NULL)) {

    if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg)) {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

}

The loop checks the validity of the window handle for the dialog box and only calls the IsDialogMessage function if the handle is valid. IsDialogMessage only processes the message if it belongs to the dialog box. Otherwise, it returns FALSE and the loop dispatches the message to the appropriate window.

The following statements define the dialog box procedure.

int iLine;             /* receives line number      */

BOOL fRelative;        /* receives check box status */

    .

    .

    .

BOOL CALLBACK GoToProc(hwndDlg, message, wParam, lParam)

HWND hwndDlg;

UINT message;

WPARAM wParam;

LPARAM lParam;

{

    BOOL fError;

    switch (message) {

        case WM_INITDIALOG:

            CheckDlgButton(hwndDlg, ID_ABSREL, fRelative);

            return TRUE;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                case IDOK:

                    fRelative = IsDlgButtonChecked(hwndDlg, ID_ABSREL);

                    iLine = GetDlgItemInt(hwndDlg, ID_LINE, &fError,

                        fRelative);

                    if (fError) {

                        MessageBox(hwndDlg, SZINVALIDNUMBER,

                            SZGOTOERR, MB_OK);

                        SendDlgItemMessage(hwndDlg, ID_LINE,

                            EM_SETSEL, 0, -1L);

                    } else

                        .

                        . /*

                        . * Notify the owner window to carry out the

                        . * command.

                        . */

                        .

                    return TRUE;

                case IDCANCEL:

                    DestroyWindow(hwndDlg);

                    hwndGoto = NULL;

                    return TRUE;

            }

    }

    return FALSE;

}

In the preceding statements, the procedure processes the WM_INITDIALOG and WM_COMMAND messages. During WM_INITDIALOG processing, the procedure initializes the check box by passing the current value of the global variable fRelative to the CheckDlgButton function. The procedure then returns TRUE to direct Windows to set the default input focus.

During WM_COMMAND processing, the procedure closes the dialog box only if the user chooses the Cancel button — that is, the button having the IDCANCEL identifier. The procedure must call the DestroyWindow function to close a modeless dialog box. Notice that the procedure also sets the hwndGoto variable to NULL to ensure that other statements that depend on this variable operate correctly.

If the user chooses the OK button, the procedure retrieves the current state of the check box and assigns it to the fRelative variable. It then uses the variable to retrieve the line number from the edit control. The GetDlgItemInt function translates the text in the edit control into a integer number. The value of fRelative determines whether the function interprets the number as a signed or unsigned value. If the edit control text is not a valid number, GetDlgItemInt sets the value of the fError variable to nonzero. The procedure checks this value to determine whether to display an error message or carry out the command. Notice that on an error, the dialog box procedure sends a message to the edit control, directing it to select the text in the control so that the user can easily replace it. If the GetDlgItemInt function does not return an error, the procedure can either carry out the requested command itself or send a message to the owner window, directing it to carry out the command.


  18.2.4  Initializing a Dialog Box

You initialize the dialog box and its contents while processing the WM_INITDIALOG message. The most common task is to initialize the controls to reflect the current dialog box settings. Another common task is to center a dialog box on the screen or within its owner window. Finally, a useful task for some dialog boxes is to set the input focus to a given control rather than accept the default input focus.

In the following example, the dialog box procedure centers the dialog box and sets the input focus while processing the WM_INITDIALOG message. To center the dialog box, the procedure retrieves the window rectangles for the dialog box and the owner window and calculates a new position for the dialog box. To set the input focus, the procedure checks the wParam parameter to determine the identifier of the default input focus:

HWND hwndOwner;

RECT rc, rcDlg, rcOwner;

    case WM_INITDIALOG:

        /* Get the owner window and dialog box rectangles. */

        if ((hwndOwner = GetParent(hwndDlg)) == NULL)

            hwndOwner = GetDesktopWindow();

        GetWindowRect(hwndOwner, &rcOwner);

        GetWindowRect(hwndDlg, &rcDlg);

        CopyRect(&rc, &rcOwner);

        /*

         * Offset the owner and dialog box rectangles so that

         * right and bottom values represent the width and

         * height, and then offset the owner again to discard

         * space taken up by the dialog box.

         */

        OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);

        OffsetRect(&rc, -rc.left, -rc.top);

        OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

        /*

         * The new position is the sum of half the remaining

         * space and the owner's original position.

         */

        SetWindowPos(hwndDlg,

            HWND_TOP,

            rcOwner.left + (rc.right / 2),

            rcOwner.top + (rc.bottom / 2),

            0, 0,          /* ignores size arguments */

            SWP_NOSIZE);

        if (GetDlgCtrlID((HWND) wParam) != ID_ITEMNAME) {

            SetFocus(GetDlgItem(hwndDlg, ID_ITEMNAME));

            return FALSE;

        }

        return TRUE;

In the preceding statements, the procedure uses the GetParent function to retrieve the owner window handle for a dialog box. The function returns the owner window handle for dialog boxes, and the parent window handle for child windows. Because an application can create a dialog box that has no owner, the procedure checks the returned handle and uses the GetDesktopWindow function to retrieve the desktop window handle, if necessary. After calculating the new position, the procedure uses the SetWindowPos function to move the dialog box, specifying the HWND_TOP value to ensure that the dialog box remains on top of the owner window.

Before setting the input focus, the procedure checks the control identifier of the default input focus. Windows passes the window handle of the default input focus in the wParam parameter. The GetDlgCtrlID function returns the control identifier for the control identified by the window handle. If the identifier does not match the correct identifier, the procedure uses the SetFocus function to set the input focus. The GetDlgItem function is required to retrieve the window handle of the desired control.


  18.2.5  Creating a Template in Memory

Applications sometimes adapt or modify the content of dialog boxes depending on the current state of the data being processed. In such cases, it is not practical to provide all possible dialog box templates as resources in the application's executable file. But creating templates in memory gives the application more flexibility to adapt to any circumstances.

In the following example, the application creates a template in memory for a modal dialog box that contains a message and OK and Help buttons:

LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPSTR lpszMessage)

{

    HGLOBAL hgbl;

    LPDLGTEMPLATE lpdt;

    LPDLGITEMTEMPLATE lpdit;

    LPWORD lpw;

    LPWSTR lpwsz;

    LRESULT ret;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);

    if (!hgbl)

        return -1;

    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);

    /* Define a dialog box. */

    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU

        | DS_MODALFRAME | WS_CAPTION;

    lpdt->cdit = 3; /* number of controls */

    lpdt->cdit = 1;

    lpdt->x  = 10;  lpdt->y  = 10;

    lpdt->cx = 100; lpdt->cy = 100;

    lpw = (LPWORD) (lpdt + 1);

    *lpw++ = 0;   /* no menu */

    *lpw++ = 0;   /* predefined dialog box class (by default) */

    lpwsz = (LPWSTR)  lpw;

    lstrcpyW(lpwsz, L"My Message"); /* dialog box title (Unicode) */

    lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);

    /* Define an OK button. */

    lpdit = (LPDLGITEMTEMPLATE) lpw;

    lpdit->x  = 10; lpdit->y  = 10;

    lpdit->cx = 40; lpdit->cy = 20;

    lpdit->id = IDOK;  /* OK button identifier */

    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

    lpw = (LPWORD) (lpdit + 1);

    *lpw++ = 0xFFFF;

    *lpw++ = 0x0080;    /* button class */

    lpwsz = (LPWSTR) lpw;

    lstrcpyW(lpwsz, L"OK"); /* button label (Unicode) */

    lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);

    *lpw++ = 0;             /* no creation data */

    /* Define a Help button. */

    lpdit = (LPDLGITEMTEMPLATE) lpw;

    lpdit->x  = 55; lpdit->y  = 10;

    lpdit->cx = 40; lpdit->cy = 20;

    lpdit->id = ID_HELP;    /* help button identifier */

    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;

    lpw = (LPWORD) (lpdit + 1);

    *lpw++ = 0xFFFF;

    *lpw++ = 0x0080;                 /* button class atom */

    lpwsz = (LPWSTR) lpw;

    lstrcpyW(lpwsz, L"Help");        /* button label (Unicode) */

    lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);

    *lpw++ = 0;                      /* no creation data */

    /* Define a static text control. */

    lpdit = (LPDLGITEMTEMPLATE) lpw;

    lpdit->x  = 55; lpdit->y  = 10;

    lpdit->cx = 40; lpdit->cy = 20;

    lpdit->id = ID_TEXT;  /* text identifier */

    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

    lpw = (LPWORD) (lpdit + 1);

    *lpw++ = 0xFFFF;

    *lpw++ = 0x0082;                        /* static class */

    for (lpwsz = (LPWSTR) lpw;

         *lpwsz++ = (WCHAR) *lpszMessage++;  /* message (Unicode) */

         );

    lpw = (LPWORD) lpwsz;

    *lpw++ = 0;                             /* no creation data */

    GlobalUnlock(hgbl);

    ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl,

        hwndOwner, (DLGPROC) DialogProc);

    GlobalFree(hgbl);

    return ret;

}


  18.3  Functions and Messages

Following are the functions and messages used to create and manage dialog boxes and controls within dialog boxes.

CreateDialog
CreateDialogIndirect
CreateDialogIndirectParam
CreateDialogParam
DefDlgProc
DialogBox
DialogBoxIndirect
DialogBoxIndirectParam
DialogBoxParam
DialogProc
EndDialog
GetDialogBaseUnits
GetDlgCtrlID
GetDlgItem
GetDlgItemInt
GetDlgItemText
GetNextDlgGroupItem
GetNextDlgTabItem
IsDialogMessage
MapDialogRect
MessageBox
MessageBoxEx
SendDlgItemMessage
SetDlgItemInt
SetDlgItemText
WM_CTLCOLORMSGBOX
WM_ENTERIDLE
WM_GETDLGCODE
WM_INITDIALOG
WM_NEXTDLGCTL


19.1  About Rectangles
  Chapter 19    Rectangles

19.1  About Rectangles

Applications written for Microsoft® Windows (™)  use rectangles to specify rectangular areas on the screen or in a window. Rectangles are used for the cursor clipping region, the invalid portion of the client area, an area for displaying formatted text, or the scroll area. Your applications can also use rectangles to fill, frame, or invert a portion of the client area with a given brush, and to retrieve the coordinates of a window or a window's client area.


  19.1.1  Rectangle Coordinates

An application must use a RECT structure to define a rectangle. The structure specifies the coordinates of two points: the upper left and lower right corners of the rectangle. The sides of the rectangle extend from these two points and are parallel to the x- and y-axes.

The coordinate values for a rectangle are expressed as signed integers. The coordinate value of a rectangle's right side must be greater than that of its left side. Likewise, the coordinate value of the bottom must be greater than that of the top.

Because applications can use rectangles for many different purposes, the Windows rectangle functions do not use an explicit unit of measure. Instead, all rectangle coordinates and dimensions are given in signed, logical values. The mapping mode and the function in which the rectangle is used determine the units of measure. For more information about coordinates and mapping modes, see Chapter 39, »Coordinate Spaces and Transformations«.


  19.1.2  Rectangle Operations

The Microsoft Win32 (™)  application programming interface (API) provides several functions for working with rectangles.

The SetRect function creates a rectangle, the CopyRect function makes a copy of a given rectangle, and the SetRectEmpty function creates an empty rectangle. An empty rectangle is any rectangle that has zero width, zero height, or both. The IsRectEmpty function determines whether a given rectangle is empty. The EqualRect function determines whether two rectangles are identical — that is, whether they have the same coordinates.

The InflateRect function increases or decreases the width or height of a rectangle, or both. It can add or remove width from both ends of the rectangle; it can add or remove height from both the top and bottom of the rectangle.

The OffsetRect function moves a rectangle by a given amount. It moves the rectangle by adding the given x-amount, y-amount, or x- and y-amounts to the corner coordinates.

The PtInRect function determines whether a given point lies within a given rectangle. The point is in the rectangle if it lies on the left or top side or is completely within the rectangle. The point is not in the rectangle if it lies on the right or bottom side.

The IntersectRect function creates a new rectangle that is the intersection of two existing rectangles, as shown in »this figure«.

The UnionRect function creates a new rectangle that is the union of two existing rectangles, as shown in »this figure«.

For information about functions that draw ellipses and polygons, see Chapter 34, »Filled Shapes«.


  19.2  Using Rectangles

The example in this section illustrates how to use the rectangle functions. It consists of the main window procedure from an application that enables the user to move and size a bitmap.

When the application starts, it draws a 32-pixel by 32-pixel bitmap in the upper left corner of the screen. The user can move the bitmap by dragging it. To size the bitmap, the user creates a target rectangle by dragging the mouse, then drags the bitmap and "drops" it on the target rectangle. The application responds by copying the bitmap into the target rectangle.

»This illustration« shows the target rectangle as it is being drawn.

»This illustration« shows the bitmap being dragged to the target rectangle.

Finally, »this illustration« shows the bitmap after it has been dropped on the target rectangle.

The window procedure that allows the user to move and size the bitmap is given in the following example.

LRESULT CALLBACK MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;      /* handle of window         */

UINT uMsg;      /* message                  */

WPARAM wParam;  /* first message parameter  */

LPARAM lParam;  /* second message parameter */

{

    HDC hdc;                 /* device context (DC) for window   */

    RECT rcTmp;              /* temporary rectangle              */

    PAINTSTRUCT ps;          /* paint data for Begin/EndPaint    */

    POINT ptClientUL;        /* client area upper left corner    */

    POINT ptClientLR;        /* client area lower right corner   */

    static HDC hdcCompat;    /* DC for copying bitmap            */

    static POINT pt;         /* x and y coordinates of cursor    */

    static RECT rcBmp;       /* rectangle that encloses bitmap   */

    static RECT rcTarget;    /* rectangle to receive bitmap      */

    static RECT rcClient;    /* client-area rectangle            */

    static BOOL fDragRect;   /* TRUE if bitmap rect. is dragged  */

    static HBITMAP hbmp;     /* handle of bitmap to display      */

    static HBRUSH hbrBkgnd;  /* handle of background-color brush */

    static COLORREF crBkgnd; /* color of client-area background  */

    static HPEN hpenDot;     /* handle of dotted pen             */

    switch (uMsg) {

        case WM_CREATE:

            /* Load the bitmap resource. */

            hbmp = LoadBitmap(hinst, MAKEINTRESOURCE(1));

            /*

             * Create a device context (DC) to hold the bitmap.

             * The bitmap is copied from this DC to the window's DC

             * whenever it must be drawn.

             */

            hdc = GetDC(hwnd);

            hdcCompat = CreateCompatibleDC(hdc);

            SelectObject(hdcCompat, hbmp);

            /*

             * Create a brush of the same color as the background

             * of the client area. The brush is used later to erase

             * the old bitmap before copying the bitmap into the

             * target rectangle.

             */

            crBkgnd = GetBkColor(hdc);

            hbrBkgnd = CreateSolidBrush(crBkgnd);

            ReleaseDC(hwnd, hdc);

            /*

             * Create a dotted pen. The pen is used to draw the

             * bitmap rectangle as the user drags it.

             */

            hpenDot = CreatePen(PS_DOT, 1, RGB(0, 0, 0));

            /*

             * Set the initial rectangle for the bitmap. Note that

             * this application supports only a 32- by 32-pixel

             * bitmap. The rectangle is slightly larger than the

             * bitmap.

             */

            SetRect(&rcBmp, 1, 1, 34, 34);

            return 0;

        case WM_PAINT:

            /*

             * Draw the bitmap rectangle and copy the bitmap into

             * it. The 32-pixel by 32-pixel bitmap is centered

             * in the rectangle by adding 1 to the left and top

             * coordinates of the bitmap rectangle, and subtracting

             * 2 from the right and bottom coordinates.

             */

            BeginPaint(hwnd, &ps);

            Rectangle(ps.hdc, rcBmp.left, rcBmp.top,

                rcBmp.right, rcBmp.bottom);

            StretchBlt(ps.hdc, rcBmp.left + 1, rcBmp.top + 1,

                (rcBmp.right - rcBmp.left) - 2,

                (rcBmp.bottom - rcBmp.top) - 2, hdcCompat,

                0, 0, 32, 32, SRCCOPY);

            EndPaint(hwnd, &ps);

            break;

        case WM_MOVE:

        case WM_SIZE:

            /*

             * Convert the client coordinates of the client-area

             * rectangle to screen coordinates and save them in a

             * rectangle. The rectangle is passed to the ClipCursor

             * function during WM_LBUTTONDOWN processing.

             */

            GetClientRect(hwnd, &rcClient);

            ptClientUL.x = rcClient.left;

            ptClientUL.y = rcClient.top;

            ptClientLR.x = rcClient.right;

            ptClientLR.y = rcClient.bottom;

            ClientToScreen(hwnd, &ptClientUL);

            ClientToScreen(hwnd, &ptClientLR);

            SetRect(&rcClient, ptClientUL.x, ptClientUL.y,

                ptClientLR.x, ptClientLR.y);

            return 0;

        case WM_LBUTTONDOWN:

            /*

             * Restrict the mouse cursor to the client area. This

             * ensures that the window receives a matching

             * WM_LBUTTONUP message.

             */

            ClipCursor(&rcClient);

            /* Save the coordinates of the mouse cursor. */

            pt.x = (LONG) LOWORD(lParam);

            pt.y = (LONG) HIWORD(lParam);

            /*

             * If the user has clicked the bitmap rectangle, redraw

             * it using the dotted pen. Set the fDragRect flag to

             * indicate that the user is about to drag the

             * rectangle.

             */

            if (PtInRect(&rcBmp, pt)) {

                hdc = GetDC(hwnd);

                SelectObject(hdc, hpenDot);

                Rectangle(hdc, rcBmp.left, rcBmp.top, rcBmp.right,

                    rcBmp.bottom);

                fDragRect = TRUE;

                ReleaseDC(hwnd, hdc);

            }

            return 0;

        case WM_MOUSEMOVE:

            /*

             * Draw a target rectangle or drag the bitmap

             * rectangle, depending on the status of the fDragRect

             * flag.

             */

            if ((wParam && MK_LBUTTON)

                    && !fDragRect) {  /* draw a target rectangle */

                /*

                 * Set the mix mode so that the pen color is the

                 * inverse of the background color. The previous

                 * rectangle can then be erased by drawing

                 * another rectangle on top of it.

                 */

                hdc = GetDC(hwnd);

                SetROP2(hdc, R2_NOTXORPEN);

                /*

                 * If a previous target rectangle exists, erase

                 * it by drawing another rectangle on top of it.

                 */

                if (!IsRectEmpty(&rcTarget))

                    Rectangle(hdc, rcTarget.left, rcTarget.top,

                        rcTarget.right, rcTarget.bottom);

                /*

                 * Save the coordinates of the target rectangle.

                 * Avoid invalid rectangles by ensuring that the

                 * value of the left coordinate is greater than

                 * that of the right coordinate, and that the

                 * value of the bottom coordinate is greater than

                 * that of the top.

                 */

                if ((pt.x < (LONG) LOWORD(lParam)) &&

                        (pt.y > (LONG) HIWORD(lParam)))

                    SetRect(&rcTarget, pt.x, HIWORD(lParam),

                        LOWORD(lParam), pt.y);

                else if ((pt.x > (LONG) LOWORD(lParam)) &&

                        (pt.y > (LONG) HIWORD(lParam)))

                    SetRect(&rcTarget, LOWORD(lParam),

                        HIWORD(lParam), pt.x, pt.y);

                else if ((pt.x > (LONG) LOWORD(lParam)) &&

                        (pt.y < (LONG) HIWORD(lParam)))

                    SetRect(&rcTarget, LOWORD(lParam), pt.y,

                        pt.x, HIWORD(lParam));

                else

                    SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam),

                        HIWORD(lParam));

                /* Draw the new target rectangle. */

                Rectangle(hdc, rcTarget.left, rcTarget.top,

                    rcTarget.right, rcTarget.bottom);

                ReleaseDC(hwnd, hdc);

            }

            else if ((wParam && MK_LBUTTON)

                    && fDragRect) { /* drag the bitmap rectangle */

                /*

                 * Set the mix mode so that the pen color is the

                 * inverse of the background color.

                 */

                hdc = GetDC(hwnd);

                SetROP2(hdc, R2_NOTXORPEN);

                /*

                 * Select the dotted pen into the DC and erase

                 * the previous bitmap rectangle by drawing

                 * another rectangle on top of it.

                 */

                SelectObject(hdc, hpenDot);

                Rectangle(hdc, rcBmp.left, rcBmp.top,

                    rcBmp.right, rcBmp.bottom);

                /*

                 * Set the new coordinates of the bitmap

                 * rectangle, then redraw it.

                 */

                OffsetRect(&rcBmp, LOWORD(lParam) - pt.x,

                    HIWORD(lParam) - pt.y);

                Rectangle(hdc, rcBmp.left, rcBmp.top,

                    rcBmp.right, rcBmp.bottom);

                ReleaseDC(hwnd, hdc);

                /* Save the coordinates of the mouse cursor. */

                pt.x = (LONG) LOWORD(lParam);

                pt.y = (LONG) HIWORD(lParam);

            }

            return 0;

        case WM_LBUTTONUP:

            /*

             * If the bitmap rectangle and target rectangle

             * intersect, copy the bitmap into the target

             * rectangle. Otherwise, copy the bitmap into the

             * rectangle bitmap at its new location.

             */

            if (IntersectRect(&rcTmp, &rcBmp, &rcTarget)) {

                /*

                 * Erase the bitmap rectangle by filling it with

                 * the background color.

                 */

                hdc = GetDC(hwnd);

                FillRect(hdc, &rcBmp, hbrBkgnd);

                /*

                 * Redraw the target rectangle because the part

                 * that intersected with the bitmap rectangle was

                 * erased by the call to FillRect.

                 */

                Rectangle(hdc, rcTarget.left, rcTarget.top,

                    rcTarget.right, rcTarget.bottom);

                /* Copy the bitmap into the target rectangle. */

                StretchBlt(hdc, rcTarget.left + 1, rcTarget.top + 1,

                    (rcTarget.right - rcTarget.left) - 2,

                    (rcTarget.bottom - rcTarget.top) - 2, hdcCompat,

                    0, 0, 32, 32, SRCCOPY);

                /*

                 * Copy the target rectangle to the bitmap

                 * rectangle, set the coordinates of the target

                 * rectangle to 0, then reset the fDragRect flag.

                 */

                CopyRect(&rcBmp, &rcTarget);

                SetRectEmpty(&rcTarget);

                ReleaseDC(hwnd, hdc);

                fDragRect = FALSE;

            }

            else if (fDragRect) {

                /*

                 * Draw the bitmap rectangle, copy the bitmap into

                 * it, and reset the fDragRect flag.

                 */

                hdc = GetDC(hwnd);

                Rectangle(hdc, rcBmp.left, rcBmp.top,

                    rcBmp.right, rcBmp.bottom);

                StretchBlt(hdc, rcBmp.left + 1, rcBmp.top + 1,

                    (rcBmp.right - rcBmp.left) - 2,

                    (rcBmp.bottom - rcBmp.top) - 2, hdcCompat,

                    0, 0, 32, 32, SRCCOPY);

                ReleaseDC(hwnd, hdc);

                fDragRect = FALSE;

            }

            /* Release the mouse cursor. */

            ClipCursor((LPRECT) NULL);

            return 0;

        case WM_DESTROY:

            /*

             * Destroy the background brush, compatible bitmap,

             * and the bitmap.

             */

            DeleteObject(hbrBkgnd);

            DeleteDC(hdcCompat);

            DeleteObject(hbmp);

            PostQuitMessage(0);

            break;

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return (LRESULT) NULL;

}


  19.3  Functions

Following are the functions used with rectangles.

CopyRect
EqualRect
InflateRect
IntersectRect
IsRectEmpty
OffsetRect
PtInRect
SetRect
SetRectEmpty
UnionRect


20.1  About Painting and Drawing
  Chapter 20    Painting and Drawing

20.1  About Painting and Drawing

Nearly all applications use the screen to display the data they manipulate. An application paints images, draws figures, and writes text so that the user can view data as it is created, edited, and printed. Microsoft® Windows (™)  provides a rich environment for painting and drawing, but, because Windows is a multitasking operating system, applications must cooperate with one another when accessing the screen.

To keep all applications functioning smoothly and cooperatively, Windows manages all output to the screen. Applications use windows as their primary output device rather than the screen itself. Windows supplies display device contexts (or, more simply, display DCs) that uniquely correspond to the windows. Applications use display DCs to direct their output to the given windows. Drawing in a window (directing output to it) prevents an application from interfering with the output of other applications and allows applications to coexist with one another while still taking full advantage of the graphics capabilities of Windows.

This chapter describes how Windows manages output to the screen and explains what applications must do to draw in a window. In particular, this chapter describes display DCs and how to prepare and use them. This chapter does not explain how to use graphics device interface (GDI) functions to generate output, nor does it explain how to print. For information on these topics, see other chapters in this book.


  20.1.1  When to Draw in a Window

An application draws in a window at a variety of times: when first creating a window, when changing the size of the window, when moving the window from behind another window, when minimizing or maximizing the window, when displaying data from an opened file, and when scrolling, changing, or selecting a portion of the displayed data.

Windows manages actions such as moving and sizing a window. If an action affects the content of the window, Windows marks the affected portion of the window as ready for updating and, at the next opportunity, sends a WM_PAINT message to the window procedure corresponding to the window. The message is a signal to the application to determine what must be updated and to carry out the drawing that is necessary.

Some actions are managed by the application, such as displaying open files and selecting displayed data. For these actions, an application can mark for updating the portion of the window affected by the action, causing a WM_PAINT message to be sent at the next opportunity. If an action requires immediate feedback, the application can draw while the action takes place, without waiting for a WM_PAINT message. For example, a typical application applies highlight to the area the user selects rather than waiting for the next WM_PAINT message.

In all cases, an application can draw in a window as soon as it is created. To draw in the window, the application must first retrieve a handle of a display DC for the window. Ideally, an application carries out most of its drawing operations during the processing of WM_PAINT messages. In this case, the application retrieves a display DC by calling the BeginPaint function. If an application draws at any other time, such as from within the WinMain function or during processing of keyboard or mouse messages, it calls the GetDC or GetDCEx function to retrieve the display DC.


  20.1.2  The WM_PAINT Message

Typically, an application draws in a window in response to a WM_PAINT message. Windows sends this message to a window procedure when changes to the window have altered the content of the client area. Windows sends the message only if there are no other messages in the application message queue.

Upon receiving a WM_PAINT message, an application can call BeginPaint to retrieve the display DC for the client area and use it in calls to GDI functions to carry out whatever drawing operations are necessary to update the client area. After completing the drawing operations, the application calls the EndPaint function to release the display DC.

Before BeginPaint returns the display DC, Windows prepares the DC for the given window. In particular, it sets the clipping region for the DC to be equal to the intersection of the portion of the window that needs updating and the portion that is visible to the user. Only those portions of the window that have changed are redrawn. Attempts to draw outside this region are clipped and do not appear on the screen.

Windows may also send WM_NCPAINT and WM_ERASEBKGND messages to the window procedure before BeginPaint returns. These messages direct the application to draw the nonclient area and window background. The nonclient area is the part of a window that is outside of the client area. The area includes features such as the title bar, System menu (also known as the Control menu), and scroll bars. Most applications rely on the default window function, DefWindowProc, to draw this area and therefore pass the WM_NCPAINT message to this function. The window background is the color or pattern a window is filled with before other drawing operations begin. The background covers any images previously in the window or on the screen under the window. If a window belongs to a window class having a class background brush, the DefWindowProc function draws the window background automatically.

BeginPaint fills a PAINTSTRUCT structure with information such as the dimensions of the portion of the window to be updated and a flag indicating whether the window background has been drawn. The application can use this information to optimize drawing. For example, it can use the dimensions of the update region, specified by the rcPaint member, to limit drawing to only those portions of the window that need updating. If an application has very simple output, it can ignore the update region and draw in the entire window, relying on Windows to clip any unneeded output. Because the system discards (clips) drawing that extends outside the clipping region, only drawing that is in the update region is visible.

BeginPaint sets the update region of a window to NULL. This clears the region, preventing it from generating subsequent WM_PAINT messages. If an application processes a WM_PAINT message but does not call BeginPaint or otherwise clear the update region, the application continues to receive WM_PAINT messages as long as the region is not empty. In all cases, an application must clear the update region before returning from the WM_PAINT message.

After the application finishes drawing, it should call EndPaint. For most windows, EndPaint releases the display DC, making it available to other windows. EndPaint also shows the caret, if it was previously hidden by BeginPaint. BeginPaint hides the caret to prevent drawing operations from corrupting it.


  20.1.2.1  The Update Region

The update region identifies the portion of a window that is out of date or invalid and in need of redrawing. Windows uses the update region to generate WM_PAINT messages for applications and to minimize the time applications spend bringing the contents of their windows up to date. Windows adds only the invalid portion of the window to the update region, requiring only that portion to be drawn.

When Windows determines that a window needs updating, it sets the dimensions of the update region to the invalid portion of the window. Setting the update region does not immediately cause the application to draw. Instead, the application continues retrieving messages from the application message queue until no messages remain. At this point, Windows checks the update region, and if the region is not empty (non-NULL), it sends a WM_PAINT message to the window procedure.

An application can use the update region to generate its WM_PAINT messages. For example, an application that loads data from open files typically sets the update region while loading so that new data is drawn during processing of the next WM_PAINT message. In general, an application should not draw at the time its data changes but route all drawing operations through the WM_PAINT message.


  Invalidating and Validating the Update Region

An application invalidates a portion of a window and sets the update region by using the InvalidateRect or InvalidateRgn function. These functions add the specified rectangle or region (given in client coordinates) to the update region, combining the rectangle or region with anything Windows or the application may have previously added to the update region.

The InvalidateRect and InvalidateRgn functions do not generate WM_PAINT messages. Instead, Windows accumulates the changes made by these functions and its own changes while a window processes other messages in its message queue. By accumulating changes, a window processes all changes at once instead of updating bits and pieces one step at a time.

The ValidateRect and ValidateRgn functions validate a portion of the window by removing a specified rectangle or region from the update region. These functions are typically used when the window has updated a specific part of the screen in the update region before receiving the WM_PAINT message.


  Retrieving the Update Region

The GetUpdateRect and GetUpdateRgn functions retrieve the current update region for the window. GetUpdateRect retrieves the smallest rectangle (in client coordinates) that encloses the entire update region. GetUpdateRgn retrieves the update region itself. These functions can be used to calculate the current size of the update region to determine where to carry out a drawing operation.

BeginPaint also retrieves the dimensions of the smallest rectangle enclosing the current update region, copying the dimensions to the rcPaint member in the PAINTSTRUCT structure. Because BeginPaint validates the update region, any call to GetUpdateRect and GetUpdateRgn immediately after a call to BeginPaint returns an empty update region.


  Excluding the Update Region

The ExcludeUpdateRgn function excludes the update region from the clipping region for the display DC. This function is useful when drawing in a window other than when a WM_PAINT message is processing. It prevents drawing in the areas that will be updated during the next WM_PAINT message.


  20.1.2.2  Synchronous and Asynchronous Drawing

Most drawing carried out during processing of the WM_PAINT message is asynchronous. That is, there is a delay between the time a portion of the window is invalidated and the time the WM_PAINT message is sent. During the delay, the application typically retrieves messages from the queue and carries out other tasks. The reason for the delay is that Windows generally treats drawing in a window as a low-priority operation and works as though user-input messages and messages that may affect the position or size of a window will be processed before a WM_PAINT message.

In some cases, it is necessary for an application to draw synchronously — that is, draw in the window immediately after invalidating a portion of the window. A typical application draws its main window immediately after creating the window to signal the user that the application has started successfully. Windows synchronously draws some control windows, such as buttons, because such windows serve as the focus for user input. Although any window with a simple drawing routine can be drawn synchronously, all such drawing should be done quickly and should not interfere with the application's ability to respond to user input.

The UpdateWindow and RedrawWindow functions allow for synchronous drawing. UpdateWindow sends a WM_PAINT message directly to the window if the update region is not empty. RedrawWindow also sends a WM_PAINT message, but gives the application greater control over how to draw the window, such as whether to draw the nonclient area and window background or whether to send the message regardless of whether the update region is empty. These functions send the WM_PAINT message directly to the window, regardless of the number of other messages in the application message queue.

Any window requiring time-consuming drawing operations should be drawn asynchronously to prevent pending messages from being blocked as the window is drawn. Also, any application that frequently invalidates small portions of a window should usually allow these invalid portions to consolidate into a single asynchronous WM_PAINT message, rather than a series of synchronous WM_PAINT messages.


  20.1.3  Drawing Without the WM_PAINT Message

Although applications carry out most drawing operations as the WM_PAINT message is processing, it is sometimes more efficient for an application to draw directly in a window without relying on the WM_PAINT message. This can be useful when the user needs immediate feedback, such as when selecting text and dragging or sizing an object. In such cases, the application usually draws while processing keyboard or mouse messages.

To draw in a window without using a WM_PAINT message, the application uses the GetDC or GetDCEx function to retrieve a display DC for the window. With the display DC, the application can draw in the window and avoid intruding into other windows. When the application has finished drawing, it calls the ReleaseDC function to release the display DC for use by other applications.

When drawing without using a WM_PAINT message, the application usually does not invalidate the window. Instead, it draws in such a fashion that it can easily restore the window and remove the drawing. For example, when the user selects text or an object, the application typically draws the selection by inverting whatever is already in the window. The application can remove the selection and restore the original contents of the window by simply inverting again.

The application is responsible for carefully managing any changes it makes to the window. In particular, if an application draws a selection and an intervening WM_PAINT message occurs, the application must ensure that any drawing done during the message does not corrupt the selection. To avoid this, many applications remove the selection, carry out usual drawing operations, and then restore the selection when complete.


  20.1.4  Window Coordinate System

The coordinate system for a window is based on the coordinate system of the display device. The basic unit of measure is the device unit (typically, the pixel). Points on the screen are described by x- and y-coordinate pairs. The x-coordinates increase to the right; y-coordinates increase from top to bottom. The origin (0,0) for the system depends on the type of coordinates being used.

Windows and applications specify the position of a window on the screen in screen coordinates. For screen coordinates, the origin is the upper-left corner of the screen. The full position of a window is often described by a RECT structure containing the screen coordinates of two points that define the upper-left and lower-right corners of the window.

Windows and applications specify the position of points in a window by using client coordinates. The origin in this case is the upper-left corner of the window or client area. Client coordinates ensure that an application can use consistent coordinate values while drawing in the window, regardless of the position of the window on the screen.

The dimensions of the client area are also described by a RECT structure containing client coordinates for the area. In all cases, the upper-left coordinate of the rectangle is included in the window or client area, while the lower-right coordinate is excluded. Graphics operations in a window or client area are excluded from the right and lower edges of the enclosing rectangle.

Occasionally, applications may be required to map coordinates in one window to those of another window. An application can map coordinates by using the MapWindowPoints function. If one of the windows is the desktop window, the function effectively converts screen coordinates to client coordinates and vice versa; the desktop window is always specified in screen coordinates.


  20.1.5  Window Regions

In addition to the update region, every window has a visible region that defines the window portion visible to the user. The system changes the visible region for the window whenever the window changes size or whenever another window is moved such that it obscures or exposes a portion of the window. Applications cannot change the visible region directly, but Windows automatically uses the visible region to create the clipping region for any display DC retrieved for the window.

The clipping region determines where the system permits drawing. When the application retrieves a display DC using the BeginPaint, GetDC, or GetDCEx function, the system sets the clipping region for the DC to the intersection of the visible region and the update region. Applications can change the clipping region by using functions such as SelectClipPath and SelectClipRgn, to further limit drawing to a particular portion of the update area.

The WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles further specify how Windows calculates the visible region for a window. If a window has one or both of these styles, the visible region excludes any child window or sibling windows (windows having the same parent window). Therefore, drawing that would otherwise intrude in these windows will always be clipped.


  20.1.6  Window Background

The window background is the color or pattern used to fill the client area before a window begins drawing. The window background covers whatever was on the screen before the window was moved there, erasing existing images and preventing the application's new output from being mixed with unrelated information.

Windows paints the background for a window or gives the window the opportunity to do so by sending it a WM_ERASEBKGND message when the application calls BeginPaint. If an application does not process the message but passes it to the DefWindowProc function, Windows erases the background by filling it with the pattern in the background brush specified by the window's class. If the class has no background brush or the brush is not valid, Windows sets the fErase member in the PAINTSTRUCT structure returned by BeginPaint, but carries out no other action. This gives the application a second chance to draw the window background, if necessary.

If it processes the WM_ERASEBKGND message, the application should use the message's wParam parameter to draw the background. This parameter contains the handle of the display DC for the window. After drawing the background, the application should return a nonzero value. This ensures that BeginPaint does not erroneously set the fErase member of the PAINTSTRUCT structure to a nonzero value (indicating the background should be erased) when the application processes the subsequent WM_PAINT message.

An application can define a class background brush by assigning a brush handle or a system color value to the hbrBackground member of the WNDCLASS structure when registering the class with the RegisterClass function. The GetStockObject or CreateSolidBrush function can be used to create a brush handle; a system color value can be one of those defined for the SetSysColors function. (The value must be increased by one before it is assigned to the member.)

An application can process the WM_ERASEBKGND message even though a class background brush is defined. This is typical in applications that enable the user to change the window background color or pattern for a given window without affecting other windows in the class. In such cases, the application must not pass the message to DefWindowProc.

In Windows 3.x, the origin of the screen is the point of reference for drawing brushes. The pattern in a window background can become misaligned if the window is moved to a new location. To prevent misalignment when running with Windows 3.x, applications that use pattern brushes for the window background must use the SetBrushOrg and UnrealizeObject functions to align the brush with the window before drawing.

In Windows NT (™) , it is not necessary for an application to align brushes, because the system draws the brush using the window origin as the point of reference. Given this, the user can move the window without affecting the alignment of pattern brushes.


  20.1.7  Minimized Windows

Windows reduces an application's main window (overlapping style) to a minimized window when the user chooses the Minimize command from the System menu or the application calls the ShowWindow function and specifies a value such as SW_MINIMIZE. Minimizing a window speeds up system performance by reducing the amount of work an application must do when updating its main window.

For a typical application, Windows draws an icon, called the class icon, when the window is minimized, labeling the icon with the name of the window. The class icon, a static image that represents the application, is specified by the application when it registers the window class. The application assigns the handle of the class icon to the hIcon member of the WNDCLASS structure before calling RegisterClass. The application can use the LoadIcon function to retrieve the icon handle.

Before drawing the class icon, Windows sends a WM_ICONERASEBKGND message to the window procedure, enabling the application to prepare the background for drawing the icon and by setting the best possible background colors for the icon. This is useful for applications that combine the icon with the current background colors. If the application processes the message, it should use the display DC provided with the message to draw the background (the wParam parameter contains the handle of the display DC). If the application does not process the WM_ICONERASEBKGND message, it should pass the message to DefWindowProc; the function fills the icon area with the current desktop color and pattern. After sending WM_ICONERASEBKGND, Windows sends the WM_PAINTICON message to the window procedure. The application should immediately forward this internal message to DefWindowProc.

Windows does not require that a window class have a class icon. If an application sets the hIcon member of the WNDCLASS structure to NULL, a class icon is not defined. In this case, Windows sends the WM_ERASEBKGND message (instead of the WM_ICONERASEBKGND message) to a window of the class whenever the window must paint the icon background. Windows then sends a WM_PAINT message and the application draws an icon or another image representing the minimized window. In such cases, the application must determine when the window is minimized and draw accordingly. It can do so by calling the IsIconic function. If the function returns TRUE, the window is minimized. If an application has no class icon and fails to process the WM_ERASEBKGND and WM_PAINT messages, the area that Windows reserves for the application's icon will contain whatever was previously on the screen.


  20.1.8  Window Size

Windows changes the size of a window when the user chooses System menu commands, such as Size and Maximize, or when the application calls functions, such as the SetWindowPos function. When a window changes size, Windows assumes that the contents of the previously exposed portion of the window are not affected and need not be redrawn. Windows invalidates only the newly exposed portion of the window, which saves time when the eventual WM_PAINT message is processed by the application. In this case, WM_PAINT message is not generated when the size of the window is reduced.

For some windows, however, any change to the size of the window invalidates the contents. For example, a clock application that adapts the face of the clock to fit neatly within its window must redraw the clock anytime the window changes size. To force Windows to invalidate the entire client area of the window when a vertical, horizontal, or both vertical and horizontal change is made, an application must specify the CS_VREDRAW or CS_HREDRAW style, or both, when registering the window class. Any window belonging to a window class having these styles is invalidated each time the user or the application changes the size of the window.


  20.1.9  Nonclient Area

Windows sends a WM_NCPAINT message to the window whenever a part of the nonclient area of the window, such as the title bar, menu bar, or window frame, must be updated. Windows may also send other messages to direct a window to update a portion of its client area; for example, when a window becomes active or inactive it sends the WM_NCACTIVATE message to update its title bar. In general, processing these messages for standard windows is not recommended, because the application must be able to draw all the required parts of the nonclient area for the window. For this reason, most applications pass these messages to DefWindowProc for default processing.

An application that creates custom nonclient areas for its windows must process these messages. When doing so, the application must use a window DC to carry out drawing in the window. The window DC enables the application to draw in all portions of the window, including the nonclient area. An application retrieves a window DC by using the GetWindowDC or GetDCEx function and must release the window DC by using the ReleaseDC function when drawing is complete.

Windows maintains an update region for the nonclient area. When an application receives a WM_NCPAINT message, the wParam parameter contains the handle of a region defining the dimensions of the update region. The application can use the handle to combine the update region with the clipping region for the window DC. Windows does not automatically combine the update region when retrieving the window DC unless the application uses GetDCEx and specifies both the region handle and the DCX_INTERSECTRGN flag. If the application does not combine the update region, only drawing operations that would otherwise extend outside the window are clipped. The application is not responsible for clearing the update region, regardless of whether it uses the region.

If an application processes the WM_NCACTIVATE message, it must return TRUE after processing the message to direct Windows to complete the change of active window. If the window is minimized when the application receives the WM_NCACTIVATE message, it should pass the message to DefWindowProc. In such cases, the default function redraws the label for the icon.


  20.1.10  Child Windows

A child window is a window having the WS_CHILD or WS_CHILDWINDOW style. Like other window styles, child windows receive WM_PAINT messages to prompt updating. Each child window has an update region, which either Windows or the application can set to generate eventual WM_PAINT messages.

A child window's update and visible regions are affected by the child's parent window; this is not true for windows of other styles. Windows often sets the child window's update region when it sets the parent window's update region, causing the child window to receive WM_PAINT messages when the parent window receives them. Also, Windows limits the location of the child window's visible region to within the client area of the parent window. Windows clips any portion of the child window moved outside the parent window.

Windows sets the update region for a child window whenever part of the parent window's update region includes a portion of the child window. In such cases, Windows first sends a WM_PAINT message to the parent window and then sends a message to the child window, allowing the child to restore any portions of the window that the parent may have drawn over.

Windows does not set the parent's update region when the child's is set. An application cannot generate a WM_PAINT message for the parent window by invalidating the child window. Similarly, an application cannot generate a WM_PAINT message for the child by invalidating a portion of the parent's client area that lies entirely under the child window. In such cases, neither window receives a WM_PAINT message.

An application can prevent a child window's update region from being set when the parent window's is set by specifying the WS_CLIPCHILDREN style when creating the parent window. When this style is set, Windows excludes the child windows from the parent's visible region and therefore ignores any portion of the update region that may contain the child windows. When the application paints in the parent window, any drawing that would cover the child window is clipped, making a subsequent WM_PAINT message to the child window unnecessary.

The update and visible regions of a child window are also affected by the child window's siblings. Sibling windows are any windows that have a common parent window. If sibling windows overlap, then setting the update region for one affects the update region of another, causing WM_PAINT messages to be sent to both windows. Sibling windows receive WM_PAINT messages in the reverse order of their position in the Z order. Given this, the window highest in the Z order (on the top) receives its WM_PAINT message last, and vice versa.

Sibling windows are not automatically clipped. One sibling can draw over another overlapping sibling even if the window that is drawing has a position in the Z order that is lower. An application can prevent this by specifying the WS_CLIPSIBLINGS style when creating the windows. When this style is set, Windows excludes all portions of an overlapping sibling window from a window's visible region if the overlapping sibling window has a higher position in the Z order.

Note   The update and visible regions for windows that have the WS_POPUP or WS_POPUPWINDOW style are not affected by their parent windows.


  20.1.11  Display Device Contexts

A display DC is a device context, created by Windows, that an application uses to paint and draw a window. Windows prepares each display DC for output to a window, setting the drawing objects, colors, and modes for the window instead of for the display device. When the application supplies the display DC in calls to GDI functions, GDI uses the information in the context to generate output in the given window without intruding on other windows or other parts of the screen.

Windows provides five kinds of display device context: common, class, parent, private, and window. The common, class, and private DCs permit drawing in the client area of a given window. The parent and window DCs permit drawing anywhere in the window. Although the parent DC also permits drawing in the parent window, it is not intended to be used in this way.

Windows supplies a common, class, parent, or private DC to a window based on the type of display DC specified in that window's class style. Windows supplies a window DC only when the application explicitly requests one; for example, by calling the GetWindowDC or GetDCEx function. In all cases, an application can determine which window a display DC currently represents by using the WindowFromDC function.


  20.1.11.1  Display Device Context Cache

Windows maintains a cache of display DCs that it uses for common, parent, and window DCs. Windows retrieves a DC from the cache whenever an application calls the GetDC or BeginPaint function; Windows returns the DC to the cache when the application subsequently calls the ReleaseDC or EndPaint function.

In Windows 3.x, the cache contains five display DCs, but only five DCs from the cache can be active at a time. To ensure that other applications have access to these DCs, an application must release a device context immediately after using it. Failure to do so eventually causes the application to fail.

In Windows NT, there is no predetermined limit on the amount of DCs that a cache can hold; Windows NT creates a new display DC for the cache if none is available. Given this, an application designed for Windows NT can have more than five active DCs from the cache at a time. However, an application must continue to release these DCs after use. Because new display DCs for the cache are allocated in the application's heap space, failing to release the DCs eventually consumes all available heap space. Windows NT indicates this failure by returning an error when it cannot allocate space for the new DC. Other functions unrelated to the cache may also return errors.

Portability   To minimize porting efforts, applications that use common DCs should be limited to no more than five and ensure that a common DC is released as soon as possible after it is used.


  20.1.11.2  Display Device Context Defaults

Upon first creating a display DC, Windows assigns default values for the attributes (that is, drawing objects, colors, and modes) that comprise the DC. The following table shows the default values for the attributes of a display DC.

Attribute	Default value
Background color	Background color setting from Windows Control Panel (typically, white).
Background mode	OPAQUE.
Bitmap	None.
Brush	WHITE_BRUSH.
Brush origin	(0,0).
Clipping region	Entire window or client area with the update region clipped as appropriate. Child and pop-up windows in the client area may also be clipped.
Palette	DEFAULT_PALETTE.
Current pen position	(0,0).
Device origin	Upper-left corner of the window or the client area.
Drawing mode	R2_COPYPEN.
Font	SYSTEM_FONT (SYSTEM_FIXED_FONT for applications written to run with Windows versions 3.0 and earlier).
Intercharacter spacing	0.
Mapping mode	MM_TEXT.
Pen	BLACK_PEN.
Polygon-fill mode	ALTERNATE.
Stretch mode	BLACKONWHITE.
Text color	Text color setting from Windows Control Panel (typically, black).
Viewport extent	(1,1).
Viewport origin	(0,0).
Window extent	(1,1).
Window origin	(0,0).
An application can modify the values of the display DC attributes by using selection and attribute functions, such as SelectObject, SetMapMode, and SetTextColor. For example, an application can modify the default units of measure in the coordinate system by using SetMapMode to change the mapping mode.

Changes to the attribute values of a common, parent, or window DC are not permanent. When an application releases these DCs, the current selections, such as mapping mode and clipping region, are lost as the context is returned to the cache. Changes to a class or private DC persist indefinitely. To restore these DCs to the original defaults, an application must explicitly set each attribute.


  20.1.11.3  Common Display Device Contexts

A common DC is used for drawing in the client area of the window. Windows provides a common DC by default for any window whose window class does not explicitly specify a display DC style. Common DCs are typically used with windows that can be drawn without extensive changes to the DC attributes. Common DCs are convenient because they do not require additional memory or system resources, but they can be inconvenient if the application must set up many attributes before using it.

Windows retrieves all common DCs from the display DC cache. An application can retrieve a common DC immediately after the window is created. Because the common DC is from the cache, the application must always release the DC as soon as possible after drawing. After the common DC is released, it is no longer valid and the application must not attempt to draw with it. To draw again, the application must retrieve a new common DC, and continue to retrieve and release a common DC each time it draws in the window. If the application retrieves the DC handle by using the GetDC function, it must use the ReleaseDC function to release the handle. Similarly, for each BeginPaint function, the application must use a corresponding EndPaint function.

When the application retrieves the DC, Windows adjusts the origin so that it aligns with the upper-left corner of the client area. It also sets the clipping region so that output to the DC is clipped to the client area. Any output that would otherwise appear outside the client area is clipped. If the application retrieves the common DC by using BeginPaint, Windows also includes the update region in the clipping region to further restrict the output.

When an application releases a common DC, Windows restores the default values for the attributes of the DC. An application that modifies attribute values must do so each time it retrieves a common DC. Releasing the DC releases any drawing objects the application may have selected into the DC, so the application need not release these objects before releasing the DC. In all cases, an application must never assume that the common DC retains nondefault selections after being released.


  20.1.11.4  Private Display Device Contexts

A private DC enables an application to avoid retrieving and initializing a display DC each time the application must draw in a window. Private DCs are useful for windows that require many changes to the values of the attributes of the DC to prepare it for drawing. Private DCs reduce the time required to prepare the DC and therefore the time needed to carry out drawing in the window.

An application directs Windows to create a private DC for a window by specifying the CS_OWNDC style in the window class. Windows creates a unique private DC each time it creates a new window belonging to the class. Initially, the private DC has the same default values for attributes as a common DC, but the application can modify these at any time. Windows preserves changes to the DC for the life of the window or until the application makes additional changes.

An application can retrieve the handle of the private DC by using the GetDC function any time after the window is created. The application must retrieve the handle only once. Thereafter, it can keep and use the handle any number of times. Because a private DC is not part of the display DC cache, an application never needs to release the DC by using the ReleaseDC function.

Windows automatically adjusts the DC to reflect changes to the window, such as moving or sizing. This ensures that any overlapping windows are always properly clipped; that is, no action is required by the application to ensure clipping. However, Windows does not revise the DC to include the update region. Therefore, when processing a WM_PAINT message, the application must incorporate the update region either by calling BeginPaint or by retrieving the update region and intersecting it with the current clipping region. If the application does not call BeginPaint, it must explicitly validate the update region by using the ValidateRect or ValidateRgn function. If the application does not validate the update region, the window receives an endless series of WM_PAINT messages.

Because BeginPaint hides the caret if a window is showing it, an application that calls BeginPaint should also call the EndPaint function to restore the caret. EndPaint has no other effect on a private DC.

Although a private DC is convenient to use, it is expensive in terms of system resources, requiring 800 or more bytes to store. Private DCs are recommended when performance considerations outweigh storage costs.

Windows includes the private DC when sending the WM_ERASEBKGND message to the application. The current selections of the private DC, including mapping mode, are in effect when the application or Windows processes these messages. To avoid undesirable effects, Windows uses logical coordinates when erasing the background; for example, it uses the GetClipBox function to retrieve the logical coordinates of the area to erase and passes these coordinates to the FillRect function. Applications that process these messages can use similar techniques. Windows supplies a window DC with the WM_ICONERASEBKGND message regardless of whether the corresponding window has a private DC.

An application can use the GetDCEx function to force Windows to return a common DC for the window that has a private DC. This is useful for carrying out quick touch-ups to a window without changing the current values of the attributes of the private DC.


  20.1.11.5  Class Display Device Contexts

By using a class DC, an application can use a single display DC for every window belonging to a given class. Class DCs are often used with control windows that are drawn using the same attribute values. Like private DCs, class DCs minimize the time required to prepare a DC for drawing.

Windows supplies a class DC for a window if it belongs to a window class having the CS_CLASSDC style. Windows creates the DC when creating the first window belonging to the class and then uses the same DC for all subsequently created windows in the class. Initially, the class DC has the same default values for attributes as a common DC, but the application can modify these at any time. Windows preserves all changes, except for the clipping region and device origin, until the last window in the class has been destroyed. A change made for one window applies to all windows in that class.

An application can retrieve the handle for the class DC by using the GetDC function any time after the first window has been created. The application can keep and use the handle without releasing it because the class DC is not part of the display DC cache. If the application creates another window in the same window class, the application must retrieve the class DC again. Retrieving the DC sets the correct device origin and clipping region for the new window. After the application retrieves the class DC for a new window in the class, the DC can no longer be used to draw in the original window without again retrieving it for that window. In general, each time it must draw in a window, an application must explicitly retrieve the class DC for the window.

Applications that use class DCs should always call BeginPaint when processing a WM_PAINT message. The function sets the correct device origin and clipping region for the window, and incorporates the update region. The application should also call EndPaint to restore the caret if BeginPaint hid it. EndPaint has no other effect on a class DC.

Windows passes the class DC when sending the WM_ERASEBKGND message to the application, permitting the current attribute values to affect any drawing carried out by the application or Windows when processing this message. Windows supplies a window DC with the WM_ICONERASEBKGND message regardless of whether the corresponding window has a class DC. As it could with a window having a private DC, an application can use GetDCEx to force Windows to return a common DC for the window that has a class DC.

In Windows 3.x, class DCs are intended to be used with windows created by a single application. This ensures that drawing objects, such as pens and brushes, selected into the class DC are created and maintained by a single application. Errors can occur if several applications attempt to create and select drawing objects into a single class DC. In particular, assumptions made about the validity of handles returned by the SelectObject function can be wrong. In Windows NT, using class DCs is not recommended.


  20.1.11.6  Window Display Device Contexts

A window DC enables an application to draw anywhere in a window, including the nonclient area. Window DCs are typically used by applications that process the WM_NCPAINT and WM_NCACTIVATE messages for windows with custom nonclient areas. Using a window DC is not recommended for any other purpose.

An application can retrieve a window DC by using the GetWindowDC or GetDCEx function with the DCX_WINDOW option specified. The function retrieves a window DC from the display DC cache. A window that uses a window DC must release it after drawing by using the ReleaseDC function as soon as possible. Window DCs are always from the cache; the CS_OWNDC and CS_CLASSDC class styles do not affect the DC.

When an application retrieves a window DC, Windows sets the device origin to the upper-left corner of the window instead of the upper-left corner of the client area. It also sets the clipping region to include the entire window, not just the client area. Windows sets the current attribute values of a window DC to the same default values as a common DC. An application can change the attribute values, but Windows does not preserve any changes when the DC is released.


  20.1.11.7  Parent Display Device Contexts

A parent DC enables an application to minimize the time necessary to set up the clipping region for a window. An application typically uses parent DCs to speed up drawing for control windows without requiring a private or class DC. For example, Windows uses parent DCs for push button and edit controls. Parent DCs are intended for use with child windows only, never with top-level or pop-up windows.

Windows supplies a parent DC for any window belonging to a window class specifying the CS_PARENTDC style. An application can retrieve the parent DC by using GetDC immediately after the window is created. Windows always retrieves the parent DC from the display DC cache even if the parent uses a private or class DC, so the application must release the DC by using ReleaseDC as soon as possible after drawing. When processing a WM_PAINT message, the application must retrieve the parent DC by using BeginPaint and release it by using EndPaint.

When a parent DC is retrieved, Windows searches the cache for the display DC previously used by the parent window. In most cases, the parent window retrieves and releases a display DC before the child window attempts to retrieve one, so the parent DC is usually in the cache. If Windows finds the display DC, Windows uses it and its corresponding clipping region, which was previously calculated for the parent DC. The time saved is in skipping the calculation required to define the clipping region. If Windows does not find the parent DC, it retrieves a common DC for the window and calculates the clipping region for the window rather than for the parent window.

Windows sets the device origin for the parent DC to the upper-left corner of the child window. Attribute values set by the parent window are not preserved for the child window; for example, the parent window cannot set the brush for its child windows. The only property preserved is the clipping region. The window is responsible for clipping its own output to the limits of the window. Because the clipping region for the parent DC is identical to the parent window, the child window can potentially draw over the entire parent window, but the parent DC must not be used in this way.

Windows ignores the CS_PARENTDC style if the parent window uses a private or class DC, if the parent window clips its child windows, or if the child window clips its child windows or sibling windows. In these cases, Windows always retrieves a common DC for the window.


  20.1.12  Window Update Lock

A window update lock is a temporary suspension of drawing in a window. Windows uses the lock to prevent other windows from drawing over the tracking rectangle whenever the user moves or sizes a window. Applications can use the lock to prevent drawing if they carry out similar moving or sizing operations with their own windows.

An application sets and clears the window update lock by using the LockWindowUpdate function, specifying the window to lock. The lock applies to the given window and all of its child windows. When the lock is set, the GetDC and BeginPaint functions return a display DC whose visible region is empty. Given this, the application can continue to draw in the window, but all output is clipped. The lock continues until the application clears it by calling LockWindowUpdate, specifying NULL for the window. Although LockWindowUpdate forces a window's visible region to be empty, the function does not make the given window invisible and does not clear the WS_VISIBLE style bit.

After the lock is set, the application can use the GetDCEx function, with the DCX_LOCKWINDOWUPDATE value, to retrieve a display DC to draw over the locked window. This allows the application to draw a tracking rectangle when processing keyboard or mouse messages. Windows uses this method when the user moves and sizes windows. GetDCEx retrieves the display DC from the display DC cache, so the application must release the DC as soon as possible after drawing.

While a window update lock is set, the system creates an accumulated bounding rectangle for each locked window. When the lock is cleared, Windows uses this bounding rectangle to set the update region for the window and its child windows, forcing an eventual WM_PAINT message. If the accumulated bounding rectangle is empty (that is, if no drawing has occurred while the lock was set), the update region is not set.


  20.1.13  Accumulated Bounding Rectangle

The accumulated bounding rectangle is the smallest rectangle enclosing the portion of a window or client area affected by recent drawing operations. An application can use this rectangle to conveniently determine the extent of changes caused by drawing operations. It is sometimes used in conjunction with LockWindowUpdate to determine which portion of the client area must be redrawn after the update lock is cleared.

An application starts accumulating the bounding rectangle by using the SetBoundsRect function, specifying the DCB_ENABLE value. Windows subsequently accumulates points for the bounding rectangle as the application uses the specified display DC. The application can retrieve the current bounding rectangle at any time by using the GetBoundsRect function. The application stops the accumulation by calling SetBoundsRect again, specifying DCB_DISABLE.


  20.2  Using the WM_PAINT Message

You can use the WM_PAINT message to carry out the drawing necessary for displaying information. Because Windows sends WM_PAINT messages to your application when your window must be updated or when you explicitly request an update, you can consolidate the code for drawing in your application's window procedure. You can then use this code whenever your application must draw either new or existing information.

The following sections show a variety of ways to use the WM_PAINT message to draw in a window.


  20.2.1  Drawing in the Client Area

You use the BeginPaint and EndPaint functions to prepare for and complete the drawing in the client area. BeginPaint returns a handle of the display DC used for drawing in the client area, and EndPaint ends the paint request and releases the display DC.

In the following code sample, the window procedure writes the message "Hello, Windows!" in the client area. To make sure the string is visible when the window is first created, the WinMain function calls the UpdateWindow function immediately after creating and showing the window. This causes a WM_PAINT message to be sent immediately to the window procedure.

LRESULT APIENTRY WndProc(hwnd, message, wParam, lParam)

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

{

    PAINTSTRUCT ps;

    HDC hdc;

    switch (message) {

        case WM_PAINT:

            hdc = BeginPaint(hwnd, &ps);

            TextOut(hdc, 0, 0, "Hello, Windows!", 15);

            EndPaint(hwnd, &ps);

            return 0L;

        .

        .

        .

    }

}

int APIENTRY WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)

HINSTANCE hInstance;         /* handle of current instance   */

HINSTANCE hPrevInstance;     /* handle of previous instance  */

LPSTR lpCmdLine;             /* address of command line      */

int nCmdShow;                /* show-window type (open/icon) */

{

    HWND hwnd;

    hwnd = CreateWindowEx( /* parameters */ );

    ShowWindow(hwnd, SW_SHOW);

    UpdateWindow(hwnd);

    .

    .

    .

    return msg.wParam;

}


  20.2.2  Redrawing the Entire Client Area

You can have your application redraw the entire contents of the client area whenever the window changes size by setting the CS_HREDRAW and CS_VREDRAW styles for the window class. Applications that adjust the size of the drawing based on the size of the window use these styles to ensure that they start with a completely empty client area when drawing.

In the following code, the window procedure draws a five-pointed star that fits neatly in the client area. It uses a common DC and must set the mapping mode and window and viewport extents each time the WM_PAINT message is processed.

LRESULT APIENTRY WndProc(hwnd, message, wParam, lParam)

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

{

    PAINTSTRUCT ps;

    HDC hdc;

    RECT rc;

    POINT aptStar[6] = {50,2, 2,98, 98,33, 2,33, 98,98, 50,2};

    .

    .

    .

        case WM_PAINT:

            hdc = BeginPaint(hwnd, &ps);

            GetClientRect(hwnd, &rc);

            SetMapMode(hdc, MM_ANISOTROPIC);

            SetWindowExtEx(hdc, 100, 100, NULL);

            SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);

            Polyline(hdc, aptStar, 6);

            EndPaint(hwnd, &ps);

            return 0L;

        .

        .

        .

}

int APIENTRY WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)

HINSTANCE hInstance;         /* handle of current instance   */

HINSTANCE hPrevInstance;     /* handle of previous instance  */

LPSTR lpCmdLine;             /* address of command line      */

int nCmdShow;                /* show-window type (open/icon) */

{

    WNDCLASS wc;

    .

    .

    .

        wc.style = CS_HREDRAW | CS_VREDRAW;

        wc.lpfnWndProc = (WNDPROC) WndProc;

    .

    .

    .

        RegisterClass(&wc);

    .

    .

    .

    return msg.wParam;

}


  20.2.3  Redrawing in the Update Region

You can limit the amount of drawing your application carries out when processing the WM_PAINT message by determining the size and location of the update region. Because Windows uses the update region when creating the clipping region for the window's display DC, you can indirectly determine the update region by examining the clipping region.

In the following code sample, the window procedure draws a triangle, a rectangle, a pentagon, and a hexagon, but only if all or a portion of each figure lies within the update region. The window procedure uses the RectVisible function and a 100-by-100 rectangle to determine whether a figure is within the clipping region (and therefore the update region) for the common DC retrieved by the BeginPaint function.

POINT aptTriangle[4]  = {50,2, 98,86,  2,86, 50,2},

      aptRectangle[5] = { 2,2, 98,2,  98,98,  2,98, 2,2},

      aptPentagon[6]  = {50,2, 98,35, 79,90, 21,90, 2,35, 50,2},

      aptHexagon[7]   = {50,2, 93,25, 93,75, 50,98, 7,75, 7,25, 50,2};

  .

  .

  .

        case WM_PAINT:

            hdc = BeginPaint(hwnd, &ps);

            SetRect(&rc, 0, 0, 100, 100);

            if (RectVisible(hdc, &rc))

                Polyline(hdc, aptTriangle, 4);

            SetViewportOrgEx(hdc, 100, 0, NULL);

            if (RectVisible(hdc, &rc))

                Polyline(hdc, aptRectangle, 5);

            SetViewportOrgEx(hdc, 0, 100, NULL);

            if (RectVisible(hdc, &rc))

                Polyline(hdc, aptPentagon, 6);

            SetViewportOrgEx(hdc, 100, 100, NULL);

            if (RectVisible(hdc, &rc))

                Polyline(hdc, aptHexagon, 7);

            EndPaint(hwnd, &ps);

            return 0L;

  .

  .

  .

In this example, the coordinates of each figure lie within the same 100-by-100 rectangle. Before drawing a figure, the window procedure uses the SetViewportOrgEx function to set the viewport origin to a different part of the client area. This prevents the figures from being drawn one on top of the other. Changing the viewport origin does not affect the clipping region but does affect how the coordinates of the rectangle passed to RectVisible are interpreted. Changing the origin also allows you to use a single rectangle to check the update region rather than individual rectangles for each figure.


  20.2.4  Invalidating the Client Area

Windows is not the only source of WM_PAINT messages. The InvalidateRect or InvalidateRgn function can indirectly generate WM_PAINT messages for your windows. These functions mark all or part of a client area as invalid (that must be redrawn).

In the following code sample, the window procedure invalidates the entire client area when processing WM_CHAR messages. This allows the user to change the figure by typing a number and view the results, which are drawn as soon as there are no other messages in the application's message queue.

POINT aptPentagon[6] = {50,2, 98,35, 79,90, 21,90, 2,35, 50,2},

      aptHexagon[7]  = {50,2, 93,25, 93,75, 50,98, 7,75, 7,25, 50,2};

POINT *ppt = aptPentagon;

int cpt = 6;

  .

  .

  .

case WM_CHAR:

    switch (wParam) {

    case '5':

        ppt = aptPentagon;

        cpt = 6;

        break;

    case '6':

        ppt = aptHexagon;

        cpt = 7;

        break;

    }

    InvalidateRect(hwnd, NULL, TRUE);

    return 0L;

case WM_PAINT:

    hdc = BeginPaint(hwnd, &ps);

    GetClientRect(hwnd, &rc);

    SetMapMode(hdc, MM_ANISOTROPIC);

    SetWindowExtEx(hdc, 100, 100, NULL);

    SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);

    Polyline(hdc, ppt, cpt);

    EndPaint(hwnd, &ps);

    return 0L;

In this example, the NULL argument used in InvalidateRect specifies the entire client area; the TRUE argument causes the background to be erased. If you do not want the application to wait until the application's message queue has no other messages, use the UpdateWindow function to force the WM_PAINT message to be sent immediately. If there is any invalid part of the client area, UpdateWindow sends the WM_PAINT message for the given window directly to the window procedure.


  20.2.5  Drawing a Minimized Window

You can draw your own minimized windows rather than having Windows draw them for you. Most applications define a class icon when registering the window class for the window, and Windows draws the icon when the window is minimized. If you set the class icon to NULL, however, Windows sends a WM_PAINT message to your window procedure whenever the window is minimized, enabling the window procedure to draw in the minimized window.

In the following code sample, the window procedure draws a star in the minimized window. The procedure uses the IsIconic function to determine when the window is minimized. This ensures that the star is drawn only when the window is minimized.

POINT aptStar[6] = {50,2, 2,98, 98,33, 2,33, 98,98, 50,2};

  .

  .

  .

case WM_PAINT:

    hdc = BeginPaint(hwnd, &ps);

    /* Determine whether the window is minimized. */

    if (IsIconic(hwnd)) {

        GetClientRect(hwnd, &rc);

        SetMapMode(hdc, MM_ANISOTROPIC);

        SetWindowExtEx(hdc, 100, 100, NULL);

        SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);

        Polyline(hdc, aptStar, 6);

    } else {

        TextOut(hdc, 0,0, "Hello, Windows!", 15);

    }

    EndPaint(hwnd, &ps);

    return 0L;

You set the class icon to NULL by setting the hIcon member of the WNDCLASS structure to NULL before calling the RegisterClass function for the window class.


  20.2.6  Drawing a Custom Window Background

You can draw your own window background rather than having Windows draw it for you. Most applications specify a brush handle or system color value for the class background brush when registering the window class; Windows uses the brush or color to draw the background. If you set the class background brush to NULL, however, Windows sends a WM_ERASEBKGND message to your window procedure whenever the window background must be drawn, letting you draw a custom background.

In the following code sample, the window procedure draws a large checkerboard pattern that fits neatly in the window. The procedure fills the client area with a white brush and then draws thirteen 20-by-20 rectangles using a gray brush. The display DC to use when drawing the background is in the wParam parameter for the message.

HBRUSH hbrWhite, hbrGray;

  .

  .

  .

case WM_CREATE:

    hbrWhite = GetStockObject(WHITE_BRUSH);

    hbrGray  = GetStockObject(GRAY_BRUSH);

    return 0L;

case WM_ERASEBKGND:

    hdc = (HDC) wParam;

    GetClientRect(hwnd, &rc);

    SetMapMode(hdc, MM_ANISOTROPIC);

    SetWindowExtEx(hdc, 100, 100, NULL);

    SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);

    FillRect(hdc, &rc, hbrWhite);

    for (i = 0; i < 13; i++) {

        x = (i * 40) % 100;

        y = ((i * 40) / 100) * 20;

        SetRect(&rc, x, y, x + 20, y + 20);

        FillRect(hdc, &rc, hbrGray);

    }

  return 1L;

If the application draws its own minimized window, Windows also sends the WM_ERASEBKGND message to the window procedure to draw the background for the minimized window. You can use the same technique used with the WM_PAINT message to determine whether the window is minimized — that is, call the IsIconic function and check for the return value TRUE.


  20.3  Using the GetDC Function

You use the GetDC function to carry out drawing that must occur instantly rather than when a WM_PAINT message is processing. Such drawing is usually in response to an action by the user, such as making a selection or drawing with the mouse. In such cases, the user should receive instant feedback and must not be forced to stop selecting or drawing in order for the application to display the result. The following sections show how to use GetDC to draw in a window.


  20.3.1  Drawing with the Mouse

You can permit the user to draw lines with the mouse by having your window procedure draw while processing the WM_MOUSEMOVE message. Windows sends the WM_MOUSEMOVE message to the window procedure whenever the user moves the cursor within the window. To draw lines, the window procedure can retrieve a display DC and draw a line in the window between the current and previous cursor positions.

In the following code sample, the window procedure prepares for drawing when the user presses and holds the left mouse button (the WM_LBUTTONDOWN message). As the user moves the cursor within the window, the window procedure receives a series of WM_MOUSEMOVE messages. For each message, the window procedure draws a line connecting the previous position and the current position. To draw the line, the procedure uses GetDC to retrieve a display DC; then, as soon as drawing is complete and before returning from the message, the procedure uses the ReleaseDC function to release the display DC. As soon as the user releases the mouse button, the window procedure clears the flag, and the drawing stops (the WM_LBUTTONUP message).

BOOL fDraw = FALSE;

POINT ptPrevious;

  .

  .

  .

case WM_LBUTTONDOWN:

    fDraw = TRUE;

    ptPrevious.x = LOWORD(lParam);

    ptPrevious.y = HIWORD(lParam);

    return 0L;

case WM_LBUTTONUP:

    if (fDraw) {

        hdc = GetDC(hwnd);

        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);

        LineTo(hdc, LOWORD(lParam), HIWORD(lParam));

        ReleaseDC(hwnd, hdc);

    }

    fDraw = FALSE;

    return 0L;

case WM_MOUSEMOVE:

    if (fDraw) {

        hdc = GetDC(hwnd);

        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);

        LineTo(hdc, ptPrevious.x = LOWORD(lParam),

          ptPrevious.y = HIWORD(lParam));

        ReleaseDC(hwnd, hdc);

    }

  return 0L;

An application that enables drawing, as in this example, typically records either the points or lines so that the lines can be redrawn whenever the window is updated. Drawing applications often use a memory DC and an associated bitmap to store lines that were drawn by using a mouse.


  20.3.2  Drawing at Timed Intervals

You can draw at timed intervals by creating a timer with the SetTimer function. By using a timer to send WM_TIMER messages to the window procedure at regular intervals, an application can carry out simple animation in the client area while other applications continue running.

In the following code sample, the application bounces a star from side to side in the client area. Each time the window procedure receives a WM_TIMER message, the procedure erases the star at the current position, calculates a new position, and draws the star at the new position. The procedure starts the timer by calling SetTimer while processing the WM_CREATE message.

RECT rcCurrent = {0,0,20,20};

POINT aptStar[6] = {10,1, 1,19, 19,6, 1,6, 19,19, 10,1};

int X = 2, Y = -1, idTimer = -1;

BOOL fVisible = FALSE;

HDC hdc;

LRESULT APIENTRY WndProc(hwnd, message, wParam, lParam)

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

{

    PAINTSTRUCT ps;

    RECT rc;

    switch (message) {

        case WM_CREATE:

            /* Calculate the starting point. */

            GetClientRect(hwnd, &rc);

            OffsetRect(&rcCurrent, rc.right / 2, rc.bottom / 2);

            /* Initialize the private DC. */

            hdc = GetDC(hwnd);

            SetViewportOrgEx(hdc, rcCurrent.left,

                rcCurrent.top, NULL);

            SetROP2(hdc, R2_NOT);

            /* Start the timer. */

            SetTimer(hwnd, idTimer = 1, 10, NULL);

            return 0L;

        case WM_DESTROY:

            KillTimer(hwnd, 1);

            PostQuitMessage(0);

            return 0L;

        case WM_SIZE:

            switch (wParam) {

                case SIZE_MINIMIZED:

                    /* Stop the timer if the window is minimized. */

                    KillTimer(hwnd, 1);

                    idTimer = -1;

                    break;

                case SIZE_RESTORED:

                    /*

                     * Move the star back into the client area

                     * if necessary.

                     */

                    if (rcCurrent.right > (int) LOWORD(lParam))

                        rcCurrent.left =

                            (rcCurrent.right =

                                (int) LOWORD(lParam)) - 20;

                    if (rcCurrent.bottom > (int) HIWORD(lParam))

                        rcCurrent.top =

                            (rcCurrent.bottom =

                                (int) HIWORD(lParam)) - 20;

                    /* Fall through to the next case. */

                case SIZE_MAXIMIZED:

                    /* Start the timer if it had been stopped. */

                    if (idTimer == -1)

                        SetTimer(hwnd, idTimer = 1, 10, NULL);

                    break;

            }

            return 0L;

        case WM_TIMER:

            /* Hide the star if it is visible. */

            if (fVisible)

                Polyline(hdc, aptStar, 6);

            /* Bounce the star off a side if necessary. */

            GetClientRect(hwnd, &rc);

            if (rcCurrent.left + X < rc.left ||

                rcCurrent.right + X > rc.right)

                X = -X;

            if (rcCurrent.top + Y < rc.top ||

                rcCurrent.bottom + Y > rc.bottom)

                Y = -Y;

            /* Show the star in its new position. */

            OffsetRect(&rcCurrent, X, Y);

            SetViewportOrgEx(hdc, rcCurrent.left,

                rcCurrent.top, NULL);

            fVisible = Polyline(hdc, aptStar, 6);

            return 0L;

        case WM_ERASEBKGND:

            /* Erase the star. */

            fVisible = FALSE;

            return DefWindowProc(hwnd, message, wParam, lParam);

        case WM_PAINT:

            /*

             * Show the star if it is not visible. Use BeginPaint

             * to clear the update region.

             */

            BeginPaint(hwnd, &ps);

            if (!fVisible)

                fVisible = Polyline(hdc, aptStar, 6);

            EndPaint(hwnd, &ps);

            return 0L;

    }

    return DefWindowProc(hwnd, message, wParam, lParam);

}

This application uses a private DC to minimize the time required to prepare the DC for drawing. The window procedure retrieves and initializes the private DC when processing the WM_CREATE message, setting the binary raster operation mode to allow the star to be erased and drawn using the same call to the Polyline function. The window procedure also sets the viewport origin to allow the star to be drawn using the same set of points regardless of the star's position in the client area.

The application uses the WM_PAINT message to draw the star whenever the window must be updated. The window procedure draws the star only if it is not visible; that is, only if it has been erased by the WM_ERASEBKGND message. The window procedure intercepts the WM_ERASEBKGND message to set the fVisible variable, but passes the message to the DefWindowProc function so that Windows can draw the window background.

The application uses the WM_SIZE message to stop the timer when the window is minimized and to restart the timer when the minimized window is restored. The window procedure also uses the message to update the current position of the star if the size of the window has been reduced so that the star is no longer in the client area. The application keeps track of the star's current position by using the rcCurrent structure, which defines the bounding rectangle for the star. Keeping all corners of the rectangle in the client area keeps the star in the area. The window procedure initially centers the star in the client area when processing the WM_CREATE message.


  20.4  Functions and Messages

Use the following functions and messages for painting and drawing in windows.


  Functions

BeginPaint
EndPaint
ExcludeUpdateRgn
GdiFlush
GdiGetBatchLimit
GdiSetBatchLimit
GetBoundsRect
GetUpdateRect
GetUpdateRgn
GetWindowDC
InvalidateRect
InvalidateRgn
LockWindowUpdate
RedrawWindow
SetBoundsRect
SetRectRgn
UpdateWindow
ValidateRect
ValidateRgn
WindowFromDC


  Messages

WM_ERASEBKGND
WM_ICONERASEBKGND
WM_NCPAINT
WM_PAINT
WM_PAINTICON


21.1  About Cursors
  Chapter 21    Cursors

21.1  About Cursors

A cursor is a small bitmap whose location on the screen is controlled by a pointing device, such as a mouse, pen, or trackball. (In the remainder of this chapter, the term mouse refers to any pointing device.) When the user moves the mouse, Microsoft® Windows (™)  moves the cursor accordingly. Win32 (™)  cursor functions enable applications to create, load, display, move, confine, and destroy cursors.

Windows supports two kinds of cursors: standard and custom. Standard cursors are predefined cursors that Windows displays automatically as the user moves windows or icons, resizes windows, or pauses while a process is underway. Win32 display driver files provide 13 standard cursors, such as the arrow, hourglass, and crosshair. Windows and Windows-based applications can use these cursors. »This illustration« shows these standard cursors and their identifiers.

Custom cursors are designed for use in a specific application and can be any design the developer defines. »This illustration« shows several custom cursors.


  21.1.1  The Hot Spot

In the cursor, a pixel called the hot spot marks the exact screen location that is affected by a mouse event, such as clicking a mouse button. Typically, the hot spot is the focal point of the cursor. The system tracks and recognizes this point as the position of the cursor. For example, typical hot spots are the pixel at the tip of an arrow-shaped cursor and the pixel in the middle of a crosshair-shaped cursor.

When a mouse input event occurs, the Windows mouse driver translates the event into an appropriate mouse message that includes the coordinates of the hot spot. Windows sends the mouse message to the window that contains the hot spot or to the window that is capturing mouse input. For more information about mouse input, see Chapter 6, »Mouse Input«.


  21.1.2  The Mouse and the Cursor

If the system includes a mouse, Windows reflects the movement of the mouse by moving the cursor on the screen accordingly. As the cursor moves over different parts of windows or into different windows, Windows changes the appearance of the cursor. For example, when the cursor crosses a window border, Windows changes the cursor into a two-headed arrow.

If the system does not have a mouse, Windows displays and moves the cursor only when the user chooses certain system commands, such as those used to size or move a window. To provide the user with a method of displaying and moving the cursor when a mouse isn't available, an application can use the cursor functions to simulate mouse movement. Given this, the user can use the arrow keys to move the cursor.


  21.1.3  Cursor Creation

Because standard cursors are predefined, it is not necessary to create them. To use a standard cursor, an application retrieves a cursor handle by using the LoadCursor function. A cursor handle is a unique value of the HCURSOR type that identifies a standard or custom cursor.

To create a custom cursor for an application, developers typically use a graphics application and include the cursor as a resource in the application's resource-definition file. At run time, an application calls LoadCursor to retrieve the cursor handle. Cursor resources contain data for several different display devices. LoadCursor automatically selects the most appropriate data for the current display device.

An application can also create a custom cursor at run time by using the CreateCursor function. This function creates a cursor having the specified size, design, and hot spot.

Applications should implement custom cursors as resources and use LoadCursor rather than create the cursor at run time. Using cursor resources avoids device dependence, simplifies localization, and enables applications to share cursor designs.


  21.1.3.1  Alternative Cursor Creation

Two other functions create cursors at run time: CreateIconFromResource and CreateIconIndirect. These functions enable an application to browse through the system's resources and create icons and cursors based on resource data. CreateIconFromResource creates a cursor based on binary resource data from other executable files or dynamic-link libraries. It must be preceded by calls to the LookupIconIDFromDirectory function, as well as several resource functions. LookupIconIDFromDirectory identifies the most appropriate cursor data for the current display device. For more information about resource functions, see Chapter 51, "Resources," in Microsoft Win32 Programmer's Reference, Volume 2.

CreateIconIndirect creates a cursor based on the contents of an ICONINFO structure. The GetIconInfo function fills this structure with hot spot coordinates and information concerning the associated bitmask and color.


  21.1.4  Cursor Location and Appearance

If the system includes a mouse, Windows automatically displays a cursor and updates its position on the screen. Applications can obtain current screen coordinates of the cursor and move the cursor to any location on the screen by using the GetCursorPos and SetCursorPos functions, respectively.

Applications can also retrieve the handle of the current cursor by using the GetCursor function and can set the cursor by using the SetCursor function. After an application uses SetCursor, the appearance of the cursor does not change until the mouse moves, until the cursor is explicitly set to a different cursor, or until a system command is executed.

When the user moves the mouse, the system redraws the cursor at the new location as designated by the mouse. The system automatically redraws the cursor design associated with the window to which the cursor is pointing.

Applications can hide and redisplay the cursor, without changing the cursor design, by using the ShowCursor function. This function uses an internal counter to determine when to hide or display the cursor. An attempt to show the cursor increments the counter; an attempt to hide the cursor decrements the counter. The cursor is visible only if this counter is greater than or equal to zero.


  21.1.4.1  The Window Class Cursor

When registering a window class, an application can assign it a default cursor, known as the class cursor. After the application registers the window class, each window of that class will have the specified class cursor.

To override the class cursor, an application can process the WM_SETCURSOR message. Applications can also replace a class cursor by using the SetClassLong function. This function changes the default window settings for all windows of a given class. For more information about window classes, see Chapter 3, »Window Classes«.


  21.1.5  Cursor Confinement

Applications can confine the cursor to a rectangular area on the screen by using the ClipCursor function. This can be useful when the user must respond to a certain event within the confined area of the rectangle. For example, an application might use ClipCursor to confine the cursor to a modal dialog box, preventing the user from interacting with other windows until the dialog box is closed.

The GetClipCursor function retrieves the screen coordinates of the rectangular area to which the cursor is temporarily confined. When it is necessary to confine the cursor, the application can also use this function to save the coordinates of the original area in which the cursor can move. Then, the application can restore the cursor to the original area when the new confinement is no longer necessary.


  21.1.6  Cursor Destruction

When an application no longer needs a cursor it created by using the CreateCursor function, it should destroy the cursor. The DestroyCursor function destroys the cursor handle and frees any memory that it used. Applications should use this function only on cursors that were created with CreateCursor; it is not necessary to destroy other cursors.


  21.1.7  Cursor Duplication

The CopyCursor function copies a cursor handle. This enables an application or dynamic-link library to retrieve the handle of a cursor owned by another module. Then, if the other module is freed, the application that copied the cursor will still be able to use the cursor design.

For information on how to add, remove, or replace cursor resources in executable files, see Chapter 51, "Resources," in Microsoft Win32 Programmer's Reference, Volume 2.


  21.2  Using Cursors

This section describes how to perform the following tasks:

•	Create a cursor.

•	Display a cursor.

•	Confine a cursor.

•	Use a cursor in a mousetrap.

•	Use the keyboard to move the cursor.


  21.2.1  Creating a Cursor

The following code sample creates two cursor handles: one for the standard hourglass cursor and one for a custom cursor included as a resource in the application's resource-definition file.

HINSTANCE hinst;            /* handle of current instance */

HCURSOR hCurs1, hCurs2;     /* cursor handles             */

/* Create a standard hourglass cursor. */

hCurs1 = LoadCursor(NULL, IDC_WAIT);

/* Create a custom cursor based on a resource. */

hCurs2 = LoadCursor(hinst, MAKEINTRESOURCE(240));

An application should implement custom cursors as resources. Rather than create the cursors at run time, use the LoadCursor function to avoid device dependence, to simplify localization, and to enable applications to share cursor designs.

The following example is included to illustrate how the system interprets cursor bitmasks. Use the CreateCursor function to create a custom cursor at run time, based on cursor bitmasks.

HINSTANCE hinst;            /* handle of current instance */

HCURSOR hCurs1, hCurs2;     /* cursor handles             */

HCURSOR hCurs3;             /* cursor handle              */

/* Yin cursor AND bitmask */

BYTE ANDmaskCursor[] = {0xFF, 0xFC, 0x3F, 0xFF,   /* line 1 */

                        0xFF, 0xC0, 0x1F, 0xFF,   /* line 2 */

                        0xFF, 0x00, 0x3F, 0xFF,   /* line 3 */

                        0xFE, 0x00, 0xFF, 0xFF,   /* line 4 */

                        0xF7, 0x01, 0xFF, 0xFF,   /* line 5 */

                        0xF0, 0x03, 0xFF, 0xFF,   /* line 6 */

                        0xF0, 0x03, 0xFF, 0xFF,   /* line 7 */

                        0xE0, 0x07, 0xFF, 0xFF,   /* line 8 */

                        0xC0, 0x07, 0xFF, 0xFF,   /* line 9 */

                        0xC0, 0x0F, 0xFF, 0xFF,   /* line 10 */

                        0x80, 0x0F, 0xFF, 0xFF,   /* line 11 */

                        0x80, 0x0F, 0xFF, 0xFF,   /* line 12 */

                        0x80, 0x07, 0xFF, 0xFF,   /* line 13 */

                        0x00, 0x07, 0xFF, 0xFF,   /* line 14 */

                        0x00, 0x03, 0xFF, 0xFF,   /* line 15 */

                        0x00, 0x00, 0xFF, 0xFF,   /* line 16 */

                        0x00, 0x00, 0x7F, 0xFF,   /* line 17 */

                        0x00, 0x00, 0x1F, 0xFF,   /* line 18 */

                        0x00, 0x00, 0x0F, 0xFF,   /* line 19 */

                        0x80, 0x00, 0x0F, 0xFF,   /* line 20 */

                        0x80, 0x00, 0x07, 0xFF,   /* line 21 */

                        0x80, 0x00, 0x07, 0xFF,   /* line 22 */

                        0xC0, 0x00, 0x07, 0xFF,   /* line 23 */

                        0xC0, 0x00, 0x0F, 0xFF,   /* line 24 */

                        0xE0, 0x00, 0x0F, 0xFF,   /* line 25 */

                        0xF0, 0x00, 0x1F, 0xFF,   /* line 26 */

                        0xF0, 0x00, 0x1F, 0xFF,   /* line 27 */

                        0xF8, 0x00, 0x3F, 0xFF,   /* line 28 */

                        0xFE, 0x00, 0x7F, 0xFF,   /* line 29 */

                        0xFF, 0x00, 0xFF, 0xFF,   /* line 30 */

                        0xFF, 0xC3, 0xFF, 0xFF,   /* line 31 */

                        0xFF, 0xFF, 0xFF, 0xFF};  /* line 32 */

/* Yin cursor XOR bitmask */

BYTE XORmaskCursor[] = {0x00, 0x00, 0x00, 0x00,   /* line 1 */

                        0x00, 0x03, 0xC0, 0x00,   /* line 2 */

                        0x00, 0x3F, 0x00, 0x00,   /* line 3 */

                        0x00, 0xFE, 0x00, 0x00,   /* line 4 */

                        0x0E, 0xFC, 0x00, 0x00,   /* line 5 */

                        0x07, 0xF8, 0x00, 0x00,   /* line 6 */

                        0x07, 0xF8, 0x00, 0x00,   /* line 7 */

                        0x0F, 0xF0, 0x00, 0x00,   /* line 8 */

                        0x1F, 0xF0, 0x00, 0x00,   /* line 9 */

                        0x1F, 0xE0, 0x00, 0x00,   /* line 10 */

                        0x3F, 0xE0, 0x00, 0x00,   /* line 11 */

                        0x3F, 0xE0, 0x00, 0x00,   /* line 12 */

                        0x3F, 0xF0, 0x00, 0x00,   /* line 13 */

                        0x7F, 0xF0, 0x00, 0x00,   /* line 14 */

                        0x7F, 0xF8, 0x00, 0x00,   /* line 15 */

                        0x7F, 0xFC, 0x00, 0x00,   /* line 16 */

                        0x7F, 0xFF, 0x00, 0x00,   /* line 17 */

                        0x7F, 0xFF, 0x80, 0x00,   /* line 18 */

                        0x7F, 0xFF, 0xE0, 0x00,   /* line 19 */

                        0x3F, 0xFF, 0xE0, 0x00,   /* line 20 */

                        0x3F, 0xC7, 0xF0, 0x00,   /* line 21 */

                        0x3F, 0x83, 0xF0, 0x00,   /* line 22 */

                        0x1F, 0x83, 0xF0, 0x00,   /* line 23 */

                        0x1F, 0x83, 0xE0, 0x00,   /* line 24 */

                        0x0F, 0xC7, 0xE0, 0x00,   /* line 25 */

                        0x07, 0xFF, 0xC0, 0x00,   /* line 26 */

                        0x07, 0xFF, 0xC0, 0x00,   /* line 27 */

                        0x01, 0xFF, 0x80, 0x00,   /* line 28 */

                        0x00, 0xFF, 0x00, 0x00,   /* line 29 */

                        0x00, 0x3C, 0x00, 0x00,   /* line 30 */

                        0x00, 0x00, 0x00, 0x00,   /* line 31 */

                        0x00, 0x00, 0x00, 0x00};  /* line 32 */

/* Create a custom cursor at run time. */

hCurs3 = CreateCursor(hinst,  /* app instance */

             19,     /* horiz pos of hot spot */

             2,      /* vert pos of hot spot  */

             32,     /* cursor width          */

             32,     /* cursor height         */

             ANDmaskCursor,    /* AND bitmask */

             XORmaskCursor);   /* XOR bitmask */

To create the cursor, CreateCursor applies the following truth table to the AND and XOR bitmasks.

AND	XOR	Display
0	0	Black
0	1	White
1	0	Screen
1	1	Reverse screen
For more information about bitmaps, see Chapter 29, »Bitmaps«.

Before closing, your application must use the DestroyCursor function to destroy any cursors it created with CreateCursor. It is not necessary to destroy cursors created by other functions.


  21.2.2  Displaying a Cursor

If the system includes a mouse, Windows automatically displays the class cursor (the cursor associated with the window to which the cursor is pointing). Your application can assign a class cursor while registering a window class. The following example illustrates this by assigning a cursor handle to the hCursor member of the WNDCLASS structure identified by the wc parameter.

WNDCLASS  wc;

/*

 * Fill the window class structure with parameters that describe

 * the main window.

 */

wc.style = NULL;                        /* class style(s)   */

wc.lpfnWndProc = (WNDPROC) MainWndProc; /* window procedure */

wc.cbClsExtra = 0;             /* no per-class extra data   */

wc.cbWndExtra = 0;             /* no per-window extra data  */

wc.hInstance = hinstance;      /* app that owns the class   */

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);   /* class icon */

wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(230));

                                            /* class cursor */

wc.hbrBackground = GetStockObject(WHITE_BRUSH);

                                        /* class background */

wc.lpszMenuName =  "GenericMenu";             /* class menu */

wc.lpszClassName = "GenericWClass";           /* class name */

/* Register the window class. */

return RegisterClass(&wc);

When the window class is registered, the cursor identified by 230 in the application's resource-definition file will be the default cursor for all windows based on the class.

Your application can change the design of the cursor by using the SetCursor function and specifying a different cursor handle. However, when the cursor moves, Windows redraws the class cursor at the new location. To prevent the class cursor from being redrawn, your application must process the WM_SETCURSOR message. Each time the cursor moves and mouse input is not captured, Windows sends this message to the window in which the cursor is moving.

You can specify different cursors for different conditions while processing WM_SETCURSOR. For example, the following code shows how to display the hCurs3 cursor whenever the cursor moves over the icon of a minimized application.

case WM_SETCURSOR:

    /*

     * If the window is minimized, draw the hCurs3 cursor.

     * If the window is not minimized, draw the default

     * cursor (class cursor).

     */

    if (IsIconic(hwnd)) {

        SetCursor(hCurs3);

        break;

    }

When the window is not minimized, Windows displays the class cursor.

Your application can replace a class cursor by using the SetClassLong function. This function changes the default window settings for all windows of a given class. The following example replaces the existing class cursor with the hCurs2 cursor.

/* Change the cursor for hwnd's window class. */

SetClassLong(hwnd,    /* window handle */

    GCL_HCURSOR,      /* change cursor */

    (LONG) hCurs2);   /* new cursor    */

For more information about window classes and mouse input, see Chapter 3, »Window Classes«, and Chapter 6, »Mouse Input«.


  21.2.3  Confining a Cursor

The following example confines the cursor to the application's window and then restores the cursor to its previous window. The example uses the GetClipCursor function to record the area in which the cursor can move and the ClipCursor function to confine and restore the cursor.

RECT rcClip;           /* new ClipCursor area      */

RECT rcOldClip;        /* previous ClipCursor area */

/* Record the area in which the cursor can move. */

GetClipCursor(&rcOldClip);

/* Get the dimensions of the application's window. */

GetWindowRect(hwnd, &rcClip);

/* Confine the cursor to the application's window. */

ClipCursor(&rcClip);

    .

    . /* Process input from the confined cursor. */

    .

/* Restore the cursor to its previous area. */

ClipCursor(&rcOldClip);

Because there is only one cursor at a time available in the system, an application that confines the cursor must restore the cursor before relinquishing control to another window.


  21.2.4  Creating a Mousetrap

The following example uses the  SetCursorPos, GetCursorPos, CreateCursor, LoadCursor, and SetCursor functions to create a simple mousetrap. It also uses cursor and timer functions to monitor the cursor's position every 10 seconds. If the cursor position has not changed in the last 10 seconds and the application's main window is minimized, the application changes the cursor and moves it to the mousetrap icon.

Sample code for a similar mousetrap is included in Chapter 23, "Icons." It uses the LoadCursor and LoadIcon functions instead of the more device-dependent CreateCursor and CreateIcon.

HICON hIcon1;               /* icon handles             */

POINT ptOld;                /* previous cursor location */

HCURSOR hCurs1;             /* cursor handle            */

/*

 * The following cursor bitmasks are defined in a code example

 * that appears earlier in this chapter.

 */

/* Yin cursor AND and XOR bitmasks */

BYTE ANDmaskCursor[] = ...

BYTE XORmaskCursor[] = ...

/* Yang icon AND bitmask */

BYTE ANDmaskIcon[] = {0xFF, 0xFF, 0xFF, 0xFF,   /* line 1 */

                      0xFF, 0xFF, 0xC3, 0xFF,   /* line 2 */

                      0xFF, 0xFF, 0x00, 0xFF,   /* line 3 */

                      0xFF, 0xFE, 0x00, 0x7F,   /* line 4 */

                      0xFF, 0xFC, 0x00, 0x1F,   /* line 5 */

                      0xFF, 0xF8, 0x00, 0x0F,   /* line 6 */

                      0xFF, 0xF8, 0x00, 0x0F,   /* line 7 */

                      0xFF, 0xF0, 0x00, 0x07,   /* line 8 */

                      0xFF, 0xF0, 0x00, 0x03,   /* line 9 */

                      0xFF, 0xE0, 0x00, 0x03,   /* line 10 */

                      0xFF, 0xE0, 0x00, 0x01,   /* line 11 */

                      0xFF, 0xE0, 0x00, 0x01,   /* line 12 */

                      0xFF, 0xF0, 0x00, 0x01,   /* line 13 */

                      0xFF, 0xF0, 0x00, 0x00,   /* line 14 */

                      0xFF, 0xF8, 0x00, 0x00,   /* line 15 */

                      0xFF, 0xFC, 0x00, 0x00,   /* line 16 */

                      0xFF, 0xFF, 0x00, 0x00,   /* line 17 */

                      0xFF, 0xFF, 0x80, 0x00,   /* line 18 */

                      0xFF, 0xFF, 0xE0, 0x00,   /* line 19 */

                      0xFF, 0xFF, 0xE0, 0x01,   /* line 20 */

                      0xFF, 0xFF, 0xF0, 0x01,   /* line 21 */

                      0xFF, 0xFF, 0xF0, 0x01,   /* line 22 */

                      0xFF, 0xFF, 0xF0, 0x03,   /* line 23 */

                      0xFF, 0xFF, 0xE0, 0x03,   /* line 24 */

                      0xFF, 0xFF, 0xE0, 0x07,   /* line 25 */

                      0xFF, 0xFF, 0xC0, 0x0F,   /* line 26 */

                      0xFF, 0xFF, 0xC0, 0x0F,   /* line 27 */

                      0xFF, 0xFF, 0x80, 0x1F,   /* line 28 */

                      0xFF, 0xFF, 0x00, 0x7F,   /* line 29 */

                      0xFF, 0xFC, 0x00, 0xFF,   /* line 30 */

                      0xFF, 0xF8, 0x03, 0xFF,   /* line 31 */

                      0xFF, 0xFC, 0x3F, 0xFF};  /* line 32 */

/* Yang icon XOR bitmask */

BYTE XORmaskIcon[] = {0x00, 0x00, 0x00, 0x00,   /* line 1 */

                      0x00, 0x00, 0x00, 0x00,   /* line 2 */

                      0x00, 0x00, 0x00, 0x00,   /* line 3 */

                      0x00, 0x00, 0x00, 0x00,   /* line 4 */

                      0x00, 0x00, 0x00, 0x00,   /* line 5 */

                      0x00, 0x00, 0x00, 0x00,   /* line 6 */

                      0x00, 0x00, 0x00, 0x00,   /* line 7 */

                      0x00, 0x00, 0x38, 0x00,   /* line 8 */

                      0x00, 0x00, 0x7C, 0x00,   /* line 9 */

                      0x00, 0x00, 0x7C, 0x00,   /* line 10 */

                      0x00, 0x00, 0x7C, 0x00,   /* line 11 */

                      0x00, 0x00, 0x38, 0x00,   /* line 12 */

                      0x00, 0x00, 0x00, 0x00,   /* line 13 */

                      0x00, 0x00, 0x00, 0x00,   /* line 14 */

                      0x00, 0x00, 0x00, 0x00,   /* line 15 */

                      0x00, 0x00, 0x00, 0x00,   /* line 16 */

                      0x00, 0x00, 0x00, 0x00,   /* line 17 */

                      0x00, 0x00, 0x00, 0x00,   /* line 18 */

                      0x00, 0x00, 0x00, 0x00,   /* line 19 */

                      0x00, 0x00, 0x00, 0x00,   /* line 20 */

                      0x00, 0x00, 0x00, 0x00,   /* line 21 */

                      0x00, 0x00, 0x00, 0x00,   /* line 22 */

                      0x00, 0x00, 0x00, 0x00,   /* line 23 */

                      0x00, 0x00, 0x00, 0x00,   /* line 24 */

                      0x00, 0x00, 0x00, 0x00,   /* line 25 */

                      0x00, 0x00, 0x00, 0x00,   /* line 26 */

                      0x00, 0x00, 0x00, 0x00,   /* line 27 */

                      0x00, 0x00, 0x00, 0x00,   /* line 28 */

                      0x00, 0x00, 0x00, 0x00,   /* line 29 */

                      0x00, 0x00, 0x00, 0x00,   /* line 30 */

                      0x00, 0x00, 0x00, 0x00,   /* line 31 */

                      0x00, 0x00, 0x00, 0x00};  /* line 32 */

hIcon1 = CreateIcon(hinstance, /* handle of app instance   */

             32,           /* icon width                   */

             32,           /* icon height                  */

             1,            /* number of XOR planes         */

             1,            /* number of bits per pixel     */

             ANDmaskIcon,  /* AND bitmask                  */

             XORmaskIcon); /* XOR bitmask                  */

hCurs1 = CreateCursor(hinstance, /* handle of app instance */

             19,         /* horiz. position of hot spot    */

             2,          /* vert. position of hot spot     */

             32,         /* cursor width                   */

             32,         /* cursor height                  */

             ANDmaskCursor,            /* AND bitmask      */

             XORmaskCursor);           /* XOR bitmask      */

.

. /* Fill in the window class structure. */

.

WNDCLASS  wc;

wc.hIcon = hIcon1;                        /* class icon   */

wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* class cursor */

.

. /*

. * Register the window class and perform

. * other application initialization.

. */

.

/* Set a timer for the mousetrap. */

GetCursorPos(&ptOld);

SetTimer(hwnd, IDT_CURSOR, 10000, (TIMERPROC) NULL);

LONG APIENTRY MainWndProc(

    HWND hwnd,          /* window handle          */

    UINT message,       /* type of message        */

    UINT wParam,        /* additional information */

    LONG lParam)        /* additional information */

{

    HDC hdc;              /* handle of device context */

    POINT pt;             /* current cursor location  */

    RECT rc;              /* iconized window location */

    switch (message) {

         .

         . /* Process other messages. */

         .

        case WM_TIMER:

            /*

             * If the window is minimized, compare the current

             * cursor position with the one 10 seconds before.

             * If the cursor position has not changed, move the

             * cursor to the icon.

             */

            if (IsIconic(hwnd)) {

                GetCursorPos(&pt);

                if ((pt.x == ptOld.x) && (pt.y == ptOld.y)) {

                    GetWindowRect(hwnd, &rc);

                    SetCursorPos(rc.left + 20, rc.top + 4);

                    /*

                     * Note that the additional constants

                     * (20 and 4) are application-specific

                     * values to align the yin-shaped cursor

                     * and the yang-shaped icon.

                     */

                }

                else {

                    ptOld.x = pt.x;

                    ptOld.y = pt.y;

                }

            }

            return 0;

        case WM_SETCURSOR:

            /*

             * If the window is minimized, draw hCurs1.

             * If the window is not minimized, draw the default

             * cursor (class cursor).

             */

            if (IsIconic(hwnd)) {

                SetCursor(hCurs1);

                break;

            }

        case WM_DESTROY:

            /* Destroy timer. */

            KillTimer(hwnd, IDT_CURSOR);

            PostQuitMessage(0);

            break;

                .

                . /* Process other messages. */

                .

    }             /* ends switch (message) */


  21.2.5  Using the Keyboard to Move the Cursor

Because Windows does not require a mouse, an application should be able to simulate mouse actions with the keyboard. The following example shows how to achieve this, by using the GetCursorPos and SetCursorPos functions, and by processing input from the arrow keys.

HCURSOR hCurs1, hCurs2;    /* cursor handles        */

POINT pt;                  /* cursor location         */

RECT rc;                   /* client area coordinates */

static int repeat = 1;     /* repeat key counter      */

.

. /* Other declarations and initialization. */

.

switch (message) {

.

. /* Process other messages. */

.

    case WM_KEYDOWN:

        if (wParam != VK_LEFT && wParam != VK_RIGHT &&

        wParam != VK_UP && wParam != VK_DOWN) {

            break;

        }

        GetCursorPos(&pt);

        /* Convert screen coordinates to client coordinates. */

        ScreenToClient(hwnd, &pt);

        switch (wParam) {

            /*

             * Move the cursor to reflect which

             * arrow keys are pressed.

             */

            case VK_LEFT: /* left arrow */

                pt.x -= repeat;

                break;

            case VK_RIGHT: /* right arrow */

                pt.x += repeat;

                break;

            case VK_UP: /* up arrow */

                pt.y -= repeat;

                break;

            case VK_DOWN: /* down arrow */

                pt.y += repeat;

                break;

            default:

                return NULL;

        }

        repeat++;           /* increments repeat count */

        /* Keep the cursor in the client area. */

        GetClientRect(hwnd, &rc);

        if (pt.x >= rc.right) {

            pt.x = rc.right - 1;

        }

        else {

            if (pt.x < rc.left) {

                pt.x = rc.left;

            }

        }

        if (pt.y >= rc.bottom) {

            pt.y = rc.bottom - 1;

        }

        else {

            if (pt.y < rc.top) {

                pt.y = rc.top;

            }

        }

        /* Convert client coordinates to screen coordinates. */

        ClientToScreen(hwnd, &pt);

        SetCursorPos(pt.x, pt.y);

        break;

    case WM_KEYUP:

        repeat = 1;            /* clears repeat count */

        break;

        .

        .

        .

    }               /* ends switch (message) */


  21.3  Functions and Messages

The following functions and messages are used with cursors.


  Functions

ClipCursor
CopyCursor
CreateCursor
DestroyCursor
GetClipCursor
GetCursor
GetCursorPos
LoadCursor
SetCursor
SetCursorPos
ShowCursor


  Messages

WM_SETCURSOR


22.1  About Carets
  Chapter 22    Carets

22.1  About Carets

A caret is a flashing line, block, or bitmap in the client area of a window; the caret typically indicates the place at which text or graphics will be inserted. »This illustration« shows some common variations in the appearance of the caret.

Because only one window at a time can have the keyboard focus or be active, there is only one caret in the system. Generally, each window that accepts keyboard input must create the caret when it receives the keyboard focus and destroy the caret when it loses the keyboard focus. For more information on keyboard input, see Chapter 5, »Keyboard Input«.

An application written for Microsoft® Windows (™)  can create a caret, display or hide it, relocate the caret, and change its blink time.

An application uses the CreateCaret function to specify the parameters for a caret. Microsoft Windows forms a caret by inverting the pixel color within the rectangle specified by the caret's position, width, and height. The width and height are specified in logical units; therefore, the appearance of a caret is subject to the window's mapping mode.

After the caret is defined, an application uses the ShowCaret function to make the caret visible. When the caret appears, it automatically begins flashing. To display a solid caret, Windows inverts every pixel in the rectangle; to display a gray caret, Windows inverts every other pixel; to display a bitmap caret, Windows inverts only the white bits of the bitmap.

The elapsed time, in milliseconds, required to invert the caret is called the blink time. An application can determine the caret's blink time by using the GetCaretBlinkTime function. If it is necessary to define a specific blink time, use the SetCaretBlinkTime function to set the rate of the blink time to a specified number of milliseconds. The flash time is the elapsed time, in milliseconds, required to display, invert, and restore the caret's display. The flash time of a caret is twice as much as the blink time.

An application can determine the caret's position by using the GetCaretPos function. The position, in client coordinates, is copied to a POINT structure specified by a parameter in GetCaretPos. An application can move a caret in a window by using the SetCaretPos function. A window can move a caret only if it already owns the caret. SetCaretPos can move the caret whether it is visible or not.

An application can use the HideCaret function to remove the caret from the screen. This is useful when your application must redraw the screen while processing a message but must keep the caret out of the way. When the application finishes drawing, it can display the caret again by using the ShowCaret function. Hiding the caret does not destroy its shape or invalidate the insertion point. Hiding the caret is cumulative; that is, if the application calls HideCaret five times, it must also call ShowCaret five times before the caret will reappear.

An application can remove the caret from the screen and destroy its shape by using the DestroyCaret function. DestroyCaret destroys the caret only if the window involved in the current task owns the caret.


  22.2  Using Carets

This section explains how to perform the following tasks:

•	Create and display a caret.

•	Hide a caret.

•	Destroy a caret

•	Adjust the blink time.

•	Move the caret while processing keyboard input.


  22.2.1  Creating and Displaying a Caret

Upon receiving the keyboard focus, the window should create and display the caret. Use the CreateCaret function to create a caret in the given window. Then call SetCaretPos to set the current position of the caret and ShowCaret to make the caret visible.

The system sends the WM_SETFOCUS message to the window receiving keyboard focus; therefore, an application should create and display the caret while processing this message.

HWND hwnd,   /* window handle                   */

int x;       /* horizontal coordinate of cursor */

int y;       /* vertical coordinate of cursor   */

int nWidth;      /* width of cursor             */

int nHeight;     /* height of cursor            */

char *lpszChar;  /* pointer to character        */

    case WM_SETFOCUS:

        /* Create a solid black caret. */

        CreateCaret(hwnd, (HBITMAP) NULL, nWidth, nHeight);

        /* Adjust the caret position, in client coordinates. */

        SetCaretPos(x, y);

        /* Display the caret. */

        ShowCaret(hwnd);

        break;

To create a caret based on a bitmap, you must specify a bitmap handle when using CreateCaret. You can use a graphics application to create the bitmap and a resource compiler to add the bitmap to your application's resources. Your application can then use the LoadBitmap function to load the bitmap handle. For example, you could replace the CreateCaret line in the preceding example with the following lines to create a bitmap caret.

/* Load the application-defined caret resource. */

hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));

/* Create a bitmap caret. */

CreateCaret(hwnd, hCaret, 0, 0);

Alternatively, you can use the CreateBitmap or CreateDIBitmap function to retrieve the handle of the caret bitmap. For more information about bitmaps, see Chapter 29, »Bitmaps«.

If your application specifies a bitmap handle, CreateCaret ignores the width and height parameters. The bitmap defines the size of the caret.


  22.2.2  Hiding a Caret

Whenever your application redraws a screen while processing a message other than WM_PAINT, it must make the caret invisible by using the HideCaret function. When your application is finished drawing, redisplay the caret by using the ShowCaret function. If your application processes the WM_PAINT message, it is not necessary to hide and redisplay the caret, because this function does this automatically.

The following code sample shows how to have your application hide the caret while drawing a character on the screen and while processing the WM_CHAR message.

HWND hwnd,   /* window handle                   */

HDC hdc;     /* device context                  */

    case WM_CHAR:

        switch (wParam) {

            case 0x08:

             .

             . /* Process a backspace. */

             .

                break;

            case 0x09:

             .

             . /* Process a tab. */

             .

                break;

            case 0x0D:

             .

             . /* Process a carriage return. */

             .

                break;

            case 0x1B:

             .

             . /* Process an escape. */

             .

                break;

            case 0x0A:

             .

             . /* Process a linefeed. */

             .

                break;

            default:

                /* Process all other characters. */

                /* Hide the caret. */

                HideCaret(hwnd);

                /* Draw the character on the screen. */

                hdc = GetDC(hwnd);

                SelectObject(hdc,

                    GetStockObject(SYSTEM_FIXED_FONT));

                TextOut(hdc, x, y, lpszChar, 1);

                ReleaseDC(hwnd, hdc);

                /* Display the caret. */

                ShowCaret(hwnd);

        }

If your application calls the HideCaret function several times without calling ShowCaret, the caret will not be displayed until the application also calls ShowCaret the same number of times.


  22.2.3  Destroying a Caret

When a window loses the keyboard focus, the system sends the WM_KILLFOCUS message to the window. Your application should destroy the caret while processing this message by using the DestroyCaret function. The following code shows how to destroy a caret in a window that no longer has the keyboard focus.

case WM_KILLFOCUS:

    /*

     * The window is losing the keyboard focus,

     * so destroy the caret.

     */

    DestroyCaret();

    break;


  22.2.4  Adjusting the Blink Time

Because there is only one caret in the system, use caution when your application must adjust the rate of the blink time, so as not to disrupt subsequent windows that may receive the keyboard focus. If your application changes the blink time, it must restore the blink time to its original value upon losing the keyboard focus. The GetCaretBlinkTime function returns the current blink time, in milliseconds, and the SetCaretBlinkTime function sets the blink time to the specified number of milliseconds.

If you anticipate that your application will adjust the blink time, add the following line to the WM_SETFOCUS message processing:

uOldBlink = GetCaretBlinkTime();

Then, you can restore the blink time to its original rate by including the following line in the WM_KILLFOCUS message processing:

SetCaretBlinkTime(uOldBlink);


  22.2.5  Processing Keyboard Input

The following code sample demonstrates how to use a caret in a simple text editor. The code updates the caret position as the user types printable characters and uses various keys to move through the client area.

#define TEXTMATRIX(x, y) *(pTextMatrix + (y * nWindowCharsX) + x)

HINSTANCE hinst;           /* current instance                 */

HBITMAP hCaret;            /* caret bitmap                     */

HDC hdc;                   /* device context                   */

PAINTSTRUCT ps;            /* client area paint info           */

static char *pTextMatrix = NULL;   /* pointer to text matrix   */

static int  nCharX,        /* width of char. in logical units  */

            nCharY,        /* height of char. in logical units */

            nWindowX,      /* width of client area             */

            nWindowY,      /* height of client area            */

            nWindowCharsX, /* width of client area in char.s   */

            nWindowCharsY, /* height of client area in char.s  */

            nCaretPosX,    /* x-position of caret in matrix    */

            nCaretPosY;    /* y-position of caret in matrix    */

static UINT uOldBlink;     /* holds previous blink rate        */

int x, y;       /* x and y coordinates to use in text matrix   */

TEXTMETRIC tm;             /* font information                 */

LONG APIENTRY MainWndProc(

    HWND hwnd,            /* window handle              */

    UINT message,         /* type of message            */

    UINT wParam,          /* additional information     */

    LONG lParam)          /* additional information     */

{

switch (message) {

    case WM_CREATE:

        /*

         * Select a fixed-width system font,

         * and get the text metrics of the font.

         */

        hdc = GetDC(hwnd);

        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

        GetTextMetrics(hdc, &tm);

        ReleaseDC(hwnd, hdc);

        /* Save the avg. width and height of the characters. */

        nCharX = tm.tmAveCharWidth;

        nCharY = tm.tmHeight;

        return 0;

    case WM_SIZE:

        /*

         * Determine the width of the client area, in pixels

         * and in number of characters.

         */

        nWindowX = LOWORD(lParam);

        nWindowCharsX = max(1, nWindowX/nCharX);

        /*

         * Determine the height of the client area, in pixels

         * and in number of characters.

         */

        nWindowY = HIWORD(lParam);

        nWindowCharsY = max(1, nWindowY/nCharY);

        /* Clear the buffer that holds the text input. */

        if (pTextMatrix != NULL) {

            free(pTextMatrix);

        }

        /*

         * If there is enough memory, allocate space for the

         * text input buffer.

         */

        pTextMatrix = malloc(nWindowCharsX * nWindowCharsY);

        if (pTextMatrix == NULL) {

            ErrorHandler("Not enough memory.");

        }

        else {

            for (y = 0; y < nWindowCharsY; y++)

                for (x = 0; x < nWindowCharsX; x++)

                    TEXTMATRIX(x, y) = ' ';

        }

        /* Move the caret to the origin. */

        SetCaretPos(0, 0);

        return 0;

    case WM_KEYDOWN:

        switch (wParam) {

            case VK_HOME: /* Home */

                nCaretPosX = 0;

                break;

            case VK_END: /* End */

                nCaretPosX = nWindowCharsX - 1;

                break;

            case VK_PRIOR: /* Page Up */

                nCaretPosY = 0;

                break;

            case VK_NEXT: /* Page Down */

                nCaretPosY = nWindowCharsY -1;

                break;

            case VK_LEFT: /* Left arrow */

                nCaretPosX = max(nCaretPosX - 1, 0);

                break;

            case VK_RIGHT: /* Right arrow */

                nCaretPosX = min(nCaretPosX + 1,

                    nWindowCharsX - 1);

                break;

            case VK_UP: /* Up arrow */

                nCaretPosY = max(nCaretPosY - 1, 0);

                break;

            case VK_DOWN: /* Down arrow */

                nCaretPosY = min(nCaretPosY + 1,

                    nWindowCharsY - 1);

                break;

            case VK_DELETE: /* Delete */

                /*

                 * Move all the characters that followed the

                 * deleted character (on the same line) one

                 * space back (to the left) in the matrix.

                 */

                for (x = nCaretPosX; x < nWindowCharsX; x++)

                    TEXTMATRIX(x, nCaretPosY) =

                        TEXTMATRIX(x + 1, nCaretPosY);

                /*

                 * Replace the last character on the

                 * line with a space.

                 */

                TEXTMATRIX(nWindowCharsX - 1,

                    nCaretPosY) = ' ';

                /*

                 * The application will draw outside the

                 * WM_PAINT message processing, so hide the

                 * caret.

                 */

                HideCaret(hwnd);

                /*

                 * Redraw the line, adjusted for the

                 * deleted character.

                 */

                hdc = GetDC(hwnd);

                SelectObject(hdc,

                    GetStockObject(SYSTEM_FIXED_FONT));

                TextOut(hdc,

                    nCaretPosX * nCharX, nCaretPosY * nCharY,

                    &TEXTMATRIX(nCaretPosX, nCaretPosY),

                    nWindowCharsX - nCaretPosX);

                ReleaseDC(hwnd, hdc);

                /* Display the caret. */

                ShowCaret(hwnd);

                break;

        }

        /*

         * Adjust the caret position based on the

         * virtual-key processing.

         */

        SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);

        return 0;

    case WM_CHAR:

        switch (wParam) {

            case 0x08: /* Backspace */

                /*

                 * Move the caret back one space, and then process

                 * this like the DEL key.

                 */

                if (nCaretPosX > 0) {

                    nCaretPosX--;

                    SendMessage(hwnd, WM_KEYDOWN,

                        VK_DELETE, 1L);

                }

                break;

            case 0x09: /* Tab */

                /*

                 * Tab stops exist every four spaces, so add

                 * spaces until the user hits the next tab stop.

                 */

                do {

                    SendMessage(hwnd, WM_CHAR, ' ', 1L);

                } while (nCaretPosX % 4 != 0);

                break;

            case 0x0D: /* Carriage return */

                /*

                 * Go to the beginning of the next line.

                 * The bottom line wraps around to the top.

                 */

                nCaretPosX = 0;

                if (++nCaretPosY == nWindowCharsY) {

                    nCaretPosY = 0;

                }

                break;

            case 0x1B: /* Escape */

            case 0x0A: /* Linefeed */

                /* No processing. */

                MessageBeep((UINT) -1);

                break;

            default: /* all other characters */

                /* Add the character to the text buffer. */

                TEXTMATRIX(nCaretPosX, nCaretPosY) =

                    (char) wParam;

                /*

                 * The application will draw outside the

                 * WM_PAINT message processing, so hide the

                 * caret.

                 */

                HideCaret(hwnd);

                /* Draw the character on the screen. */

                hdc = GetDC(hwnd);

                SelectObject(hdc,

                    GetStockObject(SYSTEM_FIXED_FONT));

                TextOut(hdc, nCaretPosX * nCharX,

                    nCaretPosY * nCharY,

                    &TEXTMATRIX(nCaretPosX, nCaretPosY), 1);

                ReleaseDC(hwnd, hdc);

                /* Display the caret. */

                ShowCaret(hwnd);

                /*

                 * Prepare to wrap around if you reached the

                 * end of the line.

                 */

                if (++nCaretPosX == nWindowCharsX) {

                    nCaretPosX = 0;

                    if (++nCaretPosY == nWindowCharsY) {

                        nCaretPosY = 0;

                    }

                }

                break;

        }

        /*

         * Adjust the caret position based on the

         * character processing.

         */

        SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);

        return 0;

    case WM_PAINT:

        /* Draw all the characters in the buffer, line by line. */

        hdc = BeginPaint(hwnd, &ps);

        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));

        for (y = 0; y < nWindowCharsY; y++)

            TextOut(hdc, 0, y * nCharY, &TEXTMATRIX(0, y),

                nWindowCharsX);

        EndPaint(hwnd, &ps);

    case WM_SETFOCUS:

        /*

         * The window has the input focus. Load the

         * application-defined caret resource.

         */

        hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));

        /* Create the caret. */

        CreateCaret(hwnd, hCaret, 0, 0);

        /* Adjust the caret position. */

        SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);

        /* Display the caret. */

        ShowCaret(hwnd);

        break;

    case WM_KILLFOCUS:

        /*

         * The window is losing the input focus,

         * so destroy the caret.

         */

        DestroyCaret();

        break;

    default: /* passes it on if unprocessed */

        return DefWindowProc(hwnd, message, wParam, lParam);

}                       /* ends switch (message)      */

    return NULL;

}                       /* ends main window procedure */


  22.3  Functions

The following functions are used with carets.

CreateCaret
DestroyCaret
GetCaretBlinkTime
GetCaretPos
HideCaret
SetCaretBlinkTime
SetCaretPos
ShowCaret


23.1  About Icons
  Chapter 23    Icons

23.1  About Icons

An icon is a small bitmap that usually represents a minimized application, but can also illustrate a warning message or other window. If an icon represents a minimized application, the user can move the icon or size the window by using the mouse or other pointing device. Icons that do not represent minimized applications cannot be moved by the mouse. The icon functions in Microsoft® Windows (™)  enable applications to create, load, display, arrange, destroy, and retrieve information about icons.

Windows supports two kinds of icons: standard and custom. Standard icons are predefined icons that Windows displays in system message boxes. The Windows display driver files provide five standard icons, such as the stop sign, for use by the operating system or by any Windows-based application. »This illustration« shows the standard icons and their identifiers.

Custom icons are designed to represent a particular application and can be any design the developer defines. »This illustration« shows several custom icons.


  23.1.1  The Hot Spot

In the center of an icon, one pixel called the hot spot is the point the system tracks and recognizes as the position of the icon. Unlike the cursor's hot spot, which can be any pixel in the cursor bitmap, the icon hot spot is always in the center of the icon bitmap.


  23.1.2  Icon Creation

Standard icons are predefined by Windows, so it is not necessary to create them. To use a standard icon, an application can obtain its handle by using the LoadIcon function. An icon handle is a unique value of the HICON type that identifies a standard or custom icon.

To create a custom icon for an application, developers typically use a graphics application and include the icon as a resource in the application's resource-definition file. At run time, an application can call LoadIcon to retrieve the handle of the icon. An icon resource contains data for several different display devices. LoadIcon automatically selects the most appropriate data for the current display device.

An application can also create a custom icon at run time by using the CreateIcon function. This function creates an icon of the specified size, colors, and bit patterns.

Applications should implement custom icons as resources and should use LoadIcon, rather than create the icon at run time. Using icon resources avoids device dependence, simplifies localization, and enables applications to share icon shapes.


  23.1.2.1  Alternative Icon Creation

Two other functions can create icons at run time: CreateIconFromResource and CreateIconIndirect. These functions enable an application to browse through the system's resources and create icons and cursors based on resource data. CreateIconFromResource creates an icon based on binary resource data from other executable files or dynamic-link libraries. An application must precede this function with calls to the LookupIconIDFromDirectory function and several of the resource functions. LookupIconIDFromDirectory returns the identifier of the most appropriate icon data for the current display device. For more information about the resource functions, see Chapter 51, "Resources," in Microsoft Win32 Programmer's Reference, Volume 2.

CreateIconIndirect creates an icon based on the contents of an ICONINFO structure. The GetIconInfo function fills this structure with the hot spot coordinates and information about the bitmask bitmap and color bitmap for the icon.


  23.1.3  Icon Display

The Win32 application programming interface (API) provides several functions that display and manipulate icons. Once an application has loaded an icon, it can use DrawIcon to draw the icon at a specified location in a window's client area. ArrangeIconicWindows arranges all of the minimized child windows in a parent window. OpenIcon activates and restores a minimized window to its previous size and location. IsIconic tests to see whether a window is minimized.

DrawIcon requires that the icon be loaded; the other functions do not. ArrangeIconicWindows, OpenIcon, and IsIconic operate on minimized windows, which may or may not have an icon drawn on top.


  23.1.3.1  The Window Class Icon

While registering a window class, applications can assign a default icon, known as the class icon, to the class. After the application registers the window class, each window of that class will have that class icon when it is minimized. When the user minimizes a window, Windows uses the DrawIcon function to paint the class icon.

To override a class icon, an application can process the WM_PAINTICON message. Applications can also replace the class icon by using the SetClassLong function. This function changes the default window settings for all windows of a given class. For more information about window classes, see Chapter 3, »Window Classes«.


  23.1.4  Icon Destruction

When an application no longer needs an icon it created by using CreateIcon, it should destroy the icon. The DestroyIcon function destroys the icon handle and frees any memory used by the icon. Applications should use this function only for icons created with CreateIcon; it is not necessary to destroy other icons.


  23.1.5  Icon Duplication

The CopyIcon function copies an icon handle. This enables an application or dynamic-link library to get its own handle for an icon owned by another module. Then, if the other module is freed, the application that copied the icon will still be able to use the icon.

For information about adding, removing, or replacing icon resources in executable files, see Chapter 51, "Resources," in Microsoft Win32 Programmer's Reference, Volume 2.


  23.2  Using Icons

This section describes how to perform the following tasks:

•	Create an icon.

•	Display an icon.

•	Use an icon in a mousetrap.

•	Share an icon resource.


  23.2.1  Creating an Icon

To use an icon, your application must get the handle of the icon. The following example shows how to create two different icon handles: one for the standard exclamation icon and one for a custom icon included as a resource in the application's resource-definition file.

HICON hIcon1;   /* icon handle            */

HICON hIcon2;   /* icon handle            */

/* Create a standard question icon. */

hIcon1 = LoadIcon(NULL, IDI_QUESTION);

/* Create a custom icon based on a resource. */

hIcon2 = LoadIcon(hinst, MAKEINTRESOURCE(460));

/* Create a custom icon at run time. */

An application should implement custom icons as resources and should use LoadIcon, rather than create the icons at run time. This approach avoids device dependence, simplies localization, and enables applications to share icon bitmaps. However, the following code uses CreateIcon to create a custom icon at run time, based on bitmap bitmasks. It is included to illustrate how the system interprets icon bitmap bitmasks.

HICON hIcon3;               /* icon handle        */

/* Yang icon AND bitmask */

BYTE ANDmaskIcon[] = {0xFF, 0xFF, 0xFF, 0xFF,   /* line 1 */

                      0xFF, 0xFF, 0xC3, 0xFF,   /* line 2 */

                      0xFF, 0xFF, 0x00, 0xFF,   /* line 3 */

                      0xFF, 0xFE, 0x00, 0x7F,   /* line 4 */

                      0xFF, 0xFC, 0x00, 0x1F,   /* line 5 */

                      0xFF, 0xF8, 0x00, 0x0F,   /* line 6 */

                      0xFF, 0xF8, 0x00, 0x0F,   /* line 7 */

                      0xFF, 0xF0, 0x00, 0x07,   /* line 8 */

                      0xFF, 0xF0, 0x00, 0x03,   /* line 9 */

                      0xFF, 0xE0, 0x00, 0x03,   /* line 10 */

                      0xFF, 0xE0, 0x00, 0x01,   /* line 11 */

                      0xFF, 0xE0, 0x00, 0x01,   /* line 12 */

                      0xFF, 0xF0, 0x00, 0x01,   /* line 13 */

                      0xFF, 0xF0, 0x00, 0x00,   /* line 14 */

                      0xFF, 0xF8, 0x00, 0x00,   /* line 15 */

                      0xFF, 0xFC, 0x00, 0x00,   /* line 16 */

                      0xFF, 0xFF, 0x00, 0x00,   /* line 17 */

                      0xFF, 0xFF, 0x80, 0x00,   /* line 18 */

                      0xFF, 0xFF, 0xE0, 0x00,   /* line 19 */

                      0xFF, 0xFF, 0xE0, 0x01,   /* line 20 */

                      0xFF, 0xFF, 0xF0, 0x01,   /* line 21 */

                      0xFF, 0xFF, 0xF0, 0x01,   /* line 22 */

                      0xFF, 0xFF, 0xF0, 0x03,   /* line 23 */

                      0xFF, 0xFF, 0xE0, 0x03,   /* line 24 */

                      0xFF, 0xFF, 0xE0, 0x07,   /* line 25 */

                      0xFF, 0xFF, 0xC0, 0x0F,   /* line 26 */

                      0xFF, 0xFF, 0xC0, 0x0F,   /* line 27 */

                      0xFF, 0xFF, 0x80, 0x1F,   /* line 28 */

                      0xFF, 0xFF, 0x00, 0x7F,   /* line 29 */

                      0xFF, 0xFC, 0x00, 0xFF,   /* line 30 */

                      0xFF, 0xF8, 0x03, 0xFF,   /* line 31 */

                      0xFF, 0xFC, 0x3F, 0xFF};  /* line 32 */

/* Yang icon XOR bitmask */

BYTE XORmaskIcon[] = {0x00, 0x00, 0x00, 0x00,   /* line 1 */

                      0x00, 0x00, 0x00, 0x00,   /* line 2 */

                      0x00, 0x00, 0x00, 0x00,   /* line 3 */

                      0x00, 0x00, 0x00, 0x00,   /* line 4 */

                      0x00, 0x00, 0x00, 0x00,   /* line 5 */

                      0x00, 0x00, 0x00, 0x00,   /* line 6 */

                      0x00, 0x00, 0x00, 0x00,   /* line 7 */

                      0x00, 0x00, 0x38, 0x00,   /* line 8 */

                      0x00, 0x00, 0x7C, 0x00,   /* line 9 */

                      0x00, 0x00, 0x7C, 0x00,   /* line 10 */

                      0x00, 0x00, 0x7C, 0x00,   /* line 11 */

                      0x00, 0x00, 0x38, 0x00,   /* line 12 */

                      0x00, 0x00, 0x00, 0x00,   /* line 13 */

                      0x00, 0x00, 0x00, 0x00,   /* line 14 */

                      0x00, 0x00, 0x00, 0x00,   /* line 15 */

                      0x00, 0x00, 0x00, 0x00,   /* line 16 */

                      0x00, 0x00, 0x00, 0x00,   /* line 17 */

                      0x00, 0x00, 0x00, 0x00,   /* line 18 */

                      0x00, 0x00, 0x00, 0x00,   /* line 19 */

                      0x00, 0x00, 0x00, 0x00,   /* line 20 */

                      0x00, 0x00, 0x00, 0x00,   /* line 21 */

                      0x00, 0x00, 0x00, 0x00,   /* line 22 */

                      0x00, 0x00, 0x00, 0x00,   /* line 23 */

                      0x00, 0x00, 0x00, 0x00,   /* line 24 */

                      0x00, 0x00, 0x00, 0x00,   /* line 25 */

                      0x00, 0x00, 0x00, 0x00,   /* line 26 */

                      0x00, 0x00, 0x00, 0x00,   /* line 27 */

                      0x00, 0x00, 0x00, 0x00,   /* line 28 */

                      0x00, 0x00, 0x00, 0x00,   /* line 29 */

                      0x00, 0x00, 0x00, 0x00,   /* line 30 */

                      0x00, 0x00, 0x00, 0x00,   /* line 31 */

                      0x00, 0x00, 0x00, 0x00};  /* line 32 */

hIcon3 = CreateIcon(hinst,    /* application instance     */

             32,              /* icon width               */

             32,              /* icon height              */

             1,               /* number of XOR planes     */

             1,               /* number of bits per pixel */

             ANDmaskIcon,     /* AND bitmask              */

             XORmaskIcon);    /* XOR bitmask              */

To create the icon, CreateIcon applies the following truth table to the AND and XOR bitmasks.

AND bitmask	XOR bitmask	Display
0	0	Black
0	1	White
1	0	Screen
1	1	Reverse screen
For information about full-color bitmaps, see Chapter 29, »Bitmaps«, and Chapter 36, »Colors«.

Before closing, your application must use DestroyIcon to destroy any icon it created by using CreateIcon. It is not necessary to destroy icons created by other functions.


  23.2.2  Displaying an Icon

Your application can load and create icons to display in the application's client area or child windows. The following code demonstrates how to draw an icon in the client area of the window whose display context is identified by hdc.

HICON hIcon1;   /* icon handle               */

HDC hdc;        /* handle of display context */

DrawIcon(hdc, 10, 20, hIcon1);

Windows automatically displays the class icon — the icon associated with the window — when the window is minimized. Your application can assign a class icon while registering a window class. The following example assigns an icon handle to the hIcon member of the WNDCLASS structure identified by wc.

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(430));

When the window class is registered, the icon identified by 430 in the application's resource-definition file will be the default icon for all windows based on the class.

Your application can replace a class icon by using SetClassLong. This function changes the default window settings for all windows of a given class. The following example replaces the existing class icon with the icon whose resource identifier is 480.

HINSTANCE hinst;            /* handle of current instance */

HWND hwnd;                  /* main window handle         */

/* Change the icon for hwnd's window class. */

SetClassLong(hwnd,         /* window handle */

    GCL_HICON,             /* changes icon  */

    (LONG) LoadIcon(hinst, MAKEINTRESOURCE(480))); /* new */

For more information about window classes, see Chapter 3, »Window Classes«.


  23.2.2.1  Managing the Icon Background

If your application assigns a class icon, Windows automatically repaints the icon's background whenever it repaints the icon. Your application can prevent Windows from painting the background by processing the WM_ICONERASEBKGND message.

If your application sets the class icon to NULL, there is no icon associated with the window class. In this situation, Windows sends the WM_ERASEBKGND message to the window whenever it paints the icon. If the window does not process this message, Windows draws part of the window's client area onto the iconic window.


  23.2.3  Creating a Mousetrap

The following code sample uses IsIconic, LoadIcon, and several cursor and timer functions to create a simple mousetrap. The example uses the cursor and timer functions to monitor the location of the cursor at 10-second intervals. If the cursor location has not changed in the last 10 seconds and the application's main window is minimized, the application changes the cursor shape and moves the cursor to the icon.

HICON hIcon1;              /* icon handle                */

POINT ptOld;               /* previous cursor location   */

HCURSOR hCurs1;            /* cursor handle              */

HINSTANCE hinstance;       /* handle of current instance */

hCurs1 = LoadCursor(hinstance, MAKEINTRESOURCE(220));

.

. /* Fill in the window class structure. */

.

WNDCLASS  wc;

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(470));

wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(240));

.

. /*

. * Register the window class and perform

. * other application initialization.

. */

.

/* Set a timer for the mousetrap. */

GetCursorPos(&ptOld);

SetTimer(hwnd, IDT_CURSOR, 10000, (TIMERPROC) NULL);

LONG APIENTRY MainWndProc(

    HWND hwnd,          /* window handle            */

    UINT message,       /* type of message          */

    UINT wParam,        /* additional information   */

    LONG lParam)        /* additional information   */

{

    HDC hdc;            /* device context handle    */

    POINT pt;           /* current cursor location  */

    RECT rc;            /* iconized window location */

    switch (message) {

         .

         . /* Process other messages here. */

         .

        case WM_TIMER:

            /*

             * If the window is minimized, compare the current

             * cursor position with the one from 10 seconds

             * earlier. If the cursor position has not changed,

             * move the cursor to the icon.

             */

            if (IsIconic(hwnd)) {

                GetCursorPos(&pt);

                if ((pt.x == ptOld.x) && (pt.y == ptOld.y)) {

                    GetWindowRect(hwnd, &rc);

                    SetCursorPos(rc.left, rc.top);

                }

                else {

                    ptOld.x = pt.x;

                    ptOld.y = pt.y;

                }

            }

            return 0;

        case WM_SETCURSOR:

            /*

             * If the window is minimized, draw hCurs1.

             * If the window is not minimized, draw the default

             * cursor (class cursor).

             */

            if (IsIconic(hwnd)) {

                SetCursor(hCurs1);

                break;

            }

        case WM_DESTROY:

            /* Destroy the timer. */

            KillTimer(hwnd, IDT_CURSOR);

            PostQuitMessage(0);

            break;

                .

                . /* Process other messages here. */

                .

    }             /* ends switch (message) */

A code sample for a similar mousetrap is included in Chapter 21, »Cursors«. That example uses CreateIcon to create the class icon.


  23.2.4  Sharing Icon Resources

The following code uses CreateIconFromResource, LookupIconIdFromDirectory, DrawIcon, and several of the resource functions to create an icon handle based on icon data from another executable file. Then, it displays the icon in a window.

HICON hIcon1;       /* icon handle                */

HINSTANCE hExe;     /* handle to loaded .EXE file */

HRSRC hResource;    /* handle for FindResource    */

HRSRC hMem;         /* handle for LoadResource    */

BYTE *lpResource;   /* address of resource data   */

int nID;            /* ID of resource that best

                       fits current screen        */

HDC hdc;        /* handle of display context */

/* Load the file from which to copy the icon. */

hExe = LoadLibrary("myapp.exe");

/* Find the icon directory whose identifier is 440. */

hResource = FindResource(hExe,

    MAKEINTRESOURCE(440),

    RT_GROUP_ICON);

/* Load and lock the icon directory. */

hMem = LoadResource(hExe, hResource);

lpResource = LockResource(hMem);

/*

 * Get the identifier of the icon that is most appropriate

 * for the video display.

 */

nID = LookupIconIdFromDirectory(

    (PBYTE) lpResource, TRUE);

/* Find the bits for the nID icon. */

hResource = FindResource(hExe,

    MAKEINTRESOURCE(nID),

    MAKEINTRESOURCE(RT_ICON));

/* Load and lock the icon. */

hMem = LoadResource(hExe, hResource);

lpResource = LockResource(hMem);

/* Create a handle to the icon. */

hIcon1 = CreateIconFromResource(

    (PBYTE) lpResource,

    SizeofResource(hExe, hResource),

    TRUE,

    0x00030000);

/* Draw the icon in the client area. */

DrawIcon(hdc, 10, 20, hIcon1);


  23.3  Functions and Messages

Following are the functions and messages used with icons.


  Functions

ArrangeIconicWindows
CopyIcon
CreateIcon
CreateIconFromResource
CreateIconIndirect
DestroyIcon
DrawIcon
GetIconInfo
IsIconic
LoadIcon
LookupIconIdFromDirectory
OpenIcon


  Messages

WM_ICONERASEBKGND
WM_PAINTICON


24.1  About Window Properties
  Chapter 24    Window Properties

24.1  About Window Properties

A window property is any data assigned to a window by the SetProp function. A window property is usually a handle of the window-specific data, but it may be any 32-bit value. Each window property is identified by a string name.

Window properties are typically used to associate data with a subclassed window or a window in a multiple document interface (MDI) application. In either case, it is not convenient to use the extra bytes specified in the CreateWindow function or class structure for the following two reasons:

•	An application might not know how many extra bytes are available or how the space is being used. By using window properties, the application can associate data with a window without accessing the extra bytes.

•	An application must access the extra bytes by using offsets. Window properties, however, are accessed by their string identifiers, not by offsets.

For more information about subclassing, see Chapter 4, »Window Procedures«. For more information about MDI windows, see Chapter 27, »Multiple Document Interface«.

The Microsoft® Win32 (™)  application programming interface (API) provides several functions that enable applications to use window properties. The SetProp function assigns a window property and its string identifier to a window. The GetProp function retrieves the window property identified by a given string. The RemoveProp function destroys the association between a window and a window property but does not destroy the data itself. The EnumProps and EnumPropsEx functions enumerate all of a window's properties by using an application-defined callback function. EnumPropsEx includes an extra parameter for application-defined data used by the callback function.


  24.2  Using Window Properties

This section illustrates how to use Win32 functions to perform the following tasks:

•	Add a window property

•	Retrieve a window property

•	List the window properties of a given window

•	Delete a window property


  24.2.1  Adding a Window Property

The following example loads an icon and then a cursor and allocates memory for a buffer. The example then uses the SetProp function to assign the resulting icon, cursor, and memory handles as window properties for the window identified by the hwndSubclass value. The properties are identified by the strings PROP_ICON, PROP_CURSOR, and PROP_BUFFER.

#define BUFFER 4096

HINSTANCE hinst;       /* handle of current instance     */

HWND hwndSubclass;     /* handle of a subclassed window */

HANDLE hIcon, hCursor;

HGLOBAL hMem;

char *lpMem;

TCHAR tchPath[] = "c:\\winnt\\samples\\winprop.c";

/* Load resources. */

hIcon = LoadIcon(hinst, MAKEINTRESOURCE(400));

hCursor = LoadCursor(hinst, MAKEINTRESOURCE(220));

/* Allocate and fill a memory buffer. */

hMem = GlobalAlloc(GPTR, BUFFER);

lpMem = GlobalLock(hMem);

lstrcpy(lpMem, tchPath);

GlobalUnlock(hMem);

/* Set the window properties for hwndSubclass. */

SetProp(hwndSubclass, "PROP_ICON", hIcon);

SetProp(hwndSubclass, "PROP_CURSOR", hCursor);

SetProp(hwndSubclass, "PROP_BUFFER", hMem);


  24.2.2  Retrieving a Window Property

A window can create handles to its window property data and use the data for any purpose. The following example uses the GetProp function to obtain handles to the window properties identified by PROP_ICON, PROP_CURSOR, and PROP_BUFFER. The example then displays the contents of the newly obtained memory buffer, cursor, and icon in the window's client area.

#define PATHLENGTH 256

HWND hwndSubclass;     /* handle of a subclassed window */

HANDLE hIconProp, hCursProp;

HGLOBAL hMemProp;

char *lpFilename;

TCHAR tchBuffer[PATHLENGTH];

int nSize;

HDC hdc;

/* Get the window properties, then use the data. */

hIconProp = (HICON) GetProp(hwndSubclass, "PROP_ICON");

TextOut(hdc, 10, 40, "PROP_ICON", 9);

DrawIcon(hdc, 90, 40, hIconProp);

hCursProp = (HCURSOR) GetProp(hwndSubclass, "PROP_CURSOR");

TextOut(hdc, 10, 85, "PROP_CURSOR", 9);

DrawIcon(hdc, 110, 85, hCursProp);

hMemProp = (HGLOBAL) GetProp(hwndSubclass, "PROP_BUFFER");

lpFilename = GlobalLock(hMemProp);

nSize = sprintf(tchBuffer,

    "Path to file: %s", lpFilename);

TextOut(hdc, 10, 10, tchBuffer, nSize);


  24.2.3  Listing Window Properties for a Given Window

In the following example, the EnumPropsEx function lists the string identifiers of the window properties for the window identified by the hwndSubclass value. This function relies on the application-defined callback function WinPropProc to display the strings in the window's client area.

EnumPropsEx(hwndSubclass, WinPropProc, NULL);

/*

 * WinPropProc is an application-defined callback function that

 * lists a window property.

 */

BOOL CALLBACK WinPropProc(

    HWND hwndSubclass,         /* handle of window with property */

    LPCSTR lpszString,         /* property string or atom        */

    HANDLE hData)              /* data handle                    */

{

    static int nProp = 1;    /* property counter           */

    TCHAR tchBuffer[BUFFER]; /* buffer for expanded string */

    int nSize;               /* size of string in buffer   */

    HDC hdc;                 /* device-context handle      */

    hdc = GetDC(hwndSubclass);

    /* Display the window property string in the client area. */

    nSize = sprintf(tchBuffer, "WinProp %d: %s", nProp++,

        lpszString);

    TextOut(hdc, 10, nProp * 20, tchBuffer, nSize);

    ReleaseDC(hwndSubclass, hdc);

    return TRUE;

}


  24.2.4  Deleting a Window Property

When a window is destroyed, it must destroy any window properties it set. The following example uses the EnumPropsEx function and the application-defined callback function DelPropProc to destroy the properties associated with the hwndSubclass window. The callback function, which uses the RemoveProp function, is also shown.

case WM_DESTROY:

    EnumPropsEx(hwndSubclass, DelPropProc, NULL);

    PostQuitMessage(0);

    break;

    .

    .

    .

/*

 * DelPropProc is an application-defined callback function that

 * deletes a window property.

 */

BOOL CALLBACK DelPropProc(

    HWND hwndSubclass,         /* handle of window with property */

    LPCSTR lpszString,         /* property string or atom        */

    HANDLE hData)              /* data handle                    */

{

    RemoveProp(hwndSubclass, lpszString);

    return TRUE;

}


  24.3  Functions

Following are the functions used with window properties.

EnumPropProc
EnumProps
EnumPropsEx
GetProp
RemoveProp
SetProp


25.1  About the Clipboard
  Chapter 25    Clipboard

25.1  About the Clipboard

The clipboard is a set of functions and messages that enable applications designed for the Microsoft® Win32 (™)  application programming interface (API) to transfer data. Because all applications have access to the clipboard, data can be easily transferred between applications or within an application.

A memory object on the clipboard can be in any data format, called a clipboard format. Each format is identified by an unsigned integer value. For standard (predefined) clipboard formats, this value is a constant defined by the Win32 API; for registered clipboard formats, it is the return value of the RegisterClipboardFormat function.

Except for registering clipboard formats, individual windows carry out most clipboard operations. Typically, a window procedure transfers information to or from the clipboard in response to the WM_COMMAND message.

The clipboard is user-driven. A window should transfer data to or from the clipboard only in response to a command from the user. A window must not use the clipboard to transfer data without the user's knowledge.

This chapter does not describe how to copy and paste linked or embedded objects. For information on these subjects, see the object linking and embedding (OLE) documentation.


  25.1.1  Clipboard Formats

A window can place more than one memory object on the clipboard, each representing the same information in a different clipboard format. Users need not be aware of the clipboard formats used for an object on the clipboard.


  25.1.1.1  Registered Clipboard Formats

Many applications work with data that cannot be translated into a standard clipboard format without loss of information. Such applications can register new clipboard formats by using the RegisterClipboardFormat function. For example, if a word processing application copied formatted text to the clipboard using a standard text format, the formatting information would be lost. The solution would be to register a new clipboard format, such as rich-text format (RTF).

If more than one application registers a clipboard format with exactly the same name, the clipboard format is registered only once. Both calls to the RegisterClipboardFormat function return the same value. In this way, two different applications can share data by using a registered clipboard format.

For a list of standard clipboard formats, see the SetClipboardData function.


  25.1.1.2  Private and GDI Object Clipboard Formats

An application can identify a private clipboard format by defining a value in the range CF_PRIVATEFIRST through CF_PRIVATELAST. An application can use a private clipboard format for an application-defined data format that does not need to be registered with the system.

Data handles associated with private clipboard formats are not automatically freed by the system when a window empties the clipboard. Windows that use private clipboard formats should process the WM_DESTROYCLIPBOARD message to free clipboard data when the data is no longer needed.

Graphics Device Interface (GDI) object clipboard formats are similar to private clipboard formats. An application can identify a GDI object format by defining a value in the range CF_GDIOBJFIRST through CF_GDIOBJLAST. Like objects associated with standard clipboard formats for GDI objects, objects associated with GDI object formats are automatically deleted (by using the DeleteObject function) when the clipboard is emptied.

For more information about the WM_DESTROYCLIPBOARD message, see Section 25.1.2.3, »Clipboard Ownership«.


  25.1.1.3  Multiple Clipboard Formats

A window can place more than one clipboard object on the clipboard, each representing the same information in a different clipboard format. When placing information on the clipboard, the window should provide data in as many formats as possible.

Clipboard formats that contain the most information should be placed on the clipboard first, followed by less descriptive formats. A window pasting information from the clipboard typically retrieves a clipboard object in the first format it recognizes. Because clipboard formats are enumerated in the order they are placed on the clipboard, the first recognized format is also the most descriptive.

For example, suppose a user copies styled text from a word-processing document. The window containing the document might first place data on the clipboard in a registered format such as RTF. Afterwards, the window would place data on the clipboard in a less descriptive format such as text (CF_TEXT).

When the contents of the clipboard are pasted into another window, the window retrieves data in the most descriptive format it recognizes. If the window recognizes RTF, the corresponding data is pasted into the document. Otherwise, the text data is pasted into the document and the formatting information is lost.


  25.1.1.4  Synthesized Clipboard Formats

Adding some formats to the clipboard implicitly creates other formats. When an application places any of the three text formats on the clipboard, the other two text formats are added implicitly. Similarly, when the application places either of the two metafile formats on the clipboard, the other metafile format is added implicitly.

When one of the implicit formats is requested by an application, the system synthesizes it by converting from an available format. For example, if an application places data on the clipboard using the CF_TEXT format, the CF_OEMTEXT and CF_UNICODETEXT clipboard formats are added implicitly. If another application requests data in the CF_UNICODETEXT clipboard format, the system synthesizes the data by converting it from the CF_TEXT format.

Synthesized clipboard formats are not added until the clipboard is closed. This enables an application to place more than one text format or both metafile formats on the clipboard.


  25.1.2  Clipboard Operations

A window should use the clipboard when cutting, copying, or pasting data. A window places data on the clipboard for cut and copy operations and retrieves data from the clipboard for paste operations. The following sections describe these operations and related issues.

To place data on or retrieve data from the clipboard, a window must first open the clipboard by using the OpenClipboard function. Only one window can have the clipboard open at a time. When it has finished, the window must close the clipboard by calling the CloseClipboard function.


  25.1.2.1  Cut and Copy Operations

To place information on the clipboard, a window first clears any previous clipboard contents by using the EmptyClipboard function. This function sends the WM_DESTROYCLIPBOARD message to the previous clipboard owner, frees resources associated with data on the clipboard, and assigns clipboard ownership to the window that has the clipboard open.

After emptying the clipboard, a window places data on the clipboard in as many clipboard formats as possible. For each format, the window calls the SetClipboardData function, specifying the format identifier and a global memory handle. The memory handle can be NULL, indicating that the window renders the data on request. (For more information, see Section 25.1.2.4, »Delayed Rendering«.) A window should place data on the clipboard in order from the most descriptive clipboard format to the least descriptive.


  25.1.2.2  Paste Operations

To retrieve paste information from the clipboard, a window first determines the clipboard format to retrieve. Typically, a window enumerates the available clipboard formats by using the EnumClipboardFormats function and uses the first format it recognizes. This method selects the best available format according to the priority set when the data was placed on the clipboard.

Alternatively, a window can use the GetPriorityClipboardFormat function. This function identifies the best available clipboard format according to a specified priority. A window that recognizes only one clipboard format can simply determine whether that format is available by using the IsClipboardFormatAvailable function.

After determining the clipboard format to use, a window calls the GetClipboardData function. This function returns the handle of a global memory object containing data in the specified format. A window can briefly lock the memory object in order to examine or copy the data. However, a window should not free the object or leave it locked for a long period of time.


  25.1.2.3  Clipboard Ownership

The clipboard owner is the window associated with the information on the clipboard. A window becomes the clipboard owner when it places data on the clipboard — specifically, when it calls the EmptyClipboard function. The window remains the clipboard owner until it is closed or another window empties the clipboard.

When the clipboard is emptied, the clipboard owner receives a WM_DESTROYCLIPBOARD message. Following are some reasons why a window might process this message:

•	The window delayed rendering of one or more clipboard formats. In response to the WM_DESTROYCLIPBOARD message, the window might free resources it had allocated in order to render data on request. For more information, see Section 25.1.2.4, »Delayed Rendering«.

•	The window placed data on the clipboard in a private clipboard format. The data for private clipboard formats is not freed by the system when the clipboard is emptied. Therefore, the clipboard owner should free the data upon receiving the WM_DESTROYCLIPBOARD message. For more information, see Section 25.1.1.2, »Private and GDI Object Clipboard Formats«.

•	The window placed data on the clipboard using the CF_OWNERDISPLAY clipboard format. In response to the WM_DESTROYCLIPBOARD message, the window might free resources it had used to display information in the clipboard viewer window. For more information, see Section 25.1.3.3, »Owner-Display Format«.


  25.1.2.4  Delayed Rendering

When placing a clipboard format on the clipboard, a window can delay rendering the data in that format until the data is needed. To do so, an application can specify NULL for the hData parameter of the SetClipboardData function. This is useful if the application supports several clipboard formats, some or all of which are time-consuming to render. By passing a NULL handle, a window renders complex clipboard formats only when and if they are needed.

If a window delays rendering a clipboard format, it must be prepared to render the format on request for as long as it is the clipboard owner. The system sends the clipboard owner a WM_RENDERFORMAT message when a request is received for a specific format that has not been rendered. Upon receiving this message, the window should call the SetClipboardData function to place a global memory handle on the clipboard in the requested format.

If the clipboard owner is destroyed and has delayed rendering some or all clipboard formats, it receives the WM_RENDERALLFORMATS message. Upon receiving this message, the window should place valid memory handles on the clipboard for all clipboard formats that it provides. This ensures that these formats remain available after the clipboard owner is destroyed.

An application should not open the clipboard before calling SetClipboardData in response to the WM_RENDERFORMAT or WM_RENDERALLFORMATS message.

Any clipboard formats that are not rendered in response to the WM_RENDERALLFORMATS message cease to be available to other applications and are no longer enumerated by the clipboard functions.


  25.1.2.5  Memory and the Clipboard

A memory object that is to be placed on the clipboard should be allocated by using the GlobalAlloc function with the GMEM_DDESHARE and GMEM_MOVEABLE flags.

Once a memory object is placed on the clipboard, ownership of that memory handle is transferred to the system. In particular, an application should not free a memory object that has been placed on the clipboard. The exception to this rule is for private clipboard formats. A window is responsible for freeing a memory handle it has placed on the clipboard using a private clipboard format; however, it must not free the memory handle until after the clipboard has been emptied.


  25.1.3  Clipboard Viewers

A clipboard viewer is a window that displays the current contents of the clipboard. The clipboard viewer is a convenience for the user and does not affect the data-transaction functions of the clipboard.

Typically, a clipboard viewer window can display at least the three most common formats: CF_TEXT, CF_BITMAP, and CF_METAFILEPICT. If a window does not make data available in any of these three formats, it should provide data in a display format, or use the owner-display format.


  25.1.3.1  Clipboard Viewer Windows

A window adds itself to the clipboard viewer chain by calling the SetClipboardViewer function. The return value is the handle of the next window in the chain. Each clipboard viewer window must keep track of the next window in the clipboard viewer chain. When the contents of the clipboard change, the system sends a WM_DRAWCLIPBOARD message to the first window in the chain. After updating its display, each clipboard viewer window must pass this message on to the next window in the chain.

Before closing, a clipboard viewer window must remove itself from the clipboard viewer chain by calling the ChangeClipboardChain function. The system then sends a WM_CHANGECBCHAIN message to the first window in the chain.

For more information about processing the WM_DRAWCLIPBOARD and WM_CHANGECBCHAIN messages, see Section 25.2.2, »Creating a Clipboard Viewer Window«.


  25.1.3.2  Display Formats

A display format is a clipboard format used to display information in a clipboard viewer window. A clipboard owner that uses a private or registered clipboard format, and none of the most common standard formats, must provide data in a display format for viewing in a clipboard viewer window. The display formats are intended for viewing only and must not be pasted into a document.

The four display formats CF_DSPBITMAP, CF_DSPMETAFILEPICT, CF_DSPTEXT, and CF_DSPENHMETAFILE are rendered in the same way as the standard CF_BITMAP, CF_TEXT, CF_METAFILEPICT, and CF_ENHMETAFILE formats.


  25.1.3.3  Owner-Display Format

For a clipboard owner that does not use any of the common standard clipboard formats, an alternative to providing a display format is to use the owner-display (CF_OWNERDISPLAY) clipboard format.

By using the owner-display format, a clipboard owner can avoid the overhead of rendering data in an additional format by taking direct control over painting the clipboard viewer window. The clipboard viewer window sends messages to the clipboard owner whenever a portion of the window must be repainted or when the window is scrolled or resized.


  25.1.4  Clipboard Commands

A user typically carries out clipboard operations by choosing commands in an application's Edit menu. Following is a brief description of the standard clipboard commands.

Command	Description
Cut	Places a copy of the current selection on the clipboard and deletes the selection from the document. The previous contents of the clipboard are destroyed.
Copy	Places a copy of the current selection on the clipboard. The document remains unchanged. The previous contents of the clipboard are destroyed.
Paste	Replaces the current selection with the contents of the clipboard. The contents of the clipboard are not changed.
Delete	Deletes the current selection from the document. The contents of the clipboard are not changed. This command does not involve the clipboard, but it should appear with the clipboard commands on the Edit menu.


  25.2  Using the Clipboard

This section explains how to perform the following tasks:

•	Implement the Cut, Copy, and Paste commands.

•	Create a clipboard viewer window.


  25.2.1  Implementing the Cut, Copy, and Paste Commands

This section describes how standard Cut, Copy, and Paste commands are implemented in an application. The example in this section uses these methods to place data on the clipboard using a registered clipboard format, the CF_OWNERDISPLAY format, and the CF_TEXT format. The registered format is used to represent rectangular or elliptical text windows, called labels.


  25.2.1.1  Selecting Data

Before information can be copied to the clipboard, the user must select specific information to be copied or cut. An application should provide a means for the user to select information within a document, and some kind of visual feedback to indicate selected data.

»This illustration« shows selected data in the example application Label. In one window, an inverted rectangle indicates a selected range of text within a label; in the other window, sizing boxes indicate a label that is itself selected.


  25.2.1.2  Creating an Edit Menu

»This illustration« shows a typical Edit menu.

An application should load an accelerator table containing the standard keyboard accelerators for the Edit menu commands. The TranslateAccelerator function must be added to the applications message loop for the accelerators to take effect. For more information, see Chapter 17, »Keyboard Accelerators«.


  25.2.1.3  Processing the WM_INITMENUPOPUP Message

Not all clipboard commands are available to the user at any given time. An application should process the WM_INITMENUPOPUP message to enable the menu items for available commands and disable unavailable commands.

Following is the WM_INITMENUPOPUP case for the Label application.

case WM_INITMENUPOPUP:

    InitMenu((HMENU) wParam);

    break;

The InitMenu function is defined as follows.

void PASCAL InitMenu(HMENU hmenu)

{

    int  cMenuItems = GetMenuItemCount(hmenu);

    int  nPos;

    UINT id;

    UINT fuFlags;

    PLABELBOX pbox = (hwndSelected == NULL) ? NULL :

        (PLABELBOX) GetWindowLong(hwndSelected, 0);

    for (nPos = 0; nPos < cMenuItems; nPos++) {

        id = GetMenuItemID(hmenu, nPos);

        switch (id) {

            case IDM_CUT:

            case IDM_COPY:

            case IDM_DELETE:

                if (pbox == NULL || !pbox->fSelected)

                    fuFlags = MF_BYCOMMAND | MF_GRAYED;

                else if (pbox->fEdit)

                    fuFlags = (id != IDM_DELETE && pbox->ichSel

                            == pbox->ichCaret) ?

                        MF_BYCOMMAND | MF_GRAYED :

                        MF_BYCOMMAND | MF_ENABLED;

                else

                    fuFlags = MF_BYCOMMAND | MF_ENABLED;

                EnableMenuItem(hmenu, id, fuFlags);

                break;

            case IDM_PASTE:

                if (pbox != NULL && pbox->fEdit)

                    EnableMenuItem(hmenu, id,

                        IsClipboardFormatAvailable(CF_TEXT) ?

                            MF_BYCOMMAND | MF_ENABLED :

                            MF_BYCOMMAND | MF_GRAYED

                    );

                else

                    EnableMenuItem(hmenu, id,

                        IsClipboardFormatAvailable(

                                uLabelFormat) ?

                            MF_BYCOMMAND | MF_ENABLED :

                            MF_BYCOMMAND | MF_GRAYED

                    );

        }

    }

}


  25.2.1.4  Processing the WM_COMMAND Message

To process menu commands, add the WM_COMMAND case to your application's main window procedure. Following is the WM_COMMAND case for the Label application's window procedure.

case WM_COMMAND:

    switch (LOWORD(wParam)) {

        case IDM_CUT:

            if (EditCopy())

                EditDelete();

            break;

        case IDM_COPY:

            EditCopy();

            break;

        case IDM_PASTE:

            EditPaste();

            break;

        case IDM_DELETE:

            EditDelete();

            break;

        case IDM_EXIT:

            DestroyWindow(hwnd);

    }

    break;

To carry out the Copy and Cut commands, the window procedure calls the application-defined EditCopy function. For more information, see Section 25.2.1.5, »Copying Information to the Clipboard«. To carry out the Paste command, the window procedure calls the application-defined EditPaste function. For more information, see Section 25.2.1.6, »Pasting Information from the Clipboard«.


  25.2.1.5  Copying Information to the Clipboard

In the Label application, the application-defined EditCopy function copies the current selection to the clipboard. This function does the following:

1.	Opens the clipboard by calling the OpenClipboard function.

2.	Empties the clipboard by calling the EmptyClipboard function.

3.	Calls the SetClipboardData function once for each clipboard format the application provides.

4.	Closes the clipboard by calling the CloseClipboard function.

Depending on the current selection, the EditCopy function either copies a range of text or copies an application-defined structure representing an entire label. The structure, call LABELBOX, is defined as follows.

#define BOX_ELLIPSE  0

#define BOX_RECT     1

#define CCH_MAXLABEL 80

#define CX_MARGIN    12

typedef struct tagLABELBOX {  /* box */

    RECT rcText;    /* coordinates of rectangle containing text  */

    BOOL fSelected; /* TRUE if the label is selected             */

    BOOL fEdit;     /* TRUE if text is selected                  */

    int nType;      /* rectangular or elliptical                 */

    int ichCaret;   /* caret position                            */

    int ichSel;     /* with ichCaret, delimits selection         */

    int nXCaret;    /* window position corresponding to ichCaret */

    int nXSel;      /* window position corresponding to ichSel   */

    int cchLabel;   /* length of text in atchLabel               */

    TCHAR atchLabel[CCH_MAXLABEL];

} LABELBOX, *PLABELBOX;

Following is the EditCopy function.

BOOL PASCAL EditCopy(VOID)

{

    PLABELBOX pbox;

    LPTSTR  lptstrCopy;

    HGLOBAL hglbCopy;

    int ich1, ich2, cch;

    if (hwndSelected == NULL)

        return FALSE;

    /* Open the clipboard, and empty it. */

    if (!OpenClipboard(hwndMain))

        return FALSE;

    EmptyClipboard();

    /* Get a pointer to the structure for the selected label. */

    pbox = (PLABELBOX) GetWindowLong(hwndSelected, 0);

    /* If text is selected, copy it using the CF_TEXT format. */

    if (pbox->fEdit) {

        if (pbox->ichSel == pbox->ichCaret) {   /* zero-length */

            CloseClipboard();                   /* selection   */

            return FALSE;

        }

        if (pbox->ichSel < pbox->ichCaret) {

            ich1 = pbox->ichSel;

            ich2 = pbox->ichCaret;

        }

        else {

            ich1 = pbox->ichCaret;

            ich2 = pbox->ichSel;

        }

        cch = ich2 - ich1;

        /* Allocate a global memory object for the text. */

        hglbCopy = GlobalAlloc(GMEM_DDESHARE,

            (cch + 1) * sizeof(TCHAR));

        if (hglbCopy == NULL) {

            CloseClipboard();

            return FALSE;

        }

        /* Lock the handle and copy the text to the buffer. */

        lptstrCopy = GlobalLock(hglbCopy);

        memcpy(lptstrCopy, &pbox->atchLabel[ich1],

            cch * sizeof(TCHAR));

        lptstrCopy[cch] = (TCHAR) 0;    /* null character */

        GlobalUnlock(hglbCopy);

        /* Place the handle on the clipboard. */

        SetClipboardData(CF_TEXT, hglbCopy);

    }

    /* If no text is selected, the label as a whole is copied. */

    else {

        /*

         * Save a copy of the selected label as a local memory

         * object. This copy is used to render data on request.

         * It is freed in response to the WM_DESTROYCLIPBOARD

         * message.

         */

        pboxLocalClip = (PLABELBOX) LocalAlloc(

            LMEM_FIXED,

            sizeof(LABELBOX)

        );

        if (pboxLocalClip == NULL) {

            CloseClipboard();

            return FALSE;

        }

        memcpy(pboxLocalClip, pbox, sizeof(LABELBOX));

        pboxLocalClip->fSelected = FALSE;

        pboxLocalClip->fEdit = FALSE;

        /*

         * Place a registered clipboard format, the owner-display

         * format, and the CF_TEXT format on the clipboard using

         * delayed rendering.

         */

        SetClipboardData(uLabelFormat, NULL);

        SetClipboardData(CF_OWNERDISPLAY, NULL);

        SetClipboardData(CF_TEXT, NULL);

    }

    /* Close the clipboard. */

    CloseClipboard();

    return TRUE;

}


  25.2.1.6  Pasting Information from the Clipboard

In the Label application, the application-defined EditPaste function pastes the contents of the clipboard. This function does the following:

1.	Opens the clipboard by calling the OpenClipboard function.

2.	Determines which of the available clipboard formats to retrieve.

3.	Retrieves the handle of the data in the selected format by calling the GetClipboardData function.

4.	Inserts a copy of the data into the document.

The handle returned by GetClipboardData is still owned by the clipboard, so an application must not free it or leave it locked.

5.	Closes the clipboard by calling the CloseClipboard function.

If a label is selected and contains an insertion point, the EditPaste function inserts the text from the clipboard at the insertion point. If there is no selection or if a label is selected, the function creates a new label, using the application-defined LABELBOX structure on the clipboard. The LABELBOX structure is placed on the clipboard by using a registered clipboard format.

Following is the EditPaste function.

VOID PASCAL EditPaste(VOID)

{

    PLABELBOX pbox;

    HGLOBAL   hglb;

    LPTSTR    lptstr;

    PLABELBOX pboxCopy;

    int cx, cy;

    HWND hwnd;

    pbox = hwndSelected == NULL ? NULL :

        (PLABELBOX) GetWindowLong(hwndSelected, 0);

    /*

     * If the application is in edit mode,

     * get the clipboard text.

     */

    if (pbox != NULL && pbox->fEdit) {

        if (!IsClipboardFormatAvailable(CF_TEXT))

            return;

        if (!OpenClipboard(hwndMain))

            return;

        hglb = GetClipboardData(CF_TEXT);

        if (hglb != NULL) {

            lptstr = GlobalLock(hglb);

            if (lptstr != NULL) {

                /*

                 * Call the application-defined ReplaceSelection

                 * function to insert the text and repaint the

                 * window.

                 */

                ReplaceSelection(hwndSelected, pbox, lptstr);

                GlobalUnlock(hglb);

            }

        }

        CloseClipboard();

        return;

    }

    /*

     * If the application is not in edit mode,

     * create a label window.

     */

    if (!IsClipboardFormatAvailable(uLabelFormat))

        return;

    if (!OpenClipboard(hwndMain))

        return;

    hglb = GetClipboardData(uLabelFormat);

    if (hglb != NULL) {

        pboxCopy = GlobalLock(hglb);

        if (pboxCopy != NULL) {

            cx = pboxCopy->rcText.right + CX_MARGIN;

            cy = pboxCopy->rcText.top * 2 + cyText;

            hwnd = CreateWindowEx(

                WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT,

                atchClassChild, NULL, WS_CHILD, 0, 0, cx, cy,

                hwndMain, NULL, hinst, NULL

            );

            if (hwnd != NULL) {

                pbox = (PLABELBOX) GetWindowLong(hwnd, 0);

                memcpy(pbox, pboxCopy, sizeof(LABELBOX));

                ShowWindow(hwnd, SW_SHOWNORMAL);

                SetFocus(hwnd);

            }

            GlobalUnlock(hglb);

        }

    }

    CloseClipboard();

}


  25.2.1.7  Registering a Clipboard Format

To register a clipboard format, add a call to the RegisterClipboardFormat function to your application's instance initialization function, as follows.

/* Register a clipboard format. */

LoadString(hinstCurrent, IDS_FORMATNAME, atchTemp,

    sizeof(atchTemp));

uLabelFormat = RegisterClipboardFormat(atchTemp);

if (uLabelFormat == 0)

    return FALSE;


  25.2.1.8  Processing the WM_RENDERFORMAT and WM_RENDERALLFORMATS Messages

If a window passes a NULL handle to the SetClipboardData function, it must process the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages to render data on request.

The WM_RENDERFORMAT message is sent to the clipboard owner if it delayed rendering a specific format and an application requested data in that format. The WM_RENDERALLFORMATS message is sent to the clipboard owner before it is destroyed if it has delayed rendering one or more clipboard formats.

To render a clipboard format, the window procedure must place a data handle on the clipboard by using the SetClipboardData function. It must not open the clipboard before calling SetClipboardData.

The Label application processes the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages as follows.

case WM_RENDERFORMAT:

    RenderFormat((UINT) wParam);

    break;

case WM_RENDERALLFORMATS:

    RenderFormat(uLabelFormat);

    RenderFormat(CF_TEXT);

    break;

In both cases, the window procedure calls the application-defined RenderFormat function, defined as follows.

void PASCAL RenderFormat(UINT uFormat)

{

    HGLOBAL hglb;

    PLABELBOX pbox;

    LPTSTR  lptstr;

    int cch;

    if (pboxLocalClip == NULL)

        return;

    if (uFormat == CF_TEXT) {

        /* Allocate a buffer for the text. */

        cch = pboxLocalClip->cchLabel;

        hglb = GlobalAlloc(GMEM_DDESHARE,

            (cch + 1) * sizeof(TCHAR));

        if (hglb == NULL)

            return;

        /* Copy the text from pboxLocalClip. */

        lptstr = GlobalLock(hglb);

        memcpy(lptstr, pboxLocalClip->atchLabel,

            cch * sizeof(TCHAR));

        lptstr[cch] = (TCHAR) 0;

        GlobalUnlock(hglb);

        /* Place the handle on the clipboard. */

        SetClipboardData(CF_TEXT, hglb);

    }

    else if (uFormat == uLabelFormat) {

        hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(LABELBOX));

        if (hglb == NULL)

            return;

        pbox = GlobalLock(hglb);

        memcpy(pbox, pboxLocalClip, sizeof(LABELBOX));

        GlobalUnlock(hglb);

        SetClipboardData(uLabelFormat, hglb);

    }

}


  25.2.1.9  Processing the WM_DESTROYCLIPBOARD Message

A window can process the WM_DESTROYCLIPBOARD message in order to free any resources it set aside to support delayed rendering. For example, the Label application, when copying a label to the clipboard, allocates a local memory object. It then frees this object in response to the WM_DESTROYCLIPBOARD message, as follows.

case WM_DESTROYCLIPBOARD:

    if (pboxLocalClip != NULL) {

        LocalFree(pboxLocalClip);

        pboxLocalClip = NULL;

    }

    break;


  25.2.1.10  Using the Owner-Display Clipboard Format

If a window places information on the clipboard by using the CF_OWNERDISPLAY clipboard format, it must do the following:

•	Process the WM_PAINTCLIPBOARD message. This message is sent to the clipboard owner when a portion of the clipboard viewer window must be repainted.

•	Process the WM_SIZECLIPBOARD message. This message is sent to the clipboard owner when the clipboard viewer has been resized or its contents have changed.

Typically, a window responds to this message by setting the scroll positions and ranges for the clipboard viewer window. In response to this message, the Label application also updates a SIZE structure for the clipboard viewer window.

•	Process the WM_HSCROLLCLIPBOARD and WM_VSCROLLCLIPBOARD messages. These messages are sent to the clipboard owner when a scroll bar event occurs in the clipboard-viewer window.

•	Process the WM_ASKCBFORMATNAME message. The clipboard viewer sends this message to an application to retrieve the name of the owner-display format.

The window procedure for the Label application processes these messages, as follows.

LRESULT CALLBACK MainWindowProc(hwnd, msg, wParam, lParam)

HWND hwnd;

UINT msg;

WPARAM wParam;

LPARAM lParam;

{

    static RECT rcViewer;

    RECT rc;

    LPRECT lprc;

    LPPAINTSTRUCT lpps;

    .

    .

    .

    switch (msg) {

        .

        .

        .

        case WM_PAINTCLIPBOARD:

            /* Determine the dimensions of the label. */

            SetRect(&rc, 0, 0,

                pboxLocalClip->rcText.right + CX_MARGIN,

                pboxLocalClip->rcText.top * 2 + cyText

            );

            /* Center the image in the viewer window. */

            if (rc.right < rcViewer.right) {

                rc.left = (rcViewer.right - rc.right) / 2;

                rc.right += rc.left;

            }

            if (rc.bottom < rcViewer.bottom) {

                rc.top = (rcViewer.bottom - rc.bottom) / 2;

                rc.bottom += rc.top;

            }

            /*

             * Paint the image, using the specified PAINTSTRUCT

             * structure, by calling the application-defined

             * PaintLabel function.

             */

            lpps = (LPPAINTSTRUCT) GlobalLock((HGLOBAL) lParam);

            PaintLabel(lpps, pboxLocalClip, &rc);

            GlobalUnlock((HGLOBAL) lParam);

            break;

        case WM_SIZECLIPBOARD:

            /*

             * Save the dimensions of the window in a static

             * RECT structure.

             */

            lprc = (LPRECT) GlobalLock((HGLOBAL) lParam);

            memcpy(&rcViewer, lprc, sizeof(RECT));

            GlobalUnlock((HGLOBAL) lParam);

            /*

             * Set the scroll ranges to zero (thus eliminating

             * the need to process the WM_HSCROLLCLIPBOARD and

             * WM_VSCROLLCLIPBOARD messages).

             */

            SetScrollRange((HWND) wParam, SB_HORZ, 0, 0, TRUE);

            SetScrollRange((HWND) wParam, SB_VERT, 0, 0, TRUE);

            break;

        case WM_ASKCBFORMATNAME:

            LoadString(hinst, IDS_OWNERDISPLAY,

                (LPSTR) lParam, wParam);

            break;

            .

            .

            .

        default:

            return DefWindowProc(hwnd, msg, wParam, lParam);

    }

    return 0;

}


  25.2.2  Creating a Clipboard Viewer Window

A clipboard viewer window displays the current contents of the clipboard, and receives messages when the clipboard contents change. To create a clipboard viewer window, your application must do the following:

•	Add the window to the clipboard viewer chain.

•	Process the WM_CHANGECBCHAIN message.

•	Process the WM_DRAWCLIPBOARD message.

•	Remove the window from the clipboard viewer chain before it is destroyed.


  25.2.2.1  Adding a Window to the Clipboard Viewer Chain

A window adds itself to the clipboard viewer chain by calling the SetClipboardViewer function. The return value is the handle of the next window in the chain. A window must keep track of this value — for example, by saving it in a static variable named hwndNextViewer.

The following example adds a window to the clipboard viewer chain in response to the WM_CREATE message.

case WM_CREATE:

    /* Add the window to the clipboard viewer chain. */

    hwndNextViewer = SetClipboardViewer(hwnd);

    break;


  25.2.2.2  Processing the WM_CHANGECBCHAIN Message

A clipboard viewer window receives the WM_CHANGECBCHAIN message when another window is removing itself from the clipboard viewer chain. If the window being removed is the next window in the chain, the window receiving the message must unlink the next window from the chain. Otherwise, this message should be passed to the next window in the chain.

The following example shows the processing of the WM_CHANGECBCHAIN message.

case WM_CHANGECBCHAIN:

    /* If the next window is closing, repair the chain. */

    if ((HWND) wParam == hwndNextViewer)

        hwndNextViewer = (HWND) lParam;

    /* Otherwise, pass the message to the next link. */

    else if (hwndNextViewer != NULL)

        SendMessage(hwndNextViewer, uMsg, wParam, lParam);

    break;


  25.2.2.3  Removing a Window from the Clipboard Viewer Chain

To remove itself from the clipboard viewer chain, a window calls the ChangeClipboardChain function. The following example removes a window from the clipboard viewer chain in response to the WM_DESTROY message.

case WM_DESTROY:

    ChangeClipboardChain(hwnd, hwndNextViewer);

    PostQuitMessage(0);

    break;


  25.2.2.4  Processing the WM_DRAWCLIPBOARD Message

The WM_DRAWCLIPBOARD message notifies a clipboard viewer window that the contents of the clipboard have changed. A window should do the following when processing the WM_DRAWCLIPBOARD message:

1.	Determine which of the available clipboard formats to display.

2.	Retrieve the clipboard data and display it in the window. Or, if the clipboard format is CF_OWNERDISPLAY, send a WM_PAINTCLIPBOARD message to the clipboard owner.

3.	Send the message to the next window in the clipboard viewer chain.

For an example of processing the WM_DRAWCLIPBOARD message, see the listing in Section 25.2.2.5, »Example of a Clipboard Viewer«.


  25.2.2.5  Example of a Clipboard Viewer

The following example shows a simple clipboard viewer application.

HINSTANCE hinst;

UINT uFormat = (UINT)(-1);

BOOL fAuto = TRUE;

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

    static HWND hwndNextViewer;

    HDC hdc;

    HDC hdcMem;

    PAINTSTRUCT ps;

    LPPAINTSTRUCT lpps;

    RECT rc;

    LPRECT lprc;

    HGLOBAL hglb;

    LPSTR lpstr;

    HBITMAP hbm;

    HENHMETAFILE hemf;

    HWND hwndOwner;

    switch (uMsg) {

        case WM_PAINT:

            hdc = BeginPaint(hwnd, &ps);

            /* Branch depending on the clipboard format. */

            switch (uFormat) {

                case CF_OWNERDISPLAY:

                    hwndOwner = GetClipboardOwner();

                    hglb = GlobalAlloc(GMEM_DDESHARE,

                        sizeof(PAINTSTRUCT));

                    lpps = GlobalLock(hglb);

                    memcpy(lpps, &ps, sizeof(PAINTSTRUCT));

                    GlobalUnlock(hglb);

                    SendMessage(hwndOwner, WM_PAINTCLIPBOARD,

                        (WPARAM) hwnd, (LPARAM) hglb);

                    GlobalFree(hglb);

                    break;

                case CF_BITMAP:

                    hdcMem = CreateCompatibleDC(hdc);

                    if (hdcMem != NULL) {

                        if (OpenClipboard(hwnd)) {

                            hbm = (HBITMAP)

                                GetClipboardData(uFormat);

                            SelectObject(hdcMem, hbm);

                            GetClientRect(hwnd, &rc);

                            BitBlt(hdc, 0, 0, rc.right, rc.bottom,

                                hdcMem, 0, 0, SRCCOPY);

                            CloseClipboard();

                        }

                        DeleteDC(hdcMem);

                    }

                    break;

                case CF_TEXT:

                    if (OpenClipboard(hwnd)) {

                        hglb = GetClipboardData(uFormat);

                        lpstr = GlobalLock(hglb);

                        GetClientRect(hwnd, &rc);

                        DrawText(hdc, lpstr, -1, &rc, DT_LEFT);

                        GlobalUnlock(hglb);

                        CloseClipboard();

                    }

                    break;

                case CF_ENHMETAFILE:

                    if (OpenClipboard(hwnd)) {

                        hemf = GetClipboardData(uFormat);

                        GetClientRect(hwnd, &rc);

                        PlayEnhMetaFile(hdc, hemf, &rc);

                        CloseClipboard();

                    }

                    break;

                case 0:

                    GetClientRect(hwnd, &rc);

                    DrawText(hdc, "The clipboard is empty.", -1,

                        &rc, DT_CENTER | DT_SINGLELINE |

                        DT_VCENTER);

                    break;

                default:

                    GetClientRect(hwnd, &rc);

                    DrawText(hdc, "Unable to display format.", -1,

                        &rc, DT_CENTER | DT_SINGLELINE |

                        DT_VCENTER);

            }

            EndPaint(hwnd, &ps);

            break;

        case WM_SIZE:

            if (uFormat == CF_OWNERDISPLAY) {

                hwndOwner = GetClipboardOwner();

                hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(RECT));

                lprc = GlobalLock(hglb);

                GetClientRect(hwnd, lprc);

                GlobalUnlock(hglb);

                SendMessage(hwndOwner, WM_SIZECLIPBOARD,

                    (WPARAM) hwnd, (LPARAM) hglb);

                GlobalFree(hglb);

            }

            break;

        case WM_CREATE:

            /* Add the window to the clipboard viewer chain. */

            hwndNextViewer = SetClipboardViewer(hwnd);

            break;

        case WM_CHANGECBCHAIN:

            /* If the next window is closing, repair the chain. */

            if ((HWND) wParam == hwndNextViewer)

                hwndNextViewer = (HWND) lParam;

            /* Otherwise, pass the message to the next link. */

            else if (hwndNextViewer != NULL)

                SendMessage(hwndNextViewer, uMsg, wParam, lParam);

            break;

        case WM_DESTROY:

            ChangeClipboardChain(hwnd, hwndNextViewer);

            PostQuitMessage(0);

            break;

        case WM_DRAWCLIPBOARD: /* clipboard contents changed. */

            /* Update the window by using Auto clipboard format. */

            SetAutoView(hwnd);

            /* Pass the message to the next window in viewer chain. */

            SendMessage(hwndNextViewer, uMsg, wParam, lParam);

            break;

        case WM_INITMENUPOPUP:

            if (!HIWORD(lParam))

                InitMenu(hwnd, (HMENU) wParam);

            break;

        case WM_COMMAND:

            switch (LOWORD(wParam)) {

                case IDM_EXIT:

                    DestroyWindow(hwnd);

                    break;

                case IDM_AUTO:

                    SetAutoView(hwnd);

                    break;

                default:

                    fAuto = FALSE;

                    uFormat = LOWORD(wParam);

                    InvalidateRect(hwnd, NULL, TRUE);

            }

            break;

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return (LRESULT) NULL;

}

void PASCAL SetAutoView(HWND hwnd)

{

    static UINT auPriorityList[] = {

        CF_OWNERDISPLAY,

        CF_TEXT,

        CF_ENHMETAFILE,

        CF_BITMAP

    };

    uFormat = GetPriorityClipboardFormat(auPriorityList, 4);

    fAuto = TRUE;

    InvalidateRect(hwnd, NULL, TRUE);

    UpdateWindow(hwnd);

}

void PASCAL InitMenu(HWND hwnd, HMENU hmenu)

{

    UINT uFormat;

    char szFormatName[80];

    LPCSTR lpFormatName;

    UINT fuFlags;

    UINT idMenuItem;

    /*

     * If a menu is not the display menu, no initialization is necessary. */

     */

    if (GetMenuItemID(hmenu, 0) != IDM_AUTO)

        return;

    /* Delete all menu items except the first. */

    while (GetMenuItemCount(hmenu) > 1)

        DeleteMenu(hmenu, 1, MF_BYPOSITION);

    /* Check or uncheck the Auto menu item. */

    fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED :

        MF_BYCOMMAND | MF_UNCHECKED;

    CheckMenuItem(hmenu, IDM_AUTO, fuFlags);

    /* If there are no clipboard formats, return. */

    if (CountClipboardFormats() == 0)

        return;

    /* Open the clipboard. */

    if (!OpenClipboard(hwnd))

        return;

    /* Add a separator and then a menu item for each format. */

    AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);

    uFormat = EnumClipboardFormats(0);

    while (uFormat) {

        /*

         * Call an application-defined function to get the name

         * of the clipboard format.

         */

        lpFormatName = GetPredefinedClipboardFormatName(uFormat);

        /* For registered formats, get the registered name. */

        if (lpFormatName == NULL) {

            if (GetClipboardFormatName(uFormat, szFormatName,

                    sizeof(szFormatName)))

                lpFormatName = szFormatName;

            else

                lpFormatName = "(unknown)";

        }

        /*

         * Add a menu item for the format. For displayable

         * formats, use the format ID for the menu ID.

         */

        if (IsDisplayableFormat(uFormat)) {

            fuFlags = MF_STRING;

            idMenuItem = uFormat;

        }

        else {

            fuFlags = MF_STRING | MF_GRAYED;

            idMenuItem = 0;

        }

        AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName);

        uFormat = EnumClipboardFormats(uFormat);

    }

    CloseClipboard();

}

BOOL PASCAL IsDisplayableFormat(UINT uFormat)

{

    switch (uFormat) {

        case CF_OWNERDISPLAY:

        case CF_TEXT:

        case CF_ENHMETAFILE:

        case CF_BITMAP:

            return TRUE;

    }

    return FALSE;

}


  25.3  Functions and Messages

Following are the functions and messages used with the clipboard.


  Functions

ChangeClipboardChain
CloseClipboard
CountClipboardFormats
EmptyClipboard
EnumClipboardFormats
GetClipboardData
GetClipboardFormatName
GetClipboardOwner
GetClipboardViewer
GetOpenClipboardWindow
GetPriorityClipboardFormat
IsClipboardFormatAvailable
OpenClipboard
RegisterClipboardFormat
SetClipboardData
SetClipboardViewer


  Messages

WM_ASKCBFORMATNAME
WM_CHANGECBCHAIN
WM_COPY
WM_CUT
WM_DESTROYCLIPBOARD
WM_DRAWCLIPBOARD
WM_HSCROLLCLIPBOARD
WM_PAINTCLIPBOARD
WM_PASTE
WM_RENDERALLFORMATS
WM_RENDERFORMAT
WM_SIZECLIPBOARD
WM_VSCROLLCLIPBOARD


26.1  About Dynamic Data Exchange
  Chapter 26    Dynamic Data Exchange

26.1  About Dynamic Data Exchange

The Microsoft® Windows (™)  operating system provides several methods for transferring data between applications. One way to transfer data is to use the Windows dynamic data exchange (DDE) protocol. The DDE protocol is a set of messages and guidelines. It sends messages between applications that share data and uses shared memory to exchange data between applications. Applications can use the DDE protocol for one-time data transfers and for continuous exchanges in which applications send updates to one another as new data becomes available.

Windows also includes the Dynamic Data Exchange Management Library (DDEML). The DDEML is a dynamic-link library (DLL) that applications running with Windows can use to share data. The DDEML provides an application programming interface (API) that simplifies the task of adding DDE capability to a Windows-based application. Instead of sending, posting, and processing DDE messages directly, an application uses the DDEML functions to manage DDE conversations. (A DDE conversation is the interaction between client and server applications.)

The DDEML also provides a facility for managing the strings and data that DDE applications share. Instead of using atoms and pointers to shared memory objects, DDE applications create and exchange string handles, which identify strings, and data handles, which identify memory objects. The DDEML also makes it possible for a server application to register the service names it supports. The names are broadcast to other applications in the system, which can then use the names to connect to the server. Moreover, the DDEML ensures compatibility among DDE applications by forcing them to implement the DDE protocol in a consistent manner.

Existing applications that use the message-based DDE protocol are fully compatible with those that use the DDEML. That is, an application that uses message-based DDE can establish conversations and perform transactions with applications that use the DDEML. Because of the many advantages of the DDEML, new applications should use it rather than the DDE messages. To use the API elements of the DDE management library, you must include the DDEML.H header file in your source files, link with DDEML.LIB, and ensure that DDEML.DLL is in the system's path.

This chapter provides guidelines for implementing dynamic data exchange for applications that cannot use the DDEML. For more information about the DDEML, see Chapter 77, "Dynamic Data Exchange Management Library," in Microsoft Win32 Programmer's Reference, Volume 2.


  26.1.1  Dynamic Data Exchange Protocol

Because Windows has a message-based architecture, passing messages is the most appropriate method for automatically transferring information between applications. However, Windows messages contain only two parameters (wParam and lParam) for passing data. As a result, these parameters must refer indirectly to other pieces of data when more than a few words of information pass between applications. The DDE protocol defines exactly how applications should use the wParam and lParam parameters to pass larger pieces of data by means of global atoms and shared memory handles. The DDE protocol has specific rules for allocating and deleting global atoms and shared memory objects.

A global atom is a reference to a character string. In the DDE protocol, atoms identify the applications exchanging data, the nature of the data being exchanged, and the data items themselves. For more information about atoms, see Chapter 61 in Microsoft Win32 Programmer's Reference, Volume 2. A shared memory handle is a handle to a memory object allocated by GlobalAlloc, using the GMEM_DDESHARE flag. In the DDE protocol, shared memory objects store data items passed between applications, protocol options, and remote command execution strings.


  26.1.2  Uses for Windows Dynamic Data Exchange

DDE is most appropriate for data exchanges that do not require ongoing user interaction. Usually, an application provides a method for the user to establish the link between the applications exchanging data. Once that link is established, however, the applications exchange data without further user involvement.

DDE can be used to implement a broad range of application features — for example:

•	Linking to real-time data, such as to stock market updates, scientific instruments, or process control.

•	Creating compound documents, such as a word processing document that includes a chart produced by a graphics application. Using DDE, the chart will change when the source data is changed, while the rest of the document remains the same.

•	Performing data queries between applications, such as a spreadsheet querying a database application for accounts past due.


26.1.3  Dynamic Data Exchange from the Users Point of View
  26.1.3  Dynamic Data Exchange from the User's Point of View

The following example illustrates illustrates how two DDE applications can cooperate, as seen from the user's point of view.

A spreadsheet user wants to use Microsoft® Excel to track the price of a particular stock on the New York Stock Exchange. The user has a Windows-based application called Quote that in turn has access to NYSE data. The DDE conversation between Microsoft Excel and Quote takes place as follows:

•	The user initiates the conversation by supplying the name of the application (Quote) that will supply the data and the particular topic of interest (NYSE). The resulting DDE conversation is used to request quotes on specific stocks.

•	Microsoft Excel broadcasts the application and topic names to all DDE applications currently running in the system. Quote responds, establishing a conversation with Microsoft Excel about the NYSE topic.

•	The user can then create a spreadsheet formula in a cell that requests that the spreadsheet be automatically updated whenever a particular stock quotation changes. For example, the user could request an automatic update whenever a change occurs in the selling price of ZAXX stock by specifying the following Microsoft Excel formula:

='Quote'|'NYSE'!ZAXX

•	The user can terminate the automatic updating of the ZAXX stock quotation at any time. Other data links that were established separately (such as for quotations for other stocks) still will remain active under the same NYSE conversation.

•	The user can also terminate the entire conversation between Microsoft Excel and Quote on the NYSE topic, so that no specific data links on that topic can be established without initiating a new conversation.


  26.1.4  Dynamic Data Exchange Concepts

The following sections explain the important concepts and terminology that are key to understanding dynamic data exchange.


  26.1.4.1  Client, Server, and Conversation

Two applications participating in dynamic data exchange are said to be engaged in a DDE conversation. The application that initiates the conversation is the client application; the application that responds to the client is the server application. An application can engage in several conversations at the same time, acting as the client in some and as the server in others.

A DDE conversation takes place between two windows, one for each of the participating applications. A window may be the main window of the application; a window associated with a specific document, as in a multiple document interface (MDI) application; or a hidden (invisible) window whose only purpose is to process DDE messages.

Since a DDE conversation is identified by the pair of handles of the windows engaged in the conversation, no window should be engaged in more than one conversation with another window. Either the client application or the server application must provide a different window for each of its conversations with a particular server or client application.

An application can ensure a pair of client and server windows is never involved in more than one conversation by creating a hidden window for each conversation. The sole purpose of this window is to process DDE messages.


  26.1.4.2  Application, Topic, and Item Names

The DDE protocol identifies the units of data passed between the client and server with a three-level hierarchy of application, topic, and item names.

Each DDE conversation is uniquely defined by the application name and topic. At the beginning of a DDE conversation, the client and server determine the application name and topic. The application name is usually the name of the server application. For example, when Microsoft Excel acts as the server in a conversation, the application name is Excel.

The DDE topic is a general classification of data within which multiple data items may be "discussed" (exchanged) during the conversation. For applications that operate on file-based documents, the topic is usually a filename. For other applications, the topic is an application-specific name.

Because the client and server window handles together identify a DDE conversation, the application name and topic that define a conversation cannot be changed during the course of the conversation.

A DDE data item is information related to the conversation topic exchanged between the applications. Values for the data item can be passed from the server to the client, or from the client to the server. Data can be passed with any of the standard clipboard formats or with a registered clipboard format. A special, registered format named Link identifies an item in a DDE conversation. For more information about clipboard formats, see Chapter 25, »Clipboard«.


  26.1.4.3  The System Topic

Applications should support the System topic at all times. This topic provides a context for information that may be of general interest to another application.

Data-item values must be rendered in the CF_TEXT clipboard format. Individual elements of item values for a System topic must be delimited by tab characters. The following table suggests some items for the System topic.

Item	Description
Formats	Tab-delimited list of clipboard formats the application can render. Typically, the CF_ formats are listed with the "CF_" portion of the names removed (for example, CF_TEXT is listed as "TEXT").
Help	Text that briefly explains how to use the DDE server.
ReturnMessage	Supporting detail for the most recently used WM_DDE_ACK message. This item is useful when more than eight bits of application-specific return data are required.
Status	Indication of the current status of the application. When a server receives a WM_DDE_REQUEST message for this System-topic item, it should respond by posting a WM_DDE_DATA message with a string containing either Busy or Ready, as appropriate.
SysItems	List of System-topic items the application supports.
TopicItemList	Similar to the SysItems item, except that TopicItemList should be supported for each topic other than the System topic. This allows browsing of the items supported under any topic. If the items cannot be enumerated, this item should contain only "TopicItemList".
Topics	List of topics the application supports at the current time; this list can vary from moment to moment.


  26.1.4.4  Permanent Data Links

Once a DDE conversation has begun, the client can establish one or more permanent data links with the server. A data link is a communications mechanism by which the server notifies the client whenever the value of a given data item changes. The data link is permanent in the sense that this notification process continues until the data link or the DDE conversation itself is terminated.

There are two kinds of permanent DDE data links: warm and hot. In a warm data link, the server notifies the client that the value of the data item has changed, but the server does not send the data value to the client until the client requests it. In a hot data link, the server immediately sends the changed data value to the client.

Applications that support warm or hot data links typically provide a Copy or Paste Link command in their Edit menu to enable the user to establish links between applications. For more information, see Section 26.2.3.2, »Initiating a Data Link with the Paste Link Command«.


  26.1.4.5  Atoms and Shared Memory Objects

Certain arguments of DDE messages are global atoms or shared memory objects. Applications using these arguments must follow explicit rules about when to allocate and delete them. In all cases, the message sender must delete any atom or shared memory object that the intended receiver will not receive because of an error condition, such as failure of the PostMessage function.

DDE uses shared memory objects for three purposes:

•	To carry a data-item value to be exchanged. This is an item referenced by the hData parameter in the WM_DDE_DATA and WM_DDE_POKE messages.

•	To carry options in a message. This is an item referenced by the hOptions parameter in a WM_DDE_ADVISE message.

•	To carry a command execution string. This is an item referenced by the hCommands parameter in the WM_DDE_EXECUTE message and its corresponding WM_DDE_ACK message.

An application that receives a DDE shared memory object must treat it as read only. The application must not use the object as a mutual read-write area for the free exchange of data.

As it does with a DDE atom, an application should free a shared memory object to manage memory effectively. The application should also lock and unlock memory objects.


  26.1.5  Dynamic Data Exchange Messages

Because DDE is a message-based protocol, it employs no special Windows functions or libraries. All DDE transactions are conducted by passing certain defined DDE messages between the client and server windows.

There are nine DDE messages; the symbolic constants for these messages are defined in the Microsoft® Win32 (™)  Software Development Kit (SDK) header file DDE.H. Certain structures for the various DDE messages are also defined in DDE.H.

The following table summarizes the nine DDE messages.

Message	Description
WM_DDE_ACK	Acknowledges receiving or not receiving a message.
WM_DDE_ADVISE	Requests the server application to supply an update or notification for a data item whenever it changes. This establishes a permanent data link.
WM_DDE_DATA	Sends a data-item value to the client application.
WM_DDE_EXECUTE	Sends a string to the server application, which is expected to process the string as a series of commands.
WM_DDE_INITIATE	Initiates a conversation between the client and server applications.
WM_DDE_POKE	Sends a data-item value to the server application.
WM_DDE_REQUEST	Requests the server application to provide the value of a data item.
WM_DDE_TERMINATE	Terminates a conversation.
WM_DDE_UNADVISE	Terminates a permanent data link.
An application calls the SendMessage function to issue the WM_DDE_INITIATE message or a WM_DDE_ACK message sent in response to WM_DDE_INITIATE. All other messages are sent by the PostMessage function. The first parameter of these calls is the handle of the receiving window. The second parameter contains the message to be sent; the third parameter identifies the sending window; and the fourth parameter contains the message-specific arguments.


  26.1.6  Dynamic Data Exchange Message Flow

A typical DDE conversation consists of the following events:

1.	The client application initiates the conversation, and the server application responds.

2.	The applications exchange data by any or all of the following methods:

•	The server application sends data to the client at the client's request.

•	The client application sends unsolicited data to the server application.

•	The client application requests the server application to notify the client whenever a data item changes (warm data link).

•	The client application requests the server application to send data whenever the data changes (hot data link).

•	The server application carries out a command at the client's request.

3.	Either the client or server application terminates the conversation.

An application window that processes requests from a client or server must process them strictly in the order they are received.

A client can establish conversations with more than one server; a server can have conversations with more than one client. When handling messages from more than one source, a client or server must process the messages of a given conversation synchronously, but need not process all messages synchronously. In other words, it can shift from one conversation to another as needed.

If an application is unable to process an incoming request because it is waiting for a DDE response, it must prevent deadlock by posting a WM_DDE_ACK message with the fBusy member of the DDEACK structure set to 1. An application can also send a busy WM_DDE_ACK message if, for any reason, it cannot process an incoming request within a reasonable amount of time.

An application should be able to handle the failure of a client or server to respond to a message within a certain time. Since the length of the time-out interval may vary depending on the nature of the application and the configuration of the user's system (including whether it is connected to a network), the application should provide a way for the user to specify the interval.


  26.1.7  Parameter-Packing Functions

The lParam parameter of many DDE messages contains two pieces of data. For example, the lParam of the WM_DDE_DATA message contains a data handle and an atom. In previous versions of Windows, an application could use the MAKELONG macro to prepare an lParam parameter, and the LOWORD and HIWORD macros to remove the low-order and high-order values from lParam. Because a Win32 data handle is a 32-bit value, a Win32 application must use the PackDDElParam function to pack the handle and atom into an lParam parameter, and the UnpackDDElParam function to remove the values. DDE applications must use PackDDElParam and UnpackDDElParam for all messages posted during a DDE conversation.

The Win32 API also includes the ReuseDDElParam and FreeDDElParam functions. ReuseDDElParam allows a DDE application to reuse a packed lParam parameter, helping reduce the number of memory reallocations the application must perform during a conversation. An application can use the FreeDDElParam to free the memory associated with a data handle received during a DDE conversation.


  26.2  Using Dynamic Data Exchange

The section describes how to perform the following tasks:

•	Initiate a DDE conversation.

•	Transfer a single data item.

•	Establish a permanent data link.

•	Carry out commands in a server application.

•	Terminate a DDE conversation.


  26.2.1  Initiating a Conversation

To initiate a DDE conversation, the client sends a WM_DDE_INITIATE message. Usually, the client broadcasts this message by calling the SendMessage function, with −1 as the first parameter. If the application already has the window handle of the server application, it can send the message directly to that window. The client prepares atoms for the application name and topic name by calling the GlobalAddAtom function. The client can request conversations with any potential server application and for any potential topic by supplying NULL (wildcard) atoms for the application and topic.

The following example illustrates how the client initiates a conversation, where both the application and topic are specified.

/* Global variable */

static BOOL fInInitiate = FALSE;

    char *szApplication;

    char *szTopic;

    atomApplication = *szApplication == 0 ?

        NULL : GlobalAddAtom((LPSTR) szApplication);

    atomTopic = *szTopic == 0 ?

        NULL : GlobalAddAtom((LPSTR) szTopic);

    fInInitiate = TRUE;

    SendMessage((HWND) -1,        /* broadcasts message          */

        WM_DDE_INITIATE,          /* initiates conversation      */

        (WPARAM) hwndClientDDE,   /* handle of client DDE window */

        MAKELONG(atomApplication, /* application-name atom       */

            atomTopic));          /* topic-name atom             */

    fInInitiate = FALSE;

    if (atomApplication != NULL)

        GlobalDeleteAtom(atomApplication);

    if (atomTopic != NULL)

        GlobalDeleteAtom(atomTopic);

Note that if your application uses NULL atoms, you need not use the GlobalAddAtom and GlobalDeleteAtom functions. In this example, the client application creates two global atoms containing the name of the server and the name of the topic, respectively.

The client application sends a WM_DDE_INITIATE message with these two atoms in the lParam parameter of the message. In the call to the SendMessage function, the special window handle −1 directs Windows to send this message to all other active applications. SendMessage does not return to the client application until all applications that receive the message have, in turn, returned control to Windows. This means that all WM_DDE_ACK messages sent in reply by the server applications are guaranteed to have been processed by the client by the time the SendMessage call has returned.

After SendMessage returns, the client application deletes the global atoms.

Server applications respond according to the logic illustrated in »this diagram«.

To acknowledge one or more topics, the server must create atoms for each conversation (requiring duplicate application-name atoms if there are multiple topics) and send a WM_DDE_ACK message for each conversation, as illustrated in the following example.

if ((atomApplication = GlobalAddAtom("Server")) != 0) {

    if ((atomTopic = GlobalAddAtom(szTopic)) != 0) {

        SendMessage(hwndClientDDE,

            WM_DDE_ACK,

            (WPARAM) hwndServerDDE,

            MAKELONG(atomApplication, atomTopic));

        GlobalDeleteAtom(atomApplication);

    }

    GlobalDeleteAtom(atomTopic);

}

if ((atomApplication == 0) || (atomTopic == 0)) {

     .

     . /* error handling */

     .

}

When a server responds with a WM_DDE_ACK message, the client application should save the handle of the server window. The client receiving the handle as the wParam parameter of the WM_DDE_ACK message, then sends all subsequent DDE messages to the server window this handle identifies.

If your client application uses NULL atoms for the application name or topic name, you should expect the application to receive acknowledgments from more than one server application. Multiple acknowledgements can also come from multiple instances of a DDE server, even if your client application does not use NULL atoms. A server should always use a unique window for each conversation. The window procedure in the client application can use the handle of the server window (provided as the lParam parameter of WM_DDE_INITIATE) to track the status of multiple conversations. This allows a single client window to process several conversations without needing to terminate and reconnect with a new client window for each conversation.


  26.2.2  Transferring a Single Item

Once a DDE conversation has been established, the client can retrieve the value of a data item from the server by issuing the WM_DDE_REQUEST message, or the client can submit a data-item value to the server by issuing the WM_DDE_POKE message.


  26.2.2.1  Retrieving an Item from the Server

To retrieve an item from the server, the client sends the server a WM_DDE_REQUEST message specifying the item and format to retrieve, as shown in the following example.

if ((atomItem = GlobalAddAtom(szItemName)) != 0) {

    if (!PostMessage(hwndServerDDE,

            WM_DDE_REQUEST,

            (WPARAM) hwndClientDDE,

            PackDDElParam(WM_DDE_REQUEST, CF_TEXT, atomItem)))

        GlobalDeleteAtom(atomItem);

}

if (atomItem == 0) {

     .

     . /* error handling */

     .

}

In this example, the client specifies the clipboard format CF_TEXT as the preferred format for the requested data item.

The receiver (server) of the WM_DDE_REQUEST message typically must delete the item atom, but if the PostMessage call itself fails, the client must delete the atom.

If the server has access to the requested item and can render it in the requested format, the server copies the item value as a shared memory object and sends the client a WM_DDE_DATA message, as illustrated in the following example.

/*

 * Allocate the size of the DDE data header, plus the data: a

 * string,<CR><LF><NULL>. The byte for the string's terminating

 * null character is counted by DDEDATA.Value[1].

 */

if (!(hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,

        (LONG) sizeof(DDEDATA) + lstrlen(szItemValue) + 2)))

    return;

if (!(lpData = (DDEDATA FAR*) GlobalLock(hData)))  {

    GlobalFree(hData);

    return;

}

   .

   .

   .

lpData->cfFormat = CF_TEXT;

lstrcpy((LPSTR) lpData->Value, (LPSTR) szItemValue);

/* Each line of CF_TEXT data is terminated by CR/LF. */

lstrcat((LPSTR) lpData->Value, (LPSTR) "\r\n");

GlobalUnlock(hData);

if ((atomItem = GlobalAddAtom((LPSTR) szItemName)) != 0) {

    lParam = PackDDElParam(WM_DDE_ACK, (UINT) hData, atomItem);

    if (!PostMessage(hwndClientDDE,

            WM_DDE_DATA,

            (WPARAM) hwndServerDDE,

            lParam)) {

        GlobalFree(hData);

        GlobalDeleteAtom(atomItem);

        FreeDDElParam(WM_DDE_ACK, lParam);

    }

}

if (atomItem == 0) {

     .

     . /* error handling */

     .

}

In this example, the server application allocates a memory object to contain the data item. The memory is allocated with the GMEM_DDESHARE option, so that the server and client applications can share the memory. After allocating the memory object, the server application locks the object so it can obtain the object's address. The data object is initialized as a DDEDATA structure.

The server application then sets the cfFormat member of the structure to CF_TEXT to inform the client application that the data is in text format. In response, the client copies the value of the requested data into the Value member of the DDEDATA structure.

After the server has filled the data object, the server unlocks the data and creates a global atom containing the name of the data item.

Finally, the server issues the WM_DDE_DATA message by calling the PostMessage function. The handle of the data object and the atom containing the item name are packed into the lParam parameter of the message by the PackDDElParam function.

If PostMessage fails, the server must use the FreeDDElParam function to free the packed lParam parameter. The server must also free the packed lParam parameter for the WM_DDE_REQUEST message it received.

If the server cannot satisfy the request, it sends the client a negative WM_DDE_ACK message, as shown in the following example.

/* negative acknowledgment */

PostMessage(hwndClientDDE,

    WM_DDE_ACK,

    (WPARAM) hwndServerDDE,

    PackDDElParam(WM_DDE_ACK, 0, atomItem));

Upon receiving a WM_DDE_DATA message, the client processes the data-item value as appropriate. Then, if the fAckReq member specified in the WM_DDE_DATA message is 1, the client must send the server a positive WM_DDE_ACK message, as shown in the following example.

UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT) &hData,

    (PUINT) &atomItem);

if (!(lpDDEData = (DDEDATA FAR*) GlobalLock(hData))

        || (lpDDEData->cfFormat != CF_TEXT)) {

    PostMessage(hwndServerDDE,

        WM_DDE_ACK,

        (WPARAM) hwndClientDDE,

        PackDDElParam(WM_DDE_ACK, 0, atomItem)); /* negative ACK */

}

/* Copy data from lpDDEData here.*/

if (lpDDEData->fAckReq) {

    PostMessage(hwndServerDDE,

        WM_DDE_ACK,

        (WPARAM) hwndClientDDE,

        PackDDElParam(WM_DDE_ACK, 0x8000,

            atomItem)); /* positive ACK */

}

bRelease = lpDDEData->fRelease;

GlobalUnlock(hData);

if (bRelease)

    GlobalFree(hData);

In this example, the client examines the format of the data. If the format is not CF_TEXT (or if the client cannot lock the memory for the data), the client sends a negative WM_DDE_ACK message to indicate that it cannot process the data. If the client cannot lock a data handle because the handle contains the fAckReq member, the client should not send a negative WM_DDE_ACK message. Instead, the client should terminate the conversation.

If a client sends a negative acknowledgement in response to a WM_DDE_DATA message, the server is responsible for freeing the memory (but not the lParam parameter) referenced by the WM_DDE_DATA message associated with the negative acknowledgement.

If it can process the data, the client examines the fAckReq member of the DDEDATA structure to determine whether the server requested that it be informed that the client received and processed the data successfully. If the server did request this information, the client sends the server a positive WM_DDE_ACK message.

Because unlocking data invalidates the pointer to the data, the client saves the value of the fRelease member before unlocking the data object. After saving the value, the client then examines it to determine whether the server application requested the client to free the memory containing the data; the client acts accordingly.

Upon receiving a negative WM_DDE_ACK message, the client can ask for the same item value again, specifying a different clipboard format. Typically, a client will first ask for the most complex format it can support, then step down if necessary through progressively simpler formats until it finds one the server can provide.

If the server supports the Formats item of the System topic, the client can determine once what clipboard formats the server supports, instead of determining them each time the client requests an item. For more information about the System topic, see Section 26.1.4.3, »The System Topic«.


  26.2.2.2  Submitting an Item to the Server

The client may send an item value to the server by using the WM_DDE_POKE message. The client renders the item to be sent and sends the WM_DDE_POKE message, as illustrated in the following example.

if (!(hPokeData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,

        (LONG) sizeof(DDEPOKE) + lstrlen(szValue) + 2)))

    return;

if (!(lpPokeData = (DDEPOKE FAR*) GlobalLock(hPokeData))) {

    GlobalFree(hPokeData);

    return;

}

lpPokeData->fRelease = TRUE;

lpPokeData->cfFormat = CF_TEXT;

lstrcpy((LPSTR) lpPokeData->Value, (LPSTR) szValue);

/* Each line of CF_TEXT data is terminated by CR/LF. */

lstrcat((LPSTR) lpPokeData->Value, (LPSTR) "\r\n");

GlobalUnlock(hPokeData);

if ((atomItem = GlobalAddAtom((LPSTR) szItem)) != 0) {

       .

       .

       .

        if (!PostMessage(hwndServerDDE,

                WM_DDE_POKE,

                (WPARAM) hwndClientDDE,

                PackDDElParam(WM_DDE_POKE, (UINT) hPokeData,

                    atomItem))) {

           GlobalDeleteAtom(atomItem);

           GlobalFree(hPokeData);

        }

}

if (atomItem == 0) {

     .

     . /* error handling */

     .

}

Note that sending data by using a WM_DDE_POKE message is essentially the same as sending it by using a WM_DDE_DATA message, except that WM_DDE_POKE is sent from the client to the server.

If the server is able to accept the data-item value in the format rendered by the client, the server processes the item value as appropriate and sends the client a positive WM_DDE_ACK message. If it is unable to process the item value, because of its format or for other reasons, the server sends the client a negative WM_DDE_ACK message.

UnpackDDElParam(WM_DDE_POKE, lParam, (PUINT) &hPokeData,

    (PUINT) &atomItem);

GlobalGetAtomName(atomItem, szItemName, ITEM_NAME_MAX_SIZE);

if (!(lpPokeData = (DDEPOKE FAR*) GlobalLock(hPokeData))

        || lpPokeData->cfFormat != CF_TEXT

        || !IsItemSupportedByServer(szItemName)) {

    PostMessage(hwndClientDDE,

        WM_DDE_ACK,

        (WPARAM) hwndServerDDE,

        PackDDElParam(WM_DDE_ACK, 0, atomItem)); /* negative ACK */

}

lstrcpy(szItemValue, lpPokeData->Value); /* copies value */

bRelease = lpPokeData->fRelease;

GlobalUnlock(hPokeData);

if (bRelease) {

    GlobalFree(hPokeData);

}

PostMessage(hwndClientDDE,

    WM_DDE_ACK,

    (WPARAM) hwndServerDDE,

    PackDDElParam(WM_DDE_ACK,

         0x8000, atomItem));    /* positive ACK */

In this example, the server calls the GlobalGetAtomName function to retrieve the name of the item the client sent. The server then determines whether it supports the item and whether the item is rendered in the correct format (that is, CF_TEXT). If the item is not supported and not rendered in the correct format, or if the server cannot lock the memory for the data, the server sends a negative acknowledgment back to the client application. Note that in this case, sending a negative acknowledgement is correct because WM_DDE_POKE messages are always assumed to have the fAckReq member set. The server should ignore the member.

If a server sends a negative acknowledgement in response to a WM_DDE_POKE message, the client is responsible for freeing the memory (but not the lParam parameter) referenced by the WM_DDE_POKE message associated with the negative acknowledgement.


  26.2.3  Establishing a Permanent Data Link

A client application can use DDE to establish a link to an item in a server application. Once such a link is established, the server sends periodic updates of the linked item to the client, typically, whenever the value of the item changes. Thus, a permanent data stream is established between the two applications; this data stream remains in place until it is explicitly disconnected.


  26.2.3.1  Initiating a Data Link

The client initiates a data link by posting a WM_DDE_ADVISE message, as shown in the following example.

if (!(hOptions = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,

        sizeof(DDEADVISE))))

    return;

if (!(lpOptions = (DDEADVISE FAR*) GlobalLock(hOptions))) {

    GlobalFree(hOptions);

    return;

}

lpOptions->cfFormat = CF_TEXT;

lpOptions->fAckReq = TRUE;

lpOptions->fDeferUpd = FALSE;

GlobalUnlock(hOptions);

if ((atomItem = GlobalAddAtom(szItemName)) != 0) {

    if (!(PostMessage(hwndServerDDE,

            WM_DDE_ADVISE,

            (WPARAM) hwndClientDDE,

            PackDDElParam(WM_DDE_ADVISE, (UINT) hOptions,

                atomItem)))) {

        GlobalDeleteAtom(atomItem);

        GlobalFree(hOptions);

        FreeDDElParam(WM_DDE_ADVISE, lParam);

    }

}

if (atomItem == 0) {

    .

    . /* error handling */

    .

}

In this example, the client application sets the fDeferUpd member of the WM_DDE_ADVISE message to FALSE. This directs the server application to send the data to the client whenever the data changes.

If the server has access to the item and can render it in the requested format, the server notes the new link (recalling the flags specified in the hOptions parameter) and sends the client a positive WM_DDE_ACK message. From then on, until the client issues a matching WM_DDE_UNADVISE message, the server sends the new data to the client every time the value of the item changes in the server application.

If the server is unable to service the WM_DDE_ADVISE request, it sends the client a negative WM_DDE_ACK message.

The WM_DDE_ADVISE message establishes the format of the data to be exchanged during the link. If the client attempts to establish another link with the same item but is using a different data format, the server can choose to either reject the second data format or attempt to support it. If a warm link has been established for any data item, the server can support only one data format at a time. This is because the WM_DDE_DATA message for a warm link has a NULL data handle, which otherwise contains the format information. Thus, a server must reject all warm links for an item already linked, and it must reject all links for an item that has any warm links.

Another interpretation may be that the server changes the format and the hot/warm state of a link when a second link is requested for the same data item.

In general, client applications should not attempt to establish more than one link at a time for a data item.


  26.2.3.2  Initiating a Data Link with the Paste Link Command

Applications that support hot or warm data links typically support a registered clipboard format named Link. When associated with the application's Copy and Paste Link commands, this clipboard format enables the user to establish DDE conversations between applications simply by copying a data item in the server application and pasting it into the client application.

A server application supports the Link clipboard format by placing in the clipboard a string containing the application, topic, and item names when the user chooses the Copy command from the Edit menu. Following is the standard Link format:

application\0topic\0item\0\0

A single null character separates the names, and two null characters terminate the entire string.

Both the client and server applications must register the Link clipboard format, as shown:

cfLink = RegisterClipboardFormat("Link");

A client application supports the Link clipboard format by means of a Paste Link command on its Edit menu. When the user chooses this command, the client application parses the application, topic, and item names from the Link-format clipboard data. Using these names, the client application initiates a conversation for the application and topic, if such a conversation does not already exist. The client application then sends a WM_DDE_ADVISE message to the server application, specifying the item name contained in the Link-format clipboard data.

Following is an example of a client application's response when the user chooses the Paste Link command.

void DoPasteLink(hwndClientDDE)

HWND hwndClientDDE;

{

    HANDLE hData;

    LPSTR lpData;

    HWND hwndServerDDE;

    CHAR szApplication[APP_MAX_SIZE + 1];

    CHAR szTopic[TOPIC_MAX_SIZE + 1];

    CHAR szItem[ITEM_MAX_SIZE + 1];

    int nBufLen;

    if (OpenClipboard(hwndClientDDE)) {

        if (!(hData = GetClipboardData(cfLink)) ||

                !(lpData = GlobalLock(hData))) {

            CloseClipboard();

            return;

        }

        /* Parse the clipboard data. */

        if ((nBufLen = lstrlen(lpData)) >= APP_MAX_SIZE) {

            CloseClipboard();

            GlobalUnlock(hData);

            return;

        }

        lstrcpy(szApplication, lpData);

        lpData += (nBufLen + 1); /* skips over null */

        if ((nBufLen = lstrlen(lpData)) >= TOPIC_MAX_SIZE) {

            CloseClipboard();

            GlobalUnlock(hData);

            return;

        }

        lstrcpy(szTopic, lpData);

        lpData += (nBufLen + 1); /* skips over null */

        if ((nBufLen = lstrlen(lpData)) >= ITEM_MAX_SIZE) {

            CloseClipboard();

            GlobalUnlock(hData);

            return;

        }

        lstrcpy(szItem, lpData);

        GlobalUnlock(hData);

        CloseClipboard();

        if (hwndServerDDE =

                FindServerGivenAppTopic(szApplication, szTopic)) {

            /* App/topic conversation is already started. */

            if (DoesAdviseAlreadyExist(hwndServerDDE, szItem))

                MessageBox(hwndMain,

                    "Advisory already established",

                    "Client", MB_ICONEXCLAMATION | MB_OK);

            else

                SendAdvise(hwndClientDDE, hwndServerDDE, szItem);

        }

        else {

            /* Client must initiate a new conversation first. */

            SendInitiate(szApplication, szTopic);

            if (hwndServerDDE =

                    FindServerGivenAppTopic(szApplication,

                        szTopic))

                SendAdvise(hwndClientDDE, hwndServerDDE, szItem);

        }

    }

    return;

}

In this example, the client application opens the clipboard and determines whether it contains data in the Link format (that is, cfLink) it had previously registered. If not, or if it cannot lock the data in the clipboard, the client returns.

After the client application retrieves a pointer to the clipboard data, it parses the data to extract the application, topic, and item names.

The client application determines whether a conversation on the topic already exists between it and the server application. If a conversation does exist, the client application checks whether a link already exists for the data item. If such a link exists, the client displays a message box to the user; otherwise, it calls its own SendAdvise function to send a WM_DDE_ADVISE message to the server for the item.

If a conversation on the topic does not already exist between the client and the server, the client first calls its own SendInitiate function to broadcast the WM_DDE_INITIATE message to request a conversation and, second, calls its own FindServerGivenAppTopic function to establish the conversation with the window that responds on behalf of the server application. Once the conversation has begun, the client application calls SendAdvise to request the link.


  26.2.3.3  Notifying the Client that Data Has Changed

When the client establishes a link by using the WM_DDE_ADVISE message, with the fDeferUpd member not set (that is, equal to zero), the client has requested the server send the data item each time the item's value changes. In such cases, the server renders the new value of the data item in the previously specified format and sends the client a WM_DDE_DATA message, as shown in the following example.

/*

 * Allocate the size of a DDE data header, plus data (a string),

 * plus a <CR><LF><NULL>

 */

if (!(hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,

        sizeof(DDEDATA) + lstrlen(szItemValue) + 3)))

    return;

if (!(lpData = (DDEDATA FAR*) GlobalLock(hData))) {

    GlobalFree(hData);

    return;

}

lpData->fAckReq = bAckRequest;  /* as specified in original     */

                                /* WM_DDE_ADVISE message        */

lpData->cfFormat = CF_TEXT;

lstrcpy(lpData->Value, szItemValue); /* copies value to be sent */

lstrcat(lpData->Value, "\r\n"); /* CR/LF for CF_TEXT format     */

GlobalUnlock(hData);

if ((atomItem = GlobalAddAtom(szItemName)) != 0) {

    if (!PostMessage(hwndClientDDE,

            WM_DDE_DATA,

            (WPARAM) hwndServerDDE,

            PackDDElParam(WM_DDE_DATA, (UINT) hData, atomItem))) {

        GlobalFree(hData);

        GlobalDeleteAtom(atomItem);

        FreeDDElParam(WM_DDE_DATA, lParam);

    }

}

if (atomItem == 0) {

     .

     . /* error handling */

     .

}

In this example, the client processes the item value as appropriate. If the fAckReq flag for the item is set, the client sends the server a positive WM_DDE_ACK message.

When the client establishes the link, with the fDeferUpd member set (that is, equal to 1), the client has requested that only a notification, not the data itself, be sent each time the data changes. In such cases, when the item value changes, the server does not render the value but simply sends the client a WM_DDE_DATA message with a null data handle, as illustrated in the following example.

if (bDeferUpd) {     /* checking whether the flag was originally */

                     /* set in the WM_DDE_ADVISE message         */

    if ((atomItem = GlobalAddAtom(szItemName)) != 0) {

        if (!PostMessage(hwndClientDDE,

                WM_DDE_DATA,

                (WPARAM) hwndServerDDE,

                PackDDElParam(WM_DDE_DATA, 0,

                    atomItem))) {                   /* NULL data */

            GlobalDeleteAtom(atomItem);

            FreeDDElParam(WM_DDE_DATA, lParam);

        }

    }

}

if (atomItem == 0) {

     .

     . /* error handling */

     .

}

As necessary, the client can request the latest value of the data item by issuing a normal WM_DDE_REQUEST message, or it can simply ignore the notice from the server that the data has changed. In either case, if fAckReq is equal to 1, the client is expected to send a positive WM_DDE_ACK message to the server.


  26.2.3.4  Terminating a Data Link

If the client requests that a specific data link be terminated, the client sends the server a WM_DDE_UNADVISE message, as shown in the following example.

if ((atomItem = GlobalAddAtom(szItemName)) != 0) {

    if (!PostMessage(hwndServerDDE,

            WM_DDE_UNADVISE,

            (WPARAM) hwndClientDDE,

            PackDDElParam(WM_DDE_UNADVISE, 0, atomItem))) {

        GlobalDeleteAtom(atomItem);

        FreeDDElParam(WM_DDE_UNADVISE, lParam);

    }

}

if (atomItem == 0) {

     .

     . /* error handling */

     .

}

The server checks whether the client currently has a link to the specific item in this conversation. If a link exists, the server sends the client a positive WM_DDE_ACK message; the server is then no longer required to send updates about the item. If no link exists, the server sends the client a negative WM_DDE_ACK message.

The WM_DDE_UNADVISE message specifies a data format. A format of zero informs the server to stop all links for the specified item, even if several hot links are established and each uses a different format.

To terminate all links for a conversation, the client sends the server a WM_DDE_UNADVISE message with a null item atom. The server determines whether the conversation has at least one link currently established. If a link exists, the server sends the client a positive WM_DDE_ACK message; the server then no longer has to send any updates in the conversation. If no link exists, the server sends the client a negative WM_DDE_ACK message.


  26.2.4  Carrying Out Commands in a Server Application

A Windows-based application can use the WM_DDE_EXECUTE message to cause a certain command or series of commands to be carried out in another application. To do this, the client sends the server a WM_DDE_EXECUTE message containing a handle of a command string, as shown in the following example.

if (!(hCommand = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,

        sizeof(szCommandString) + 1)))

    return;

if (!(lpCommand = GlobalLock(hCommand))) {

    GlobalFree(hCommand);

    return;

}

lstrcpy(lpCommand, szCommandString);

GlobalUnlock(hCommand);

if (!PostMessage(hwndServerDDE,

        WM_DDE_EXECUTE,

        (WPARAM) hwndClientDDE,

        PackDDElParam(WM_DDE_EXECUTE, 0, (UINT) hCommand))) {

    GlobalFree(hCommand);

    FreeDDElParam(WM_DDE_EXECUTE, lParam);

}

In this example, the server attempts to carry out the specified command string. If it succeeds, the server sends the client a positive WM_DDE_ACK message; otherwise, it sends a negative WM_DDE_ACK message. This WM_DDE_ACK message reuses the hCommand handle passed in the original WM_DDE_EXECUTE message.

If the client's command execution string requests that the server terminate, the server should respond by sending a positive WM_DDE_ACK message and then post a WM_DDE_TERMINATE message before terminating. All other commands sent with a WM_DDE_EXECUTE message should be executed synchronously; that is, the server should send a WM_DDE_ACK message only after successfully completing the command.


  26.2.5  Terminating a Conversation

Either the client or the server can issue a WM_DDE_TERMINATE message to terminate a conversation at any time. Similarly, both the client and server applications should be prepared to receive this message at any time. An application must terminate all of its conversations before shutting down.

In the following example, the application terminating the conversation posts a WM_DDE_TERMINATE message.

PostMessage(hwndServerDDE, WM_DDE_TERMINATE,

    PackDDElParam(WM_DDE_TERMINATE, (UINT) hwndClientDDE, 0), 0);

This informs the other application that the sending application will send no further messages and the recipient can close its window. The recipient is expected in all cases to respond promptly by sending a WM_DDE_TERMINATE message. The recipient must not send a negative, busy, or positive WM_DDE_ACK message.

After an application has sent the WM_DDE_TERMINATE message to the partner in a DDE conversation, it must not respond to any messages from that partner, since the partner might already have destroyed the window to which the response would be sent.

If a DDE application receives a DDE message other than WM_DDE_TERMINATE after it has posted a WM_DDE_TERMINATE message, it should free all objects associated with the received messages except the data handles for WM_DDE_DATA or WM_DDE_POKE messages that do not have the fRelease member set.

When an application is about to terminate, it should end all active DDE conversations before completing processing of the WM_DESTROY message. However, if an application does not end its active DDE conversations, the system will properly terminate any DDE conversations associated with a window when the window is destroyed. The following example shows how a server application terminates all DDE conversations.

void TerminateConversations(hwndServerDDE)

HWND hwndServerDDE;

{

    HWND hwndClientDDE;

    /* Terminate each active conversation. */

    while (hwndClientDDE = GetNextLink(hwndClientDDE)) {

        SendTerminate(hwndServerDDE, hwndClientDDE);

    }

    return;

}

BOOL AtLeastOneLinkActive(VOID)

{

    return TRUE;

}

HWND GetNextLink(hwndDummy)

    HWND hwndDummy;

{

    return (HWND) 1;

}

VOID SendTerminate(HWND hwndServerDDE, HWND hwndClientDDE)

{

    return;

}


  26.3  Functions and Messages

Following are the functions and messages used with DDE.


  Functions

DdeSetQualityOfService
FreeDDElParam
PackDDElParam
ReuseDDElParam
UnpackDDElParam


  Messages

WM_DDE_ACK
WM_DDE_ADVISE
WM_DDE_DATA
WM_DDE_EXECUTE
WM_DDE_INITIATE
WM_DDE_POKE
WM_DDE_REQUEST
WM_DDE_TERMINATE
WM_DDE_UNADVISE


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


27.1  About the Multiple Document Interface
  Chapter 27    Multiple Document Interface

27.1  About the Multiple Document Interface

The multiple document interface (MDI) is a specification that defines the standard user interface for applications written for Microsoft® Windows (™) . An MDI application enables the user to work with more than one document at the same time. Each document is displayed in a separate child window within the client area of the application's main window. Typical MDI applications include word processing applications that allow the user to work with multiple text documents, and spreadsheet applications that allow the user to work with multiple charts and spreadsheets.

Windows provides extensive support for MDI applications. This chapter describes the structure of an MDI application and how to take advantage of the built-in MDI support found in the Win32 application program interface (API).


  27.1.1  Frame, Client, and Child Windows

An MDI application has three kinds of windows: a frame window, a client window, as well as a number of child windows. The frame window is like the main window of the application: it has a sizing border, a title bar, a System menu, a Minimize button, and a Maximize button. The application must register a window class for the frame window and provide a window procedure to support it.

An MDI application does not display output in the client area of the frame window. Instead, it displays the MDI client window. An MDI client window is a special type of child window belonging to the preregistered window class MDICLIENT. The client window is a child of the frame window; it serves as the background for child windows. It also provides support for creating and manipulating child windows. For example, an MDI application can create, activate, or maximize child windows by sending messages to the MDI client window.

When the user opens or creates a document, the client window creates a child window for the document. The client window is the parent window of all MDI child windows in a given application. Each child window has a sizing border, a title bar, a System menu (also known as the Control menu), a Minimize button, and a Maximize button. Because a child window is clipped, it is confined to the client window and cannot appear outside it.

An MDI application can support more than one kind of document. For example, a typical spreadsheet application enables the user to work with both charts and spreadsheets. For each type of document that it supports, an MDI application must register a child window class and provide a window procedure to support the windows belonging to that class. For more information about window classes, see Chapter 3, »Window Classes«. For more information about window procedures, see Chapter 4, »Window Procedures«.

»This illustration« is a typical MDI application. It is named Multipad.


  27.1.2  Child Window Creation

To create a child window, an MDI application either calls the CreateMDIWindow function or sends the WM_MDICREATE message to the MDI client window. A thread in an MDI application can use CreateMDIWindow to create a child window in a different thread. The WM_MDICREATE message is used only in the context of the same thread.

To destroy a child window, an MDI application sends a WM_MDIDESTROY message to the MDI client window.


  27.1.3  Child Window Activation

Any number of child windows can appear in the client window at any one time, but only one can be active. The active child window is positioned in front of all other child windows, and its border is highlighted.

The user can activate an inactive child window by clicking it. An MDI application activates a child window by sending a WM_MDIACTIVATE message to the MDI client window. As the client window processes this message, it sends a WM_MDIACTIVATE message to the window procedure of the child window to be activated and to the window procedure of the child window being deactivated.

Windows keeps track of each child window's position in the stack of overlapping windows. This stacking is known as the Z order. The user can activate the next child window in the Z order by choosing the Next command from the System menu in the active window. An application activates the next (or previous) child window in the Z order by sending a WM_MDINEXT message to the client window.

To retrieve the handle of the active child window, the MDI application sends a WM_MDIGETACTIVE message to the client window.


  27.1.4  Menus

The frame window of an MDI application should include a menu bar with a Window menu item and its corresponding pop-up menu. The Window pop-up menu should include command items that arrange the child windows within the client window or that close all child windows. The Window menu of a typical MDI application might include the items in the following table.

Menu item	Purpose
Tile	Arranges child windows in a tile format so that each appears in its entirety in the client window.
Cascade	Arranges child windows in a cascade format. The child windows overlap one another, but the title bar of each is visible.
Arrange Icons	Arranges the icons of minimized child windows along the bottom of the client window.
Close All	Closes all child windows.
Whenever a child window is created, Windows automatically appends a new menu item to the Window menu. The text of the menu item is the same as the text on the menu bar of the new child window. By choosing the menu item, the user can activate the corresponding child window. When a child window is destroyed, Windows automatically removes the corresponding menu item from the Window menu.

Windows can add up to ten menu items to the Window menu. When the tenth child window is created, Windows adds the More Windows item to the Window menu. Choosing this item causes the Select Window dialog box to appear. The dialog box contains a list box with the titles of all MDI child windows currently available. The user can activate a child window by choosing its title from the list box.

If your MDI application supports several types of child windows, tailor the menu bar to reflect the operations associated with the active window. To do this, provide separate menu resources for each type of child window the application supports. When a new type of child window is activated, the application should send a WM_MDISETMENU message to the client window, passing to it the handle of the corresponding menu.

When no child window exists, the menu bar should contain only items used to create or open a document.

When the user is navigating through an MDI application's menus by using cursor keys, the keys behave differently than when the user is navigating through a typical application's menus. In an MDI application, control passes from the application's System menu to the System menu of the active child window, and then to the first item on the menu bar.


  27.1.5  Accelerators

To receive and process accelerator keys for its child windows, an MDI application must include the TranslateMDISysAccel function in its message loop. The loop must call TranslateMDISysAccel before calling the TranslateAccelerator or DispatchMessage function.

Accelerator keys on the System menu for an MDI child window are different from those for a non−MDI child window. In an MDI child window, the ALT+ − (minus) key combination opens the System menu, the CTRL+F4 key combination closes the active child window, and the CTRL+F6 key combination activates the next child window.


  27.1.6  Child Window Size and Arrangement

An MDI application controls the size and position of its child windows by sending messages to the MDI client window. To maximize the active child window, the application sends the WM_MDIMAXIMIZE message to the client window. When a child window is maximized, its client area completely fills the MDI client window. In addition, Windows automatically hides the child window's title bar, and adds the child window's System menu icon and restore icon to the MDI application's menu bar. The application can restore the client window to its original (pre-maximized) size and position by sending the client window a WM_MDIRESTORE message.

An MDI application can arrange its child windows in either a cascade or tile format. When the child windows are cascaded, the windows appear in a stack. The window on the bottom of the stack occupies the upper-left corner of the screen, and the remaining windows are offset vertically and horizontally so that the left border and title bar of each child window is visible. To arrange child windows in the cascade format, an MDI application sends the WM_MDICASCADE message. Typically, the application sends this message when the user chooses the Cascade command from the Window menu.

When the child windows are tiled, Windows displays each child window in its entirety — overlapping none of the windows. All of the windows are sized, as necessary, to fit within the client window. To arrange child windows in the tile format, an MDI application sends a WM_MDITILE message to the client window. Typically, the application sends this message when the user chooses the Tile command from the Window menu.

An MDI application should provide a different icon for each type of child window it supports. The application specifies an icon when registering the child window class. Windows automatically displays a child window's icon in the lower portion of the client window when the child window is minimized. An MDI application directs Windows to arrange child window icons by sending a WM_MDIICONARRANGE message to the client window. Typically, the application sends this message when the user chooses the Arrange Icons command from the Window menu.


  27.1.7  Icon Title Windows

Because MDI child windows may be minimized, an MDI application must avoid manipulating icon title windows as if they were normal MDI child windows. Icon title windows appear when the application enumerates child windows of the MDI client window. Icon title windows differ from other child windows, however, in that they are owned by an MDI child window.

To determine whether a child window is an icon title window, use the GetWindow function with the GW_OWNER index. Non-title windows return NULL. Note that this test is insufficient for top-level windows, because menus and dialog boxes are owned windows.


  27.1.8  Child Window Data

Because the number of child windows varies depending on how many documents the user opens, an MDI application must be able to associate data (for example, the name of the current file) with each child window. There are two ways to do this:

•	Store child window data in the window structure.

•	Use window properties.


  27.1.8.1  Data in the Window Structure

When an MDI application registers a window class, it may reserve extra space in the window structure for application data specific to this particular class of windows. To store and retrieve data in this extra space, the application uses the GetWindowWord, SetWindowWord, GetWindowLong, and SetWindowLong functions.

To maintain a large amount of data for a child window, an application can allocate memory for a data structure and then store the handle of the memory containing the structure in the extra space associated with the child window.


  27.1.8.2  Window Properties

An MDI application can also store per-document data by using window properties. (Per-document data is data specific to the type of document contained in a particular child window.) Properties are different from extra space in the window structure in that you need not allocate extra space when registering the window class. A window can have any number of properties. Also, where offsets are used to access the extra space in window structures, properties are referred to by string names. For more information about window properties, see Chapter 24, »Window Properties«.


  27.2  Using the Multiple Document Interface

This section explains how to perform the following tasks:

•	Register frame and child window classes.

•	Create frame and client windows.

•	Write the main message loop.

•	Write the frame window procedure.

•	Write the child window procedure.

•	Create a child window.

To illustrate these tasks, this section includes sample code from Multipad, a typical MDI application.


  27.2.1  Registering Child and Frame Window Classes

A typical MDI application must register two window classes: one for its frame window and one for its child windows. If an application supports more than one type of document (for example, a spreadsheet and a chart), it must register a window class for each type.

The class structure for the frame window is similar to the class structure for the main window in non−MDI applications. The class structure for the MDI child windows differs slightly from the structure for child windows in non−MDI applications as follows:

•	The class structure should have an icon, because the user can minimize an MDI child window as if it were a normal application window.

•	The menu name should be NULL, because an MDI child window cannot have its own menu.

•	The class structure should reserve extra space in the window structure. With this space, the application can associate data, such as a filename, with a particular child window.

The following code shows how Multipad registers its frame and child window classes.

BOOL APIENTRY InitializeApplication()

{

    WNDCLASS wc;

    /* Register the frame window class. */

    wc.style         = 0;

    wc.lpfnWndProc   = (WNDPROC) MPFrameWndProc;

    wc.cbClsExtra    = 0;

    wc.cbWndExtra    = 0;

    wc.hInstance     = hInst;

    wc.hIcon         = LoadIcon(hInst, IDMULTIPAD);

    wc.hCursor       = LoadCursor((HANDLE) NULL, IDC_ARROW);

    wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1);

    wc.lpszMenuName  = IDMULTIPAD;

    wc.lpszClassName = szFrame;

    if (!RegisterClass (&wc) )

        return FALSE;

    /* Register the MDI child window class. */

    wc.lpfnWndProc   = (WNDPROC) MPMDIChildWndProc;

    wc.hIcon         = LoadIcon(hInst, IDNOTE);

    wc.lpszMenuName  = (LPCTSTR) NULL;

    wc.cbWndExtra    = CBWNDEXTRA;

    wc.lpszClassName = szChild;

    if (!RegisterClass(&wc))

        return FALSE;

    return TRUE;

}


  27.2.2  Creating Frame and Child Windows

After registering its window classes, an MDI application can create its windows. First, it creates its frame window by using the CreateWindow or CreateWindowEx function. After creating its frame window, the application creates its client window, again by using CreateWindow or CreateWindowEx. The application should specify MDICLIENT as the client window's class name; MDICLIENT is a preregistered window class defined by Windows. The lpvParam parameter of CreateWindow or CreateWindowEx should point to a CLIENTCREATESTRUCT structure. This structure contains the members described in the following table.

Member	Description
hWindowMenu	Identifies the Window menu used for controlling MDI child windows. As child windows are created, the application adds their titles to the Window menu as menu items. The user can then activate a child window by choosing its title from the Window menu.
idFirstChild	Specifies the identifier of the first MDI child window. The first MDI child window created is assigned this identifier. Additional windows are created with incremented window identifiers. When a child window is destroyed, Windows immediately reassigns the window identifiers to keep their range contiguous.
When a child window's title is added to the Window menu, Windows assigns an identifier to the child window. When the user chooses a child window's title, the frame window receives a WM_COMMAND message with the identifier in the wParam parameter. You should specify a value for the idFirstChild member that does not conflict with menu-item identifiers in the frame window's menu.

Multipad's frame window procedure creates the MDI client window while processing the WM_CREATE message. The following example shows how the client window is created.

.

. /* Process other messages here. */

.

case WM_CREATE:

    {

    CLIENTCREATESTRUCT ccs;

    /*

     * Retrieve the handle of the Window menu and assign the

     * first child window identifier.

     */

    ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), WINDOWMENU);

    ccs.idFirstChild = IDM_WINDOWCHILD;

    /* Create the MDI client window. */

    hwndMDIClient = CreateWindow( "MDICLIENT", (LPCTSTR) NULL,

        WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,

        0, 0, 0, 0, hwnd, (HMENU) 0xCAC, hInst, (LPSTR) &ccs);

    ShowWindow(hwndMDIClient, SW_SHOW);

    }

    break;

}

.

. /* Process other messages here. */

.

Titles of child windows are added to the bottom of the Window menu. If the application adds strings to the Window menu by using the AppendMenu function, these strings can be overwritten by the titles of the child windows when the Window menu is repainted. (The Window menu is repainted whenever a child window is created or destroyed.) An MDI application that adds strings to its Window menu should use the InsertMenu function and verify that the titles of child windows have not overwritten these new strings.

Use the WS_CLIPCHILDREN style to create the MDI client window to prevent the window from painting over its child windows.


  27.2.3  Writing the Main Message Loop

The main message loop of an MDI application is similar to that of a non−MDI application handling accelerator keys. The difference is that the MDI message loop calls the TranslateMDISysAccel function before checking for application-defined accelerator keys or before dispatching the message.

The following example shows the message loop of a typical MDI application.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) {

    if (!TranslateMDISysAccel(hwndMDIClient, &msg) &&

            !TranslateAccelerator(hwndFrame, hAccel, &msg)){

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

}

The TranslateMDISysAccel function translates WM_KEYDOWN messages into WM_SYSCOMMAND messages and sends them to the active MDI child window. If the message is not an MDI accelerator message, the function returns FALSE, in which case the application uses the TranslateAccelerator function to determine whether any of the application-defined accelerator keys were pressed. If not, the loop dispatches the message to the appropriate window procedure.


  27.2.4  Writing the Frame Window Procedure

The window procedure for an MDI frame window is similar to that of a non−MDI application's main window. The difference is that a frame window procedure passes all messages it does not handle to the DefFrameProc function rather than to the DefWindowProc function. In addition, the frame window procedure must also pass some messages that it does handle, including those listed in the following table.

Message	Response
WM_COMMAND	Activates the MDI child window that the user chooses. This message is sent when the user chooses an MDI child window from the Window menu of the MDI frame window. The window identifier accompanying this message identifies the MDI child window to be activated.
WM_MENUCHAR	Opens the System menu of the active MDI child window when the user presses the ALT+ − (minus) key combination.
WM_SETFOCUS	Passes the keyboard focus to the MDI client window, which in turn passes it to the active MDI child window.
WM_SIZE	Resizes the MDI client window to fit in the new frame window's client area. If the frame window procedure sizes the MDI client window to a different size, it should not pass the message to the DefWindowProc function.
The frame window procedure in Multipad is called MPFrameWndProc. The handling of other messages by MPFrameWndProc is similar to that of non−MDI applications. WM_COMMAND messages in Multipad are handled by the locally defined CommandHandler function. For command messages Multipad does not handle, CommandHandler calls the DefFrameProc function. If Multipad doesn't use DefFrameProc by default, the user can't activate a child window from the Window menu, because the WM_COMMAND message sent by choosing the window's menu item (command) would be lost.


  27.2.5  Writing the Child Window Procedure

Like the frame window procedure, an MDI child window procedure uses a special function for processing messages by default. All messages that the child window procedure does not handle must be passed to the DefMDIChildProc function rather than to the DefWindowProc function. In addition, some window-management messages must be passed to DefMDIChildProc, even if the application handles the message, in order for MDI to function correctly. Following are the messages the application must pass to DefMDIChildProc.

Message	Response
WM_CHILDACTIVATE	Performs activation processing when MDI child windows are sized, moved, or displayed. This message must be passed.
WM_GETMINMAXINFO	Calculates the size of a maximized MDI child window, based on the current size of the MDI client window.
WM_MENUCHAR	Passes the message to the MDI frame window.
WM_MOVE	Recalculates MDI client scroll bars if they are present.
WM_SETFOCUS	Activates the child window if it is not the active MDI child window.
WM_SIZE	Performs operations necessary for changing the size of a window, especially for maximizing or restoring an MDI child window. Failing to pass this message to the DefMDIChildProc function produces highly undesirable results.
WM_SYSCOMMAND	Handles System menu commands: SC_NEXTWINDOW, SC_PREVWINDOW, SC_MOVE, SC_SIZE, and SC_MAXIMIZE.


  27.2.6  Creating a Child Window

To create an MDI child window, an application can either call the CreateMDIWindow function or send a WM_MDICREATE message to the MDI client window. (The application must not use the CreateWindow function to create MDI child windows.) A single-threaded MDI application can use either method to create a child window. A thread in a multithreaded MDI application must use the CreateMDIWindow function to create a child window in a different thread.

The lParam parameter of a WM_MDICREATE message is a far pointer to an MDICREATESTRUCT structure. The structure includes four dimension members: x and y, which indicate the horizontal and vertical positions of the window, and cx and cy, which indicate the horizontal and vertical extents of the window. Any of these members may be assigned explicitly by the application, or they may be set to CW_USEDEFAULT, in which case Windows selects a position, size, or both, according to a cascading algorithm. In any case, all four members must be initialized. Multipad uses CW_USEDEFAULT for all dimensions.

The last member of the MDICREATESTRUCT structure is the style member, which may contain style bits for the window. To create an MDI child window that can have any combination of window styles, specify the MDIS_ALLCHILDSTYLES window style. When this style is not specified, an MDI child window has the WS_MINIMIZE, WS_MAXIMIZE, WS_HSCROLL, and WS_VSCROLL styles as default settings.

Multipad creates its MDI child windows by using its locally defined AddFile function (located in the source file MPFILE.C). The AddFile function sets the title of the child window by assigning the szTitle member of the window's MDICREATESTRUCT structure to either the name of the file being edited or to "Untitled." The szClass member is set to the name of the MDI child window class registered in Multipad's InitializeApplication function. The hOwner member is set to the application's instance handle.

The following code sample shows the AddFile function in Multipad.

HWND APIENTRY AddFile(pName)

CHAR * pName;

{

    HWND hwnd;

    CHAR sz[160];

    MDICREATESTRUCT mcs;

    if (!pName) {

        /*

         * If the pName parameter is NULL, load the "Untitled"

         * string from the STRINGTABLE resource and set the szTitle

         * member of MDICREATESTRUCT.

         */

        LoadString(hInst, IDS_UNTITLED, sz, sizeof(sz));

        mcs.szTitle = (LPCTSTR) sz;

    }

    else

        /*

         * Title the window with the full path and filename,

         * obtained by calling the OpenFile function with the

         * OF_PARSE flag, which is called before AddFile().

         */

        mcs.szTitle = of.szPathName;

    mcs.szClass = szChild;

    mcs.hOwner  = hInst;

    /* Use the default size for the child window. */

    mcs.x = mcs.cx = CW_USEDEFAULT;

    mcs.y = mcs.cy = CW_USEDEFAULT;

    /*

     * Give the child window the default style. The styleDefault

     * variable is defined in MULTIPAD.C.

     */

    mcs.style = styleDefault;

    /* Tell the MDI client window to create the child window. */

    hwnd = (HWND) SendMessage (hwndMDIClient, WM_MDICREATE, 0,

        (LONG) (LPMDICREATESTRUCT) &mcs);

    /*

     * If the file is found, read its contents into the child

     * window's client area.

     */

    if (pName) {

        if (!LoadFile(hwnd, pName)) {

            /* Cannot load the file; close the window. */

            SendMessage(hwndMDIClient, WM_MDIDESTROY,

                (DWORD) hwnd, 0L);

        }

    }

    return hwnd;

}

The pointer passed in the lParam parameter of the WM_MDICREATE message is passed to the CreateWindow function and appears as the first member in the CREATESTRUCT structure, passed in the WM_CREATE message. In Multipad, the child window initializes itself during WM_CREATE message processing by initializing document variables in its extra data and by creating the edit control's child window.


  27.3  Functions and Messages

The following functions and messages are used in MDI applications.


  Functions

CreateMDIWindow
DefFrameProc
DefMDIChildProc
TranslateMDISysAccel


  Messages

WM_MDIACTIVATE
WM_MDICASCADE
WM_MDICREATE
WM_MDIDESTROY
WM_MDIGETACTIVE
WM_MDIICONARRANGE
WM_MDIMAXIMIZE
WM_MDINEXT
WM_MDIREFRESHMENU
WM_MDIRESTORE
WM_MDISETMENU
WM_MDITILE


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


28.1  About Device Contexts
  Chapter 28    Device Contexts

28.1  About Device Contexts

One of the chief features of the Microsoft® Win32 (™)  application programming interface (API) is device independence. Applications written for Microsoft® Windows (™)  can draw and print output on a variety of devices. The software that supports this device independence is contained in two dynamic-link libraries. The first library is referred to as the graphics device interface (GDI); the second library is referred to as a device driver. The name of the second depends on the device where the application draws output. For example, if the application draws output in the client area of its window on a VGA display, this library is VGA.DLL; if the application prints output on an Epson® FX-80 printer, this library is EPSON9.DLL.

An application must inform GDI to load a particular device driver; and, once the driver is loaded, prepare the device for drawing operations (such as selecting a line color and width, a brush pattern and color, a font typeface, a clipping region, and so on). These tasks are accomplished by creating and maintaining a device context. A device context is a structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations. Unlike most of the Win32 structures, an application never has direct access to the device context; instead, it operates on the structure indirectly by calling various functions.


  28.1.1  Graphic Objects

The pen, brush, bitmap, palette, region, and path associated with a device context are referred to as the device context's graphic objects. Following are the attributes associated with each of these objects.

Graphic object	Associated attributes
Bitmap	Size, in bytes; dimensions, in pixels; color-format; compression scheme; and so on
Brush	Style, color, pattern, and origin
Palette	Colors and size (or number of colors)
Font	Typeface name, width, height, weight, character set, and so on
Path	Shape
Pen	Style, width, and color
Region	Location and dimensions
When an application creates a device context, Windows automatically stores a set of default objects in it. (There is, however, no default bitmap or path.) An application can examine the attributes of the default objects by calling the GetCurrentObject and GetObject functions. The application can change these defaults by creating a new object and selecting it into the device context. An object is selected into a device context by calling the SelectObject function. For more information about operations with graphic objects, see Section 28.1.4.1, »Operations on Graphic Objects«.


  28.1.2  Graphic Modes

Windows supports five graphic modes that allow an application to specify how colors are mixed, where output appears, how the output is scaled, and so on. These modes, stored in a device context, are described in the following table.

Mode	Description
Background mode	Defines how background colors are mixed with existing window or screen colors for bitmap and text operations.
Drawing mode	Defines how foreground colors are mixed with existing window or screen colors for pen, brush, bitmap, and text operations.
Mapping mode	Defines how graphics output is mapped from logical (or world) space onto the window, screen, or printer paper.
Polygon-fill mode	Defines how the brush pattern is used to fill the interior of complex regions.
Stretching mode	Defines how bitmap colors are mixed with existing window or screen colors when the bitmap is compressed (or scaled down).
As it does with graphic objects, Windows initializes a device context with default graphic modes. An application can retrieve and examine these default modes by calling the following functions.

Graphic mode	Function
Background mode	GetBkMode
Drawing mode	GetROP2
Mapping mode	GetMapMode
Polygon-fill mode	GetPolyFillMode
Stretching mode	GetStretchBltMode
An application can change the default modes by calling one of the following functions.

Graphic mode	Function
Background mode	SetBkMode
Drawing mode	SetROP2
Mapping mode	SetMapMode
Polygon-fill mode	SetPolyFillMode
Stretching mode	SetStretchBltMode


  28.1.3  Device Context Types

Windows provides four types of device contexts: display, printer, memory (or compatible), and information. Each type serves a specific purpose, as described in the following table.

Device context	Purpose
Display	Supports drawing operations on a video display.
Printer	Supports drawing operations on a printer or plotter.
Memory	Supports drawing operations on a bitmap.
Information	Supports the retrieval of device data.


  28.1.3.1  Display Device Contexts

Windows provides three types of device contexts for video displays: class, common and private. Class and private device contexts are used in applications that perform numerous drawing operations such as CAD applications, desktop-publishing applications, drawing and painting applications, and so on. Common device contexts are used in applications that perform infrequent drawing operations.

An application obtains a display device context by calling either the BeginPaint or GetDC function and identifying the window in which the corresponding output will appear. (The type of device context Windows returns is dependent on how the application registered its window class.) Typically, an application should obtain a display device context only when it must draw in the client area. When the application is finished drawing, it must release the device context by calling the EndPaint or ReleaseDC functions.

Class Device Contexts

Class device contexts are supported strictly for compatibility with previous versions of Windows. When writing a Win32 application, avoid using the class device context. Use a private device context instead.

Common Device Contexts

Common device contexts are display device contexts maintained in a special cache by the window management component of the Win32 API. An application obtains a handle identifying one of the available common device contexts by calling the GetDC, GetDCEx, or BeginPaint function. Before returning this device context handle, Windows initializes a common device context with default objects, attributes, and modes. Any drawing operations performed by the application use these defaults unless one of the GDI functions is called to select a new object, change the attributes of an existing object, or select a new mode.

Because only a limited number of common device contexts exist in the window manager's heap, an application should release these device contexts after it has finished drawing. An application releases a common device context by calling the ReleaseDC or EndPaint function. When the application releases a common device context, any changes to the default data are lost.

Private Device Contexts

Private device contexts are display device contexts that, unlike common device contexts, retain any changes to the default data — even after an application calls the ReleaseDC or EndPaint function. Private device contexts are not part of the window manager's cache and therefore need not be released after use. The window manager automatically removes a private device context after the last window of that class has been destroyed.

An application creates a private device context by first specifying the CS_OWNDC window-class style when it initializes the style member of the WNDCLASS structure and calls the RegisterClass function. (For more information about window classes, see Chapter 3, »Window Classes«.) After creating a window with the CS_OWNDC style, an application can call the GetDC, GetDCEx, or BeginPaint function once to obtain a handle identifying a private device context. The application can continue using this handle (and the associated device context) until it deletes the window created with this class. Any changes to graphic objects and their attributes, or graphic modes are retained by Windows until the window is deleted.


  28.1.3.2  Printer Device Contexts

Windows provides a single type of printer device context that can be used when printing on a dot-matrix printer, ink-jet printer, laser printer, or plotter. An application creates a printer device context by calling the CreateDC function and supplying the appropriate arguments (the name of the printer driver, the name of the printer, the file or device name for the physical output medium, and other initialization data). When an application has finished printing, it deletes the printer device context by calling the DeleteDC function. An application must delete (rather than release) a printer device context, because the ReleaseDC function fails when an application attempts to use it to release a printer device context.


  28.1.3.3  Memory Device Contexts

Windows supports a memory device context that stores bitmapped images for a particular device. An application creates a memory device context by calling the CreateCompatibleDC function and supplying a handle that identifies a device context for a particular device. When Windows processes this call, it creates a bitmap having a color format compatible with the original device. Because the bitmap is compatible with the given device, a memory device context is also sometimes referred to as a compatible device context.

The original bitmap in a memory device context is simply a placeholder. Its dimensions are one pixel by one pixel. Before an application can begin drawing, it must select a bitmap with the appropriate width and height into the device context by calling the SelectObject function. Once the new bitmap is selected into the memory device context, an application can begin using the device context to store images. For more information about bitmaps and bitmap operations, see Chapter 29, »Bitmaps«.


  28.1.3.4  Information Device Contexts

Windows supports an information device context used to retrieve default device data. For example, an application can call the CreateIC function to create an information device context for a particular model of printer and then call the GetCurrentObject and GetObject functions to retrieve the default pen or brush attributes. Because Windows can retrieve device information without creating the structures normally associated with the other types of device contexts, an information device context involves far less overhead and is created significantly faster than any of the other types. After an application finishes retrieving data by using an information device context, it must call the DeleteDC function.


  28.1.4  Device Context Operations

An application can perform the following operations on a device context:

•	Enumerate existing graphic objects.

•	Select new graphic objects.

•	Delete existing graphic objects.

•	Save the current graphic objects, their attributes, and the graphic modes.

•	Restore previously saved graphic objects, their attributes, and the graphic modes.

In addition, an application can use a device context to determine how graphics output is translated, cancel lengthy drawing operations (begun by a thread in a multithreaded application), or reset a printer to a particular state.


  28.1.4.1  Operations on Graphic Objects

Once an application creates a display or printer device context, it can begin drawing on the associated device or, in the case of the memory device context, it can begin drawing on the bitmap stored in memory. However, before drawing begins and sometimes while drawing is in progress, it is often necessary to replace the default objects with new objects.

An application can examine a default object's attributes by calling the GetCurrentObject and GetObject functions. The GetCurrentObject function returns a handle identifying the current pen, brush, palette, bitmap, or font, and the GetObject function initializes a structure containing that object's attributes.

Some printers provide resident pens, brushes, and fonts that can be used to improve drawing speed in an application. Two functions can be used to enumerate these objects: EnumObjects and EnumFonts. If the application must enumerate resident pens or brushes, it can call the EnumObjects function to examine the corresponding attributes. If the application must enumerate resident fonts, it can call the EnumFonts function (which can also enumerate GDI fonts).

Once an application determines that a default object needs replacing, it creates a new object by calling one of the following creation functions.

Graphic object	Function
Bitmap	CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDiscardableBitmap, CreateDIBitmap
Brush	CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush
Color Palette	CreatePalette
Font	CreateFont, CreateFontIndirect
Pen	CreatePen, CreatePenIndirect, ExtCreatePen
Region	CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreatePolyPolygonRgn, CreateRectRgn, CreateRectRgnIndirect, CreateRoundRectRgn
Each of the functions returns a handle identifying a new object. After an application retrieves a handle, it must call the SelectObject function to replace the default object. However, the application should save the handle identifying the default object and use this handle to replace the new object when it is no longer needed. When the application finishes drawing with the new object, it must restore the default object by calling the SelectObject function and delete the new object by calling the DeleteObject function. Not deleting objects causes serious performance problems.


  28.1.4.2  Cancellation of Drawing Operations

When complex drawing applications perform lengthy graphic operations, they consume valuable system resources. By taking advantage of Win32 multitasking features, an application can use threads and the CancelDC function to manage these operations. For example, if the graphic operation performed by thread A is consuming needed resources, thread B can call the CancelDC function to halt that operation.


  28.1.4.3  Retrieving Device Data

Windows supports two functions, GetDeviceCaps and DeviceCapabilitiesEx, that applications can use to retrieve device data using a device context. GetDeviceCaps retrieves general device data for the following devices:

•	Raster displays

•	Dot-matrix printers

•	Ink-jet printers

•	Laser printers

•	Vector plotters

•	Raster cameras

The data includes the supported capabilities of the device, including device resolution (for video displays), color format (for video displays and color printers), number of graphic objects, raster capabilities, curve drawing, line drawing, polygon drawing, and text drawing. An application retrieves this data by supplying a handle identifying the appropriate device context as well as an index specifying the type of data the function retrieves.

The DeviceCapabilitiesEx function retrieves data specific to printers, including the number of available paper bins, the duplex capabilities of the printer, the resolutions supported by the printer, the maximum and minimum supported paper size, and so on. An application retrieves this data by supplying a handle identifying the appropriate printer device context as well as an index specifying the type of data that the function should retrieve.


  28.1.4.4  Saving, Restoring, and Resetting a Device Context

Windows supports three functions that an application can use to save, restore, and reset a device context: SaveDC, RestoreDC, and ResetDC. The SaveDC function records on a special GDI stack the current device context's graphic objects and their attributes, and graphic modes. A drawing application can call this function before a user begins drawing and save the application's original state — providing a "clean slate" for the user. To return to this original state, the application calls the RestoreDC function.

The ResetDC function is provided to reset printer device context data. An application calls this function to reset the paper orientation, paper size, output scaling factor, number of copies to be printed, paper source (or bin), duplex mode, and so on. Typically, an application calls this function after a user has changed one of the printer options and Windows has issued a WM_DEVMODECHANGE message.


  28.2  Using the Device Context Functions

This section contains examples that demonstrate how an application can perform the following tasks:

•	Obtain a display device context.

•	Create a printer device context.

•	Retrieve the capabilities of a printer.

•	Retrieve graphic-object attributes.

•	Select a new graphic object.


  28.2.1  Obtaining a Private Display Device Context

An application performing numerous drawing operations in the client area of its window must use a private display device context. To create this type of device context, the application must specify the CS_OWNDC constant for the style member of the WNDCLASS structure when registering the window class. After registering the window class, the application obtains a handle identifying a private display device context by calling the GetDC function.

The following example shows how to create a private display device context.

#include <windows.h> /* required for all Windows-based applications */

#include <stdio.h>

#include <string.h>  /* strtok                                      */

#include "dc.h"      /* specific to this program                    */

/* Function prototypes */

BOOL InitApplication(HINSTANCE);

long FAR PASCAL MainWndProc(HWND, UINT, UINT, LONG);

/* Global variables */

HINSTANCE hinst;             /* handle of current instance        */

HDC hdc;                     /* display device context handle     */

    .

    .

    .

BOOL InitApplication(HINSTANCE hinstance)

{

    WNDCLASS  wc;

    /*

     * Fill in the window class structure with parameters describing

     * the main window.

     */

    wc.style = CS_OWNDC;                 /* Private-DC constant */

    wc.lpfnWndProc = (WNDPROC) MainWndProc;

    wc.cbClsExtra = 0;

    wc.cbWndExtra = 0;

    wc.hInstance = hinstance;

    wc.hIcon = LoadIcon((HINSTANCE) NULL,

        MAKEINTRESOURCE(IDI_APPLICATION));

    wc.hCursor = LoadCursor((HINSTANCE) NULL,

        MAKEINTRESOURCE(IDC_ARROW));

    wc.hbrBackground = GetStockObject(WHITE_BRUSH);

    wc.lpszMenuName =  "GenericMenu";

    wc.lpszClassName = "GenericWClass";

    /* Register the window class and return the resultant code. */

    return RegisterClass(&wc);

}

LRESULT APIENTRY MainWndProc(

        HWND hwnd,                /* window handle          */

        UINT message,             /* type of message        */

        WPARAM wParam,            /* additional information */

        LPARAM lParam)            /* additional information */

{

PAINTSTRUCT ps;             /* paint structure              */

    /* Retrieve a handle identifying the private display DC.*/

    hdc = GetDC(hwnd);

    switch (message) {

        case WM_PAINT:

              BeginPaint(hwnd, &ps);

        .

        . /* Perform drawing and painting using private DC. */

        .


  28.2.2  Creating a Printer Device Context

An application can create a printer device context in one of two ways:

•	Calling the PrintDlg function to display a common dialog box that allows the user to specify printer options; then creating a printer device context by using those options.

•	Creating a printer device context by using the default printer data from the WIN.INI file.

This section contains code demonstrating the latter method.

To use the default printer, retrieve and parse the appropriate string from the WIN.INI file. This string is retrieved by calling the GetProfileString function and specifying the appropriate section and entry names. In the case of the default printer, this data is stored in the [windows] section and identified by the entry named device. The sixth line in the following excerpt from a WIN.INI file shows an entry for a Kodak® Diconix (™)  printer.

[windows]

    load=

    run=

    Beep=yes

    Spooler=yes

    NullPort=None

    device=Diconix,winspool,LPT1:

    CoolSwitch=1

    BorderWidth=3

    KeyboardSpeed=31

    InitialKeyboardIndicators=2

    CursorBlinkRate=530

    DoubleClickSpeed=686

    Programs=com exe bat pif cmd

    Documents=

    DeviceNotSelectedTimeout=15

    TransmissionRetryTimeout=45

    swapdisk=

    NetWarn=1

    fPromptOnVerbose=FALSE

    fPromptOnWarning=FALSE

    fPromptOnError=TRUE

    fPrintVerbose=FALSE

    fPrintFileLine=FALSE

    shell=

    ScreenSaveTimeOut=300

    ScreenSaveActive=0

    DebugOptions=2048

The following example shows how a printer device context was created by using the data from WIN.INI.

HDC hdcPrint;               /* printer device context handle        */

char szDevString[120];      /* array that receives WIN.INI data     */

char *szPrinter, *szDriver; /* pointers to printer and driver names */

char *szPort;               /* pointer to port name                 */

    .

    .

    .

    /*

     * Retrieve the printer, printer-driver, and

     * output-port names from WIN.INI.

     */

    GetProfileString("windows", "device", ",,,",

        szDevString, 120);

    /*

     * Parse the string of names, setting ptrs

     * as required. If the string contains the

     * required names, use them to create a

     * device context.

     */

    if ((szPrinter = strtok(szDevString,

               (const char *) ","))

            && (szDriver = strtok ((char *) NULL,

               (const char *) ", "))

            && (szPort = strtok ((char *) NULL,

               (const char *) ", ")))

        hdcPrint = CreateDC(szDriver, szPrinter,

            szPort, NULL);

    /*

     * Print a test page that contains the string

     * "PRINTER TEST" in the upper left corner.

     */

    Escape(hdcPrint, STARTDOC, 8, "Test-Doc", NULL);

    TextOut(hdcPrint, 50, 50, "PRINTER TEST", 12);

    Escape(hdcPrint, NEWFRAME, 0, NULL, NULL);

    Escape(hdcPrint, ENDDOC, 0, NULL, NULL);

    /* Delete the printer DC. */

     DeleteDC(hdcPrint);


  28.2.3  Retrieving the Capabilities of a Printer

Not every output device supports the entire set of Win32 graphics functions. For example, because of hardware limitations, most vector plotters do not support bit-block transfers. An application can determine whether a device supports a particular Win32 graphics function by calling the GetDeviceCaps function, specifying the appropriate index, and examining the return value.

The following example shows how an application tests a printer to determine whether it supports bit-block transfers.

/*

 * Examine the raster capabilities of the device

 * identified by hdcPrint to verify that it supports

 * the BitBlt function.

 */

if ((GetDeviceCaps(hdcPrint, RASTERCAPS)

       & RC_BITBLT) == 0) {

    DeleteDC(hdcPrint);

    break;

}

else

 .

 . /* Print the bitmap using the printer DC. */

 .


  28.2.4  Retrieving Graphic-Object Attributes and Selecting New Graphic Objects

An application can retrieve the attributes for a pen, brush, palette, font, or bitmap by calling the GetCurrentObject and GetObject functions. The GetCurrentObject function returns a handle identifying the object currently selected into the device context; the GetObject function returns a structure that describes the object's attributes.

The following example shows how an application can retrieve the current brush attributes and use the retrieved data to determine whether it is necessary to select a new brush.

HDC hdc;                     /* display device context handle         */

HBRUSH hbrushNew, hbrushOld; /* brush handles                         */

HBRUSH hbrush;               /* brush handle                          */

LOGBRUSH lb;                 /* logical-brush structure               */

    /*

     * Retrieve a handle identifying the current brush.

     */

    hbrush = GetCurrentObject(hdc, OBJ_BRUSH);

    /*

     * Retrieve a LOGBRUSH structure that contains the

     * current brush attributes.

     */

    GetObject(hbrush, sizeof(LOGBRUSH), &lb);

    /*

     * If the current brush is not a solid-black brush,

     * replace it with the solid-black stock brush.

     */

     if ((lb.lbStyle != BS_SOLID)

            || (lb.lbColor != 0x000000)) {

         hbrushNew = GetStockObject(BLACK_BRUSH);

         hbrushOld = SelectObject(hdc, hbrushNew);

     }

    .

    . /* Perform painting operations with the white brush. */

    .

    /*

     * After completing the last painting operation

     * with the new brush, the application should

     * select the original brush back into the

     * device context and delete the new brush.

     */

     SelectObject(hdc, hbrushOld);

     DeleteObject(hbrushNew);

Note that the application saved the original brush handle when calling the SelectObject function the first time. This handle is saved so that the original brush can be selected back into the device context after the last painting operation has been completed with the new brush. After the original brush is selected back into the device context, the new brush is deleted — freeing memory in the GDI heap.


  28.3  Functions and Message

Following are the functions and the message used with device contexts.


  Functions

CancelDC
CreateCompatibleDC
CreateDC
CreateIC
DeleteDC
DeleteObject
DeviceCapabilitiesEx
EnumObjects
EnumObjectsProc
GetCurrentObject
GetDC
GetDCEx
GetDCOrg
GetDeviceCaps
GetGraphicsMode
GetObject
GetObjectType
ReleaseDC
ResetDC
RestoreDC
SaveDC
SelectObject
SetGraphicsMode


  Message

WM_DEVMODECHANGE


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


29.1  About Bitmaps
  Chapter 29    Bitmaps

29.1  About Bitmaps

A bitmap is a powerful graphics object used to create, manipulate (scale, scroll, rotate, and paint), and store images as files on a disk.

A bitmap is one of seven objects that can be selected into a device context. The other six objects are the pen, brush, font, region, logical palette, and drawing surface. (For more information about device contexts and related objects, see Chapter 28, »Device Contexts«.)

In Microsoft® Windows (™) , Control Panel is an example of an application that uses bitmaps. When a user selects wallpaper for the desktop, the user actually selects a bitmap, which Windows uses to paint the desktop background.

»This illustration« shows a desktop painted with a red-brick wallpaper pattern:

Windows creates this pattern by repeatedly drawing a 32- by 32-pixel pattern on the desktop. This pattern is stored as a bitmap in the file REDBRICK.BMP.

From the user's point of view, a bitmap is a rectangle of pixels that form a visual image. However, from the developer's perspective, a bitmap is a collection of structures that specify or contain the following elements:

•	A header that describes the resolution of the device on which the rectangle of pixels was created, the dimensions of the rectangle, the size of the array of bits, and so on.

•	A logical palette.

•	An array of bits that define the relationship between pixels in the bitmapped image and entries in the logical palette.

The next illustration shows the developer's perspective of the bitmap found in the file REDBRICK.BMP. It shows a palette array, a 32- by 32-pixel rectangle, and the index array that maps colors from the palette to pixels in the rectangle.

Palette-index

row 0, scanline 31  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

row 1, scanline 30  00 00 00 00 00 00 00 00 09 00 00 00 00 00 00 00

row 2, scanline 29  11 11 01 19 11 01 10 10 09 09 01 09 11 11 01 90

    .

    .

    .

row 31, scanline 0  99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 90

Pixel rectangle	Color-palette
	0   Black  1   Dark red  2   Dark green  3   Dark yellow  4   Dark bule  5   Dark magenta  6   Dark cyan  7   Dark gray  8   Light gray  9   Light red  A   Light green  B   Light yellow  C   Light blue  D   Light magenta  E   Light cyan  F   White

In the preceding example, the rectangle of pixels was created on a VGA display device using a palette of 16 colors. A 16-color palette requires 4-bit indices; therefore, the array that maps palette colors to pixel colors is composed of 4-bit indices as well. (For more information about logical color-palettes, see Chapter 36, »Colors«.)

It is important to note that Windows maps indices to pixels beginning with the bottom scan line of the rectangular region and ending with the top scan line. (A scan line is a single row of adjacent pixels on a video display.) In the preceding example, the first row of the array (row 0) corresponds to the bottom row of pixels, scan line 31.


  29.1.1  Bitmap Types

There are two types of bitmaps: device-dependent (DDBs) and device-independent (DIBs). DDBs were common in early (pre-3.0) versions of Windows. In fact, they were the only bitmaps available to developers. However, as display technology improved and as the variety of display devices increased among Windows users, certain inherent problems surfaced. For example, there was no method of storing (or retrieving) the resolution of the display type on which a bitmap was created, so a drawing application could not quickly determine whether a bitmap was suitable for the type of video display device on which the application was running. To solve this problem, Microsoft created DIBs.


  29.1.1.1  Device-Independent Bitmaps

A DIB contains the following color and dimension information:

•	The color format of the device on which the rectangular image was created.

•	The resolution of the device on which the rectangular image was created.

•	The palette for the device on which the image was created.

•	An array of bits that maps red, green, blue (RGB) triplets to pixels in the rectangular image.

•	A data-compression identifier that indicates the data compression scheme (if any) used to reduce the size of the array of bits.

This information is stored in a BITMAPINFO structure consisting of a BITMAPINFOHEADER structure followed by two or more RGBQUAD structures. The BITMAPINFOHEADER specifies the dimensions of the pixel rectangle, describes the device's color technology, and identifies the compression schemes used to reduce the bitmap's size. The RGBQUAD structures identify the colors that appear in the pixel rectangle.

The color format is specified in terms of a count of color planes and color bits. The count of color planes is always 1; the count of color bits is 1 for monochrome bitmaps, 4 for VGA bitmaps, and 8, 16, 24, or 32 for bitmaps on other color devices. An application retrieves the number of color bits a particular display (or printer) uses by calling the GetDeviceCaps function, specifying BITSPIXEL as the second argument.

The resolution of a display device is specified in pixels per meter. An application can retrieve the horizontal resolution for a video display, or printer, by following a three-step process:

1.	Call the GetDeviceCaps function, specifying HORZRES as the second argument.

2.	Call GetDeviceCaps a second time, specifying HORZSIZE as the second argument.

3.	Divide the first return value by the second return value.

The application can retrieve the vertical resolution by using the same three-step process with different parameters: VERTRES in place of HORZRES, and VERTSIZE in place of HORZSIZE.

The palette is represented by an array of RGBQUAD structures that specify the red, green, and blue intensity components for each color in a display device's color palette. Each color index in the palette array maps to a specific pixel in the rectangular region associated with the bitmap. The size of this array, in bits, is equivalent to the width of the rectangle, in pixels, multiplied by the height of the rectangle, in pixels, multiplied by the count of color bits for the device. An application can retrieve the size of the device's palette by calling the GetDeviceCaps function, specifying the NUMCOLORS constant as the second argument.

Windows supports the compression of the palette array for 8-bit-per-pixel and 4-bit-per-pixel DIBs. These arrays can be compressed by using the run-length encoding (RLE) scheme. The RLE scheme uses 2-byte values, the first byte specifying the number of consecutive pixels that use a color index and the second byte specifying the index. For more information about bitmap compression, see the description of the BITMAPINFOHEADER structure.

An application can create a DIB by initializing the required structures and calling the CreateDIBitmap function. Then it can initialize the array of indices by calling the SetDIBits function. To determine whether a device supports this function, call the GetDeviceCaps function, specifying RC_DI_BITMAP as the RASTERCAPS flag.

An application can use a DIB to set pixels on the display device by calling the SetDIBitsToDevice or the BitBlt function. To determine whether a device supports the SetDIBitsToDevice function, call the GetDeviceCaps function, specifying RC_DIBTODEV as the RASTERCAPS flag.

An application that simply needs to display a preexisting DIB can use the SetDIBitsToDevice function. For example, a spreadsheet application can open existing charts and display them in a window by using the SetDIBitsToDevice function. To repeatedly redraw a bitmap in a window, however, the application should use the BitBlt function. For example, a multimedia application that combines animated graphics with sound would benefit from calling the BitBlt function because it executes faster than SetDIBitsToDevice.


  29.1.1.2  Device-Dependent Bitmaps

Device-dependent bitmaps are supported only for compatibility with applications written for Windows versions earlier than 3.0. A developer writing a new application or porting an application written for a previous version of Windows to the Win32 platform should use DIBs.

DDBs are described by using a single structure, the BITMAP structure. The members of this structure specify the width and height of a rectangular region, in pixels; the width of the array that maps entries from the device palette to pixels; and the device's color format, in terms of color planes and bits per pixel. An application can retrieve the color format of a device by calling the GetDeviceCaps function and specifying the appropriate constants.

There are two types of DDBs: discardable and nondiscardable. A discardable DDB is a bitmap that Windows discards if the bitmap is not selected into a DC and if system memory is low. The CreateDiscardableBitmap function creates discardable bitmaps. The CreateBitmap, CreateCompatibleBitmap, and CreateBitmapIndirect functions create nondiscardable bitmaps.


  29.1.2  Bitmaps, Device Contexts, and Drawing Surfaces

A device context (DC) is a data structure defining the graphics objects, their associated attributes, and the graphics modes affecting output on a device. An application creates a DC by calling the CreateDC function; it retrieves a window manager device context by calling the GetDC function.


  29.1.2.1  The Drawing Surface

Before returning a handle that identifies that DC, the window manager selects a drawing surface into the DC. If the application called the CreateDC function to create a device context for a VGA display, the dimensions of this drawing surface are 640- by 480-pixels. If the application called the GetDC function, the dimensions reflect the size of the client area.

When an application passes the handle returned by CreateDC or GetDC to one of the graphics device interface (GDI) drawing functions, the requested output appears on the drawing surface selected into the device context.


  29.1.2.2  Compatible Device Contexts

To enable applications to place output in memory rather than sending it to an actual device, Windows provides a special device context for bitmap operations called a compatible device context. A compatible DC enables Windows to treat a portion of memory as a virtual device. It is an array of bits in memory that an application can use to temporarily store the color data for bitmaps created on a normal drawing surface.

An application creates a compatible DC by calling the CreateCompatibleDC function and receives a handle that identifies a normal device context. Windows creates a temporary 1-bit placeholder for the array. Before performing drawing operations using the compatible DC handle, the application must increase the size of this array. To do this, the application can call the CreateBitmap, CreateBitmapIndirect, or CreateCompatibleBitmap function to create a bitmap of the appropriate dimensions and then call the SelectObject function to select the bitmap into the DC. After the bitmap is selected into the compatible DC, Windows replaces the single-bit array with an array large enough to store color information for the specified rectangle of pixels.

When an application passes the handle returned by CreateCompatibleDC to one of the GDI drawing functions, the requested output does not appear on a device's drawing surface. Instead, Windows stores the color information for the resultant line, curve, text or region in the array of bits. The application can copy the image stored in memory back onto a drawing surface by calling the BitBlt function, identifying the compatible DC as the source device context and a window or screen DC as the target device context.


  29.1.3  Bitmap Rotation

Windows provides a function to copy a bitmap into a parallelogram; this function, PlgBlt, performs a bit-block transfer from a rectangle in a source device context into a parallelogram in a destination device context. In order to rotate the bitmap, an application must provide the coordinates, in world units, to be used for the corners of the parallelogram. (For more information about rotation and world units see Chapter 39, »Coordinate Spaces and Transformations«.)


  29.1.4  Bitmap Scaling

Windows also provides a function to scale a bitmap; this function, StretchBlt, performs a bit-block transfer from a rectangle in a source device context into a rectangle in a destination device context. However, unlike the BitBlt function, which duplicates the source rectangle dimensions in the destination rectangle, StretchBlt allows an application to specify the dimensions of both the source and the destination rectangles. When the destination bitmap is smaller than the source bitmap, Windows combines rows or columns of color data (or both) in the bitmap before rendering the corresponding image on the display device. Windows combines the color data according to the specified stretch mode, which the application defines by calling the SetStretchBltMode function. When the destination bitmap is larger than the source bitmap, Windows scales or magnifies each pixel in the resultant image accordingly.

»This illustration« shows the client area of an application that captures the entire contents of the desktop and then stores the corresponding color data in a bitmap. The window on the left displays the original bitmap; the window on the right displays the bitmap after it was scaled to twice its original size.


  29.1.5  Bitmaps as Brushes

Windows provides a number of functions that use the brush currently selected into a device context to perform bitmap operations. For example, the PatBlt function replicates the brush in a rectangular region within a window, and the FloodFill function replicates the brush inside an area in a window bounded by the specified color (unlike PatBlt, FloodFill does fill nonrectangular shapes).

The PatBlt function name (an abbreviation for pattern block transfer) implies that the function simply replicates the brush (or pattern) until it fills a specified rectangle. However, the function is actually much more powerful. Before replicating the brush, it combines the color data for the pattern with the color data for the existing pixels on the video display by using a raster operation (ROP). An ROP is a bitwise operation that is applied to the bits of color data for the replicated brush and the bits of color data for the target rectangle on the display device. There are 256 ROPs in Windows; however, the PatBlt function recognizes only those that require a pattern and a destination (not those that require a source). The following table identifies the five most common ROPs.

ROP	Description
PATCOPY	Copies the pattern to the destination bitmap.
PATINVERT	Combines the destination bitmap with the pattern by using the Boolean OR operator.
DSTINVERT	Inverts the destination bitmap.
BLACKNESS	Turns all output to binary zeroes.
WHITENESS	Turns all output to binary ones.
The FloodFill function replicates the brush within a region bounded by a specified color. However, unlike the PatBlt function, FloodFill does not combine the color data for the brush with the color data for the pixels on the display; it simply sets the color of all pixels within the enclosed region on the display to the color of the brush that is currently selected into the device context.

»This illustration« shows the result of calling the FloodFill function in the Windows Paintbrush application to paint the interior of a nonrectangular region. The window on the left shows the region before FloodFill was called; the window on the right shows the region after the call was made.


  29.1.6  Bitmap Storage

Bitmaps should be saved in a file that uses the established Windows format and assigned a name with the three-character .BMP extension. The Windows format is shown in »this illustration«.

The members of the BITMAPFILEHEADER structure identify the file; specify the size of the file, in bytes; and specify the offset from the first byte in the header to the first byte of bitmap data. The members of the BITMAPINFOHEADER structure specify the bitmap's width and height, in pixels; the color format (count of color planes and color bits per pixel) of the display device on which the bitmap was created; whether the bitmap data was compressed before storage and the type of compression used; the number of bytes of bitmap data; the resolution of the display device on which the bitmap was created; and the number of colors represented in the data. The RGBQUAD structures specify the RGB intensity values for each of the colors in the device's palette. The color-index array maps indices values from the RGBQUAD array to pixels in a rectangular region on the display.

The following hexadecimal output shows the contents of the file REDBRICK.BMP.

0000    42 4d 76 02 00 00 00 00  00 00 76 00 00 00 28 00

0010    00 00 20 00 00 00 20 00  00 00 01 00 04 00 00 00

0020    00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

0030    00 00 00 00 00 00 00 00  00 00 00 00 80 00 00 80

0040    00 00 00 80 80 00 80 00  00 00 80 00 80 00 80 80

0050    00 00 80 80 80 00 c0 c0  c0 00 00 00 ff 00 00 ff

0060    00 00 00 ff ff 00 ff 00  00 00 ff 00 ff 00 ff ff

0070    00 00 ff ff ff 00 00 00  00 00 00 00 00 00 00 00

0080    00 00 00 00 00 00 00 00  00 00 00 00 00 00 09 00

0090    00 00 00 00 00 00 11 11  01 19 11 01 10 10 09 09

00a0    01 09 11 11 01 90 11 01  19 09 09 91 11 10 09 11

00b0    09 11 19 10 90 11 19 01  19 19 10 10 11 10 09 01

00c0    91 10 91 09 10 10 90 99  11 11 11 11 19 00 09 01

00d0    91 01 01 19 00 99 11 10  11 91 99 11 09 90 09 91

00e0    01 11 11 11 91 10 09 19  01 00 11 90 91 10 09 01

00f0    11 99 10 01 11 11 91 11  11 19 10 11 99 10 09 10

0100    01 11 11 11 19 10 11 09  09 10 19 10 10 10 09 01

0110    11 19 00 01 10 19 10 11  11 01 99 01 11 90 09 19

0120    11 91 11 91 01 11 19 10  99 00 01 19 09 10 09 19

0130    10 91 11 01 11 11 91 01  91 19 11 00 99 90 09 01

0140    01 99 19 01 91 10 19 91  91 09 11 99 11 10 09 91

0150    11 10 11 91 99 10 90 11  01 11 11 19 11 90 09 11

0160    00 19 10 11 01 11 99 99  99 99 99 99 99 99 09 99

0170    99 99 99 99 99 99 00 00  00 00 00 00 00 00 00 00

0180    00 00 00 00 00 00 90 00  00 00 00 00 00 00 00 00

0190    00 00 00 00 00 00 99 11  11 11 19 10 19 19 11 09

01a0    10 90 91 90 91 00 91 19  19 09 01 10 09 01 11 11

01b0    91 11 11 11 10 00 91 11  01 19 10 11 10 01 01 11

01c0    90 11 11 11 91 00 99 09  19 10 11 90 09 90 91 01

01d0    19 09 91 11 01 00 90 10  19 11 00 11 11 00 10 11

01e0    01 10 11 19 11 00 90 19  10 91 01 90 19 99 00 11

01f0    91 01 11 01 91 00 99 09  09 01 10 11 91 01 10 91

0200    99 11 10 90 91 00 91 11  00 10 11 01 10 19 19 09

0210    10 00 99 01 01 00 91 01  19 91 19 91 11 09 10 11

0220    00 91 00 10 90 00 99 01  11 10 09 10 10 19 09 01

0230    91 90 11 09 11 00 90 99  11 11 11 90 19 01 19 01

0240    91 01 01 19 09 00 91 10  11 91 99 09 09 90 11 91

0250    01 19 11 11 91 00 91 19  01 00 11 00 91 10 11 01

0260    11 11 10 01 11 00 99 99  99 99 99 99 99 99 99 99

0270    99 99 99 99 99 90

The following table shows the data bytes associated with the structures in a bitmap file.

Structure	Corresponding bytes
BITMAPFILEHEADER	0x00 − 0x0D
BITMAPINFOHEADER	0x0E − 0x31
RGBQUAD array	0x32 − 0x75
Color-index array	0x76 − 0x275


  29.2  Using Bitmaps

This section explains how to perform the following tasks:

•	Capture an image

•	Scale an image

•	Store an image permanently


  29.2.1  Capturing an Image

You can use a bitmap to capture an image, and you can store the captured image in memory, display it at a different location in your application's window, or display it in another window.

In some cases, you may want your application to capture images and store them only temporarily. For example, when you scale or "zoom" a picture created in a drawing application, the application must temporarily save the normal view of the image and display the zoomed view. Later, when the user selects the normal view, the application must replace the zoomed image with a copy of the normal view that it temporarily saved.

If your application must store an image temporarily, you must create a DC that is compatible with the current window DC. You do this by calling the CreateCompatibleDC function. After you create a compatible DC, you create a bitmap with the appropriate dimensions by calling the CreateCompatibleBitmap function and then select it into this device context by calling the SelectObject function.

After the compatible device context is created and the appropriate bitmap has been selected into it, you can capture the image. Windows provides the BitBlt function to capture images. This function performs a bit block transfer — that is, it copies data from a source bitmap into a destination bitmap. Because it copies data from bitmaps, you'd expect that two arguments to this function would be bitmap handles; however, this is not the case. Instead, the BitBlt function receives handles that identify two device contexts and copies the bitmap data from a bitmap selected into the source DC into a bitmap selected into the target DC. In this case, the target DC is the compatible DC, so when the BitBlt function completes the transfer, the image has been stored in memory. To redisplay the image, call the BitBlt function a second time, specifying the compatible device context as the source DC and a window (or printer) device context as the target DC.

The following example code, from an application that captures an image of the entire desktop, creates a compatible device context and a bitmap with the appropriate dimensions, selects the bitmap into the compatible DC, and then copies the image using the BitBlt function.

/*

 * Create a normal DC and a memory DC for the entire screen. The

 * normal DC provides a "snapshot" of the screen contents. The

 * memory DC keeps a copy of this "snapshot" in the associated

 * bitmap.

 */

hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);

hdcCompatible = CreateCompatibleDC(hdcScreen);

/* Create a compatible bitmap for hdcScreen. */

hbmScreen = CreateCompatibleBitmap(hdcScreen,

                     GetDeviceCaps(hdcScreen, HORZRES),

                     GetDeviceCaps(hdcScreen, VERTRES));

if (hbmScreen == 0)

    errhandler("hbmScreen", hwnd);

/* Select the bitmaps into the compatible DC. */

if (!SelectObject(hdcCompatible, hbmScreen))

    errhandler("Compatible Bitmap Selection", hwnd);

        /* Hide the application window. */

        ShowWindow(hwnd, SW_HIDE);

        /*

         * Copy color data for the entire display into a

         * bitmap that is selected into a compatible DC.

         */

        if (!BitBlt(hdcCompatible,

               0,0,

               bmp.bmWidth, bmp.bmHeight,

               hdcScreen,

               0,0,

               SRCCOPY))

        errhandler("Screen to Compat Blt Failed", hwnd);

        /* Redraw the application window. */

        ShowWindow(hwnd, SW_SHOW);


  29.2.2  Scaling an Image

Some applications scale images — that is, they display zoomed or reduced views of an image. For example, a drawing application may provide a zoom feature that enables the user to view and edit a drawing on a pixel-by-pixel basis.

Applications scale images by calling the StretchBlt function. Like the BitBlt function, StretchBlt copies bitmap data from a bitmap in a source DC into a bitmap in a target DC. However, unlike the BitBlt function, StretchBlt scales the image based on the specified dimensions of the source and target rectangles. If the source rectangle is larger than the target rectangle, the resultant image will appear to have shrunk; if the source rectangle is smaller than the target rectangle, the resultant image will appear to have expanded.

If the target rectangle is smaller than the source rectangle, StretchBlt removes color data from the image according to a specified stretch mode as shown in the following table.

Stretch Mode	Method
BLACKONWHITE	Performs a logical AND operation on the color data for the eliminated pixels and the color data for the remaining pixels.
WHITEONBLACK	Performs a logical OR operation on the color data for the eliminated pixels and the color data for the remaining pixels.
COLORONCOLOR	Eliminates the color data of the deleted pixels completely.
HALFTONE	Approximates the original (source) color data in the destination.
You set the stretch-mode by calling the SetStretchBltMode function.

The following example code is taken from an application that displays an image either at its original size or a twice the original size. (This application uses the default stretch mode.).

    hdcScaled = CreateCompatibleDC(hdcScreen);

    hbmScaled = CreateCompatibleBitmap(hdcScreen,

                    GetDeviceCaps(hdcScreen, HORZRES) * 2,

                    GetDeviceCaps(hdcScreen, VERTRES) * 2);

    if (hbmScaled == 0)

        errhandler("hbmScaled", hwnd);

    /* Select the bitmaps into the compatible DC. */

    if (!SelectObject(hdcScaled, hbmScaled))

        errhandler("Scaled Bitmap Selection", hwnd);

case WM_COMMAND: /* message: command from application menu */

    switch(wParam) {

        case IDM_SCALEX1:

            if (fBlt){

                 fScaled = FALSE;

                 hdcWin = GetDC(hwnd);

                 BitBlt(hdcWin,

                    0,0,

                    bmp.bmWidth, bmp.bmHeight,

                    hdcCompatible,

                    0,0,

                    SRCCOPY);

                 ReleaseDC(hwnd, hdcWin);

            }

            break;

        case IDM_SCALEX2:

            if (fBlt){

                 fScaled = TRUE;

                 StretchBlt(hdcScaled,

                     0, 0,

                     bmp.bmWidth * 2, bmp.bmHeight * 2,

                     hdcCompatible,

                     0, 0,

                     bmp.bmWidth, bmp.bmHeight,

                     SRCCOPY);

                 hdcWin = GetDC(hwnd);

                 BitBlt(hdcWin,

                    0,0,

                    bmp.bmWidth, bmp.bmHeight,

                    hdcScaled,

                    0,0,

                    SRCCOPY);

                 ReleaseDC(hwnd, hdcWin);

            }

            break;


  29.2.3  Storing an Image

Many applications store images permanently as files. For example, drawing applications store pictures, spreadsheet applications store charts, CAD applications store drawings, and so on.

If you are writing an application that will store a bitmapped image in a file, you should use the Windows file format described in Section 29.1.6, "Bitmap Storage." In order to store a bitmap in this format, you must initialize a BITMAPINFO structure (consisting of a BITMAPFILEHEADER structure and an array of RGBQUAD structures), as well as an array of palette indices.

The following example code defines a function that allocates memory for and initializes members within a BITMAPINFOHEADER data structure.

PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp) {

    BITMAP bmp;

    PBITMAPINFO pbmi;

    WORD    cClrBits;

    /* Retrieve the bitmap's color format, width, and height. */

    if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))

        errhandler("GetObject", hwnd);

    /* Convert the color format to a count of bits. */

    cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);

    if (cClrBits == 1)

        cClrBits = 1;

    else if (cClrBits <= 4)

        cClrBits = 4;

    else if (cClrBits <= 8)

        cClrBits = 8;

    else if (cClrBits <= 16)

        cClrBits = 16;

    else if (cClrBits <= 24)

        cClrBits = 24;

    else

        cClrBits = 32;

    /*

     * Allocate memory for the BITMAPINFO structure. (This structure

     * contains a BITMAPINFOHEADER structure and an array of RGBQUAD

     * data structures.)

     */

    if (cClrBits != 24)

         pbmi = (PBITMAPINFO) LocalAlloc(LPTR,

                    sizeof(BITMAPINFOHEADER) +

                    sizeof(RGBQUAD) * cClrBits);

    /*

     * There is no RGBQUAD array for the 24-bit-per-pixel format.

     */

    else

         pbmi = (PBITMAPINFO) LocalAlloc(LPTR,

                    sizeof(BITMAPINFOHEADER));

    /* Initialize the fields in the BITMAPINFO structure. */

    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    pbmi->bmiHeader.biWidth = bmp.bmWidth;

    pbmi->bmiHeader.biHeight = bmp.bmHeight;

    pbmi->bmiHeader.biPlanes = bmp.bmPlanes;

    pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;

    /* If the bitmap is not compressed, set the BI_RGB flag. */

    pbmi->bmiHeader.biCompression = BI_RGB;

    /*

     * Compute the number of bytes in the array of color

     * indices and store the result in biSizeImage.

     */

    pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8

                                  * pbmi->bmiHeader.biHeight

                                  * cClrBits;

    /*

     * Set biClrImportant to 0, indicating that all of the

     * device colors are important.

     */

    pbmi->bmiHeader.biClrImportant = 0;

    return pbmi;

}

The following example code defines a function that initializes the remaining structures, retrieves the array of palette indices, opens the file, copies the data, and closes the file.

void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,

                  HBITMAP hBMP, HDC hDC)

 {

    HANDLE hf;                  /* file handle                */

    BITMAPFILEHEADER hdr;       /* bitmap file-header         */

    PBITMAPINFOHEADER pbih;     /* bitmap info-header         */

    HANDLE hmem;                /* memory handle              */

    LPBYTE lpBits;              /* memory pointer             */

    DWORD dwTotal;              /* total count of bytes       */

    DWORD cb;                   /* incremental count of bytes */

    BYTE *hp;                   /* byte pointer               */

    DWORD dwTmp;

    pbih = (PBITMAPINFOHEADER) pbi;

    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

    if (!lpBits)

         errhandler("GlobalAlloc", hwnd);

    /*

     * Retrieve the color table (RGBQUAD array) and the bits

     * (array of palette indices) from the DIB.

     */

    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight,

                   lpBits, pbi, DIB_RGB_COLORS))

        errhandler("GetDIBits", hwnd);

    /* Create the .BMP file. */

    hf = CreateFile(pszFile,

                   GENERIC_READ | GENERIC_WRITE,

                   (DWORD) 0,

                   (LPSECURITY_ATTRIBUTES) NULL,

                   CREATE_ALWAYS,

                   FILE_ATTRIBUTE_NORMAL,

                   (HANDLE) NULL);

    if (hf == INVALID_HANDLE_VALUE)

        errhandler("CreateFile", hwnd);

    hdr.bfType = 0x4d42;        /* 0x42 = "B" 0x4d = "M" */

    /* Compute the size of the entire file. */

    hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +

                 pbih->biSize + pbih->biClrImportant

                 * sizeof(RGBQUAD) + pbih->biSizeImage);

    hdr.bfReserved1 = 0;

    hdr.bfReserved2 = 0;

    /* Compute the offset to the array of color indices. */

    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +

                    pbih->biSize + pbih->biClrImportant

                    * sizeof (RGBQUAD);

    /* Copy the BITMAPFILEHEADER into the .BMP file. */

    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),

       (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))

       errhandler("WriteFile", hwnd);

    /* Copy the BITMAPINFOHEADER and RGBQUAD array into the file. */

    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)

                  + pbih->biClrImportant * sizeof (RGBQUAD),

                  (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))

       errhandler("WriteFile", hwnd);

    /* Copy the array of color indices into the .BMP file. */

    dwTotal = cb = pbih->biSizeImage;

    hp = lpBits;

    while (cb > MAXWRITE)  {

            if (!WriteFile(hf, (LPSTR) hp, (int) MAXWRITE,

                          (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))

                errhandler("WriteFile", hwnd);

            cb-= MAXWRITE;

            hp += MAXWRITE;

    }

    if (!WriteFile(hf, (LPSTR) hp, (int) cb,

         (LPDWORD) &dwTmp, (LPOVERLAPPED) NULL))

           errhandler("WriteFile", hwnd);

    /* Close the .BMP file. */

    if (!CloseHandle(hf))

           errhandler("CloseHandle", hwnd);

    /* Unlock and free memory. */

    GlobalUnlock(hmem);

    GlobalFree(hmem);

}


  29.3  Functions

Following are the functions used with bitmaps.

BitBlt
CreateBitmap
CreateBitmapIndirect
CreateCompatibleBitmap
CreateDiscardableBitmap
CreateDIBitmap
CreateDIBSection
ExtFloodFill
FloodFill
GetBitmapBits
GetBitmapDimensionEx
GetDIBits
GetPixel
GetStretchBltMode
LoadBitmap
MaskBlt
PatBlt
PlgBlt
SetBitmapBits
SetBitmapDimensionEx
SetDIBits
SetDIBitsToDevice
SetPixel
SetPixelV
StretchBlt
StretchDIBits
SetStretchBltMode


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


30.1  About Brushes
  Chapter 30    Brushes

30.1  About Brushes

A brush is a graphics tool that an application written for Microsoft® Windows (™)  uses to paint the interior of polygons, ellipses, and paths. Drawing applications use brushes to paint shapes; word processing applications use brushes to paint rules; computer-aided design (CAD) applications use brushes to paint the interiors of cross-section views; and spreadsheet applications use brushes to paint the sections of pie charts and the bars in bar graphs.

There are two types of brushes: logical and physical. A logical brush is a description of the ideal bitmap that an application would use to paint shapes. A physical brush is the actual bitmap that a device driver creates based on an application's logical-brush definition. For more information about bitmaps, see Chapter 29, »Bitmaps«.

When an application calls one of the functions that create a brush, it retrieves a handle that identifies a logical brush. When the application passes this handle to the SelectObject function, the device driver for the corresponding display or printer creates the physical brush.


  30.1.1  Brush Origin

When an application calls a drawing function to paint a shape, Windows positions a brush at the start of the paint operation and maps a pixel in the brush bitmap to the window origin of the client area. (The window origin is the upper-left corner of the  window's client area.) The coordinates of the pixel that Windows maps are called the brush origin. The default brush origin is located in the upper-left corner of the brush bitmap, at the coordinates (0,0). Windows then copies the brush across the client area, forming a pattern that is as tall as the bitmap. The copy operation continues, row by row, until the entire client area is filled. However, the brush pattern is visible only within the boundaries of the specified shape.

There are instances when the default brush origin should not be used. For example, it may be necessary for an application to use the same brush to paint the backgrounds of its parent and child windows and blend a child window's background with that of the parent window. To do this, the application should reset the brush origin by calling the SetBrushOrgEx function and shifting the origin the required number of pixels. (An application can retrieve the current brush origin by calling the GetBrushOrgEx function.)

»This illustration« shows a five-pointed star filled by using an application-defined brush. The illustration shows a zoomed image of the brush, as well as the location to which it was mapped at the beginning of the paint operation.


  30.1.2  Logical Brush Types

There are four types of logical brushes (solid, stock, hatch, and pattern) as shown in »this illustration«.

The stock and hatch types each have several predefined brushes, as described in Section 30.1.2.3, "Hatch Brush."


  30.1.2.1  Solid Brush

A solid brush is a logical brush that contains 64 pixels of the same color. An application can create a solid logical brush by calling the CreateSolidBrush function, specifying the color of the brush required. After creating the solid brush, the application can select it into its device context and use it to paint filled shapes.


  30.1.2.2  Stock Brush

There are seven predefined logical stock brushes maintained by the graphics device interface (GDI). The rectangles in »this illustration« were painted by using the seven predefined stock brushes.

An application can retrieve a handle identifying one of the seven stock brushes by calling the GetStockObject function, specifying the brush type.


  30.1.2.3  Hatch Brush

There are six predefined logical hatch brushes maintained by GDI. The rectangles in »this illustration«were painted by using the six predefined hatch brushes.

An application can create a hatch brush by calling the CreateHatchBrush function, specifying one of the six hatch styles.


  30.1.2.4  Pattern Brush

A pattern (or custom) brush is created from an application-defined bitmap or device-independent bitmap (DIB). The rectangles in »this illustration« were painted by using different pattern brushes.

To create a logical pattern brush, an application must first create a bitmap. After creating the bitmap, the application can create the logical pattern brush by calling the CreatePatternBrush or CreateDIBPatternBrush function, supplying a handle that identifies the bitmap (or DIB). The brushes that appear in the preceding illustration were created from monochrome bitmaps. For a description of bitmaps, DIBs, and the functions that create them, see Chapter 29, »Bitmaps«.


  30.2  Using Brushes

You can use a brush to paint the interior of virtually any shape by using a GDI function. This includes the interiors of rectangles, ellipses, polygons, and paths. Depending on the requirements of your application, you can use a solid brush of a specified color, a stock brush, a hatch brush, or a pattern brush.

This section contains code samples that demonstrate the creation of a custom brush dialog box. The dialog box contains a grid that represents the bitmap Windows uses as a brush. A user can use this grid to create a pattern-brush bitmap and then view the custom pattern by clicking the Test Pattern button.

»This illustration« shows a pattern created by using the Custom Brush dialog box.

To display a dialog box, you must first create a dialog box template. The following dialog box template defines the Custom Brush dialog box.

CustBrush DIALOG 6, 18, 160, 118

STYLE WS_DLGFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION

CAPTION "Custom Brush"

FONT 8, "MS Sans Serif"

BEGIN

    CONTROL         "", IDD_GRID, "Static", SS_BLACKFRAME |

                    WS_CHILD, 3, 2, 83, 79

    CONTROL         "", IDD_RECT, "Static", SS_BLACKFRAME |

                    WS_CHILD, 96, 11, 57, 28

    PUSHBUTTON      "Test Pattern", IDD_PAINTRECT, 96, 47, 57, 14

    PUSHBUTTON      "OK", IDD_OK, 29, 98, 40, 14

    PUSHBUTTON      "Cancel", IDD_CANCEL, 92, 98, 40, 14

END

The Custom Brush dialog box contains five controls: a bitmap-grid window, a pattern-viewing window, and three push buttons, labeled Test Pattern, OK and Cancel. The Test Pattern push button enables the user to view the pattern. The dialog box template specifies the overall dimensions of the dialog box window, assigns a value to each control, specifies the location of each control, and so forth. (For more information about creating dialog box templates, see Chapter 18, »Dialog Boxes«.)

The control values in the dialog box template are constants that have been defined as follows in the application's header file.

#define IDD_GRID  120

#define IDD_RECT  121

#define IDD_PAINTRECT 122

#define IDD_OK  123

#define IDD_CANCEL 124

After you create a dialog box template and include it in the application's resource-definition file, you must write a dialog procedure. This procedure processes messages that Windows sends to the dialog box. The following excerpt from an application's source code shows the dialog box procedure for the Custom Brush dialog box and the two application-defined functions it calls.

int APIENTRY BrushDlgProc(HWND hdlg, WORD message, LONG wParam,

                         LONG lParam)

{

    static HWND hwndGrid;       /* grid-window control     */

    static HWND hwndBrush;      /* pattern-brush control   */

    static RECT rctGrid;        /* grid-window rectangle   */

    static RECT rctBrush;       /* pattern-brush rectangle */

    static UINT bBrushBits[8];  /* bitmap bits             */

    static RECT rect[64];       /* grid-cell array         */

    static HBITMAP hbm;         /* bitmap handle           */

    HBRUSH hbrush;              /* current brush           */

    HBRUSH hbrushOld;           /* default brush           */

    HRGN hrgnCell;              /* test-region handle      */

    HDC hdc;                    /* DC handle               */

    int x, y, deltaX, deltaY;   /* drawing coordinates     */

    POINTS ptlHit;              /* mouse coordinates       */

    int i;                      /* count variable          */

    switch (message)

        {

        case WM_INITDIALOG:

            /*

             * Retrieve a window handle for the grid-window and

             * pattern-brush controls

             */

            hwndGrid = GetDlgItem(hdlg, IDD_GRID);

            hwndBrush = GetDlgItem(hdlg, IDD_RECT);

            /* Initialize the array of bits that define the

             * custom brush pattern with the value 1 to produce a

             * solid white brush).

             */

            for (i=0; i<8; i++)

                bBrushBits[i] = 0xFF;

            /*

             * Retrieve dimensions for the grid-window and pattern-brush

             * controls.

             */

            GetClientRect(hwndGrid, &rctGrid);

            GetClientRect(hwndBrush, &rctBrush);

            /* Determine the width and height of a single cell. */

            deltaX = (rctGrid.right - rctGrid.left)/8;

            deltaY = (rctGrid.bottom - rctGrid.top)/8;

            /* Initialize the array of cell rectangles. */

            for (y=rctGrid.top, i=0; y < rctGrid.bottom; y += deltaY){

                for (x=rctGrid.left; x < (rctGrid.right - 8) && i < 64;

                        x += deltaX, i++) {

                    rect[i].left = x; rect[i].top = y;

                    rect[i].right = x + deltaX;

                    rect[i].bottom = y + deltaY;

                }

            }

            return FALSE;

        case WM_PAINT:

            /* Draw the grid. */

            hdc = GetDC(hwndGrid);

            for (i=rctGrid.left; i<rctGrid.right;

                 i+=(rctGrid.right - rctGrid.left)/8){

                 MoveToEx(hdc, i, rctGrid.top, NULL);

                 LineTo(hdc, i, rctGrid.bottom);

            }

            for (i=rctGrid.top; i<rctGrid.bottom;

                 i+=(rctGrid.bottom - rctGrid.top)/8){

                 MoveToEx(hdc, rctGrid.left, i, NULL);

                 LineTo(hdc, rctGrid.right, i);

            }

            ReleaseDC(hwndGrid, hdc);

            return FALSE;

        case WM_LBUTTONDOWN:

            /* Store the mouse coordinates in a POINT structure. */

            ptlHit = MAKEPOINTS((POINTS FAR *)lParam);

            /*

             * Create a rectangular region with dimensions and

             * coordinates that correspond to those of the grid

             * window.

             */

            hrgnCell = CreateRectRgn(rctGrid.left, rctGrid.top,

                        rctGrid.right, rctGrid.bottom);

            /* Retrieve a window DC for the grid window. */

            hdc = GetDC(hwndGrid);

            /* Select the region into the DC. */

            SelectObject(hdc, hrgnCell);

            /* Test for a button click in the grid-window rectangle. */

            if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y)){

                /*

                 * A button click occurred in the grid-window rectangle;

                 * isolate the cell in which it occurred.

                 */

                for(i=0; i<64; i++){

                    DeleteObject(hrgnCell);

                    hrgnCell = CreateRectRgn(rect[i].left, rect[i].top,

                               rect[i].right, rect[i].bottom);

                    if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y)){

                         InvertRgn(hdc, hrgnCell);

                         /* Set the appropriate brush bits. */

                         if (i % 8 == 0)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x80;

                         else if (i % 8 == 1)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x40;

                         else if (i % 8 == 2)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x20;

                         else if (i % 8 == 3)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x10;

                         else if (i % 8 == 4)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x08;

                         else if (i % 8 == 5)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x04;

                         else if (i % 8 == 6)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x02;

                         else if (i % 8 == 7)

                            bBrushBits[i/8] = bBrushBits[i/8] ^ 0x01;

                      /* Exit the "for" loop after the bit is set. */

                         break;

                    } /* end if */

                } /* end for */

            } /* end if */

            /* Release the DC for the control. */

            ReleaseDC(hwndGrid, hdc);

            return TRUE;

        case WM_COMMAND:

            switch (wParam){

               case IDD_PAINTRECT:

                    hdc = GetDC(hwndBrush);

                    /* Create a monochrome bitmap. */

                    hbm = CreateBitmap(8, 8, 1, 1,

                          (LPBYTE)bBrushBits);

                    /* Select the custom brush into the DC. */

                    hbrush = CreatePatternBrush(hbm);

                    hbrushOld = SelectObject(hdc, hbrush);

                    /* Use the custom brush to fill the rectangle. */

                    Rectangle(hdc, rctBrush.left, rctBrush.top,

                              rctBrush.right, rctBrush.bottom);

                    /* Clean up memory. */

                    SelectObject(hdc, hbrushOld);

                    DeleteObject(hbrush);

                    DeleteObject(hbm);

                    ReleaseDC(hwndBrush, hdc);

                  return TRUE;

                case IDD_OK:

                case IDD_CANCEL:

                    EndDialog(hdlg, TRUE);

                    return TRUE;

            } /* end switch */

            break;

        default:

            return FALSE;

        }

}

int GetStrLngth(LPTSTR cArray)

{

    int i = 0;

    while (cArray[i++] != 0);

    return i-1;

}

DWORD RetrieveWidth(LPTSTR cArray, int iLength)

{

    int i, iTmp;

    double dVal, dCount;

    dVal = 0.0;

    dCount = (double)(iLength-1);

    for (i=0; i<iLength; i++){

        iTmp = cArray[i] - 0x30;

        dVal = dVal + (((double)iTmp) * pow(10.0, dCount--));

    }

    return (DWORD)dVal;

}

The dialog box procedure for the Custom Brush dialog box processes four messages, as described in the following table.

Message	Action
WM_INITDIALOG	Retrieves a window handle and dimensions for the grid-window and pattern-brush controls, computes the dimensions of a single cell in the grid-window control, and initializes an array of grid-cell coordinates.
WM_PAINT	Draws the grid pattern in the grid-window control.
WM_LBUTTONDOWN	Determines whether the cursor is within the grid-window control when the user presses the left mouse button. If so, the dialog box procedure inverts the appropriate grid cell and records the state of that cell in an array of bits that is used to create the bitmap for the custom brush.
WM_COMMAND	Processes input for the three push button controls. If the user presses the Test Pattern button, the dialog box procedure paints the Test Pattern control with the new custom brush pattern. If the user presses the OK or Cancel button, the dialog box procedure performs actions accordingly.
For more information about messages and message processing, see Chapter 2, »Messages and Message Queues«.

After you write the dialog box procedure, export it in the module-definition file, include the function definition for the procedure in the application's header file, and then call the dialog box procedure at the appropriate point in the application.

The following excerpt from the module-definition file shows how the dialog box procedure for the Custom Brush is exported.

; Export all functions that are called by a Windows routine.

EXPORTS

        MainWndProc   @1   ; name of window processing function

        BrushDlgProc  @2   ; name of custom-brush processing function

The following excerpt from the application's header file shows the function definition for the dialog box procedure and the two functions it calls.

int APIENTRY BrushDlgProc(HWND hdlg, WORD message, LONG wParam,

             LONG lParam);

int GetStrLngth(LPTSTR cArray);

DWORD RetrieveWidth(LPTSTR cArray, int iLength);

Finally, the following code shows how the dialog box procedure is called from the application's source-code file. In this example, the dialog box procedure is called when the user chooses an option from the application's menu.

switch (message) {

    case WM_CREATE:

        break;

    case WM_COMMAND: /* message: command from application menu */

        switch(wParam) {

            case IDM_CUSTOMBRUSH:

                    DialogBox((HANDLE)GetModuleHandle(NULL),

                    (LPTSTR)"CustBrush", hWnd,

                    (DLGPROC)BrushDlgProc);

                break;


  30.3  Functions

Following are the functions that can be used with brushes.

CreateBrushIndirect
CreateDIBPatternBrush
CreateDIBPatternBrushPt
CreateHatchBrush
CreatePatternBrush
CreateSolidBrush
GetBrushOrgEx
GetStockObject
SetBrushOrgEx


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


31.1  About Pens
  Chapter 31    Pens

31.1  About Pens

A pen is a graphics tools that an application for Microsoft® Windows (™)  uses to draw lines and curves. Drawing applications use pens to draw freehand lines, straight lines, and curves. Computer-aided design (CAD) applications use pens to draw visible lines, hidden lines, section lines, center lines, and so on. Word processing and desktop publishing applications use pens to draw borders and rules. Spreadsheet applications use pens to designate trends in graphs and to outline bar graphs and pie charts.

There are two types of pens: cosmetic and geometric. A cosmetic pen is used with applications requiring lines of fixed width and lines that are quickly drawn. A CAD application, for example, uses a cosmetic pen to generate hidden, section, center, and dimension lines that are between .015 and .022 inches wide — regardless of the scale factor. A geometric pen is used with applications requiring scalable lines, lines with unique end or join styles, and lines that are wider than a single pixel. A spreadsheet application, for example, uses a geometric pen to define each of the bars in a bar graph as a wide line.


  31.1.1  Cosmetic Pens

The dimensions of a cosmetic pen are specified in device units. Therefore, lines drawn with a cosmetic pen always have a fixed width. Lines drawn with a cosmetic pen are generally drawn three to ten times faster than lines drawn with a geometric pen. Cosmetic pens have three attributes: width, style, and color. For more information about these attributes, see »Section 31.1.3, Pen Attributes«.

To create a cosmetic pen, an application uses the CreatePen, CreatePenIndirect, or ExtCreatePen function. To retrieve one of the three stock cosmetic pens managed by window manager, the application uses the GetStockObject function.

After a pen is created (or a handle identifying one of the stock pens is obtained), the pen is selected into the application's device context by calling the SelectObject function. From this point on, the application uses this pen for any line-drawing operations in its client area.


  31.1.2  Geometric Pens

The dimensions of a geometric pen are specified in logical units. Therefore, lines drawn with a geometric pen can be scaled — that is, they may appear wider or narrower, depending on the current world transformation. For more information about the world transformation, see Chapter 39, »Coordinate Spaces and Transformations«.

In addition to the three attributes shared with cosmetic pens (width, style, and color), geometric pens possess the following four attributes: pattern, optional hatch, end style, and join style. For more information about these attributes, see Section 31.1.3, »Pen Attributes«.

To create a geometric pen, an application uses the ExtCreatePen function. As with cosmetic pens, the SelectObject function selects a geometric pen into the application's device context.


  31.1.3  Pen Attributes

There are seven pen attributes that define the type of pen and its characteristics: width, style, color, pattern, hatch, end style, and join style. Both cosmetic and geometric pens have the width, style, and color attributes. Only geometric pens have the pattern, hatch, end style, and join style attributes. The pattern and optional hatch attribute are usually associated with a brush, but can also be used with geometric pens.


  31.1.3.1  Width

The width attribute specifies a cosmetic pen width in device units. When used with a geometric pen, however, it specifies the pen's width in logical units. For more information about device units, see Chapter 39, »Coordinate Spaces and Transformations«.

Currently, Windows limits the width of cosmetic pens to a single pixel; however, future versions may remove this limitation.


  31.1.3.2  Style

The style attribute specifies the line pattern that appears when a particular cosmetic or geometric pen is used. There are eight predefined pen styles. »This illustration« shows the seven of these styles that are defined by Windows.

The inside-frame style is identical to the solid style for cosmetic pens. However, it operates differently when used with a geometric pen. If the geometric pen is wider than a single pixel and a drawing function uses the pen to draw a border around a filled object, Windows draws the border inside the object's frame. By using the inside-frame style, an application can ensure that an object appears entirely within the specified dimensions, regardless of the geometric pen width.

In addition to the seven styles defined by Windows, there is an eighth style that is user (or application) defined. A user-defined style generates lines with a customized series of dashes and dots.

Use the CreatePen, CreatePenIndirect, or ExtCreatePen function to create a pen that has the Windows-defined styles. Use the ExtCreatePen function to create a pen that has a user-defined style.


  31.1.3.3  Color

The color attribute specifies the pen's color. An application can create a cosmetic pen with a unique color by storing the red, green, blue (RGB) triplet that specifies the desired color in a COLORREF structure and passing this structure's address to the CreatePen, CreatePenIndirect, or ExtCreatePen function. (The stock pens are limited to black, white, and invisible.) For more information about RGB triplets and color, see Chapter 36, »Colors«.


  31.1.3.4  Pattern

The pattern attribute specifies the pattern of a geometric pen.

»This illustration« shows lines drawn with different geometric pens. Each pen was created using a different pattern attribute.

The first line in the previous illustration is drawn using one of the six available hatch patterns; for more information about hatch patterns, see Section 31.1.3.5, »Hatch«. The next line is drawn using the hollow pattern, identical to the null pattern. The third line is drawn using a custom pattern created from an 8- by 8-pixel bitmap. (For more information about bitmaps and their creation, see Chapter 29, »Bitmaps«.) The last line is drawn using a solid pattern. Creating a brush and passing its handle to the ExtCreatePen function creates a pattern.


  31.1.3.5  Hatch

The hatch attribute specifies the hatch type of a geometric pen with the hatch pattern attribute. There are six patterns available. »This illustration« shows lines drawn using different hatch patterns.


  31.1.3.6  End Cap

The end cap attribute specifies the shape of a geometric pen: round, square, or flat. »This illustration« shows parallel lines drawn using each type of end cap.

The round and square end caps extend past the starting and ending points of a line drawn with a geometric pen; the flat end cap does not.


  31.1.3.7  Join

The join attribute specifies how the ends of two geometric lines are joined: beveled, mitered, or round. »This illustration« shows pairs of connected lines drawn using each type of join.


  31.2  Using Pens

This section contains example code that demonstrates how to create and use a simple pen selection dialog box. The dialog box is a modified Color common dialog box that enables the user to select a pen color, width, style, and join. For more information about the Color common dialog box, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.

»This illustration« shows the modified dialog box.


  31.2.1  Modifying the Dialog Box Template

To modify the Color common dialog box, it is necessary to modify the dialog box template stored in the file COLOR.DLG. The modifications include changing the coordinates of the custom-colors box and custom-colors button (so that they are drawn outside the dialog box window and are therefore invisible) and adding three new controls. Two of these new controls are list boxes that enable the user to select a style and a join. The third control is an edit box in which the user can specify a pen width (in the range 1 through 99). The following excerpt from the application's resource file shows part of the modified dialog box template.

DLGINCLUDE RCDATA DISCARDABLE

BEGIN

    "colordlg.h\0"

END

CHOOSECOLOR DIALOG 2, 0, 298, 184

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "Standard Pen"

FONT 8, "Helv"

BEGIN

    LTEXT           "Pen Color:", -1, 4, 4, 140, 9

    CONTROL         "", COLOR_BOX1, "Static", SS_SIMPLE | WS_GROUP |

                    WS_TABSTOP, 4, 14, 140, 86

    LTEXT           "&Custom Colors:", -1, 4, 806, 140, 9

    CONTROL         "", COLOR_CUSTOM1, "Static", SS_SIMPLE | WS_GROUP |

                    WS_TABSTOP, 4, 816, 140, 28

    PUSHBUTTON      "&Define Custom Colors...", COLOR_MIX, 4, 850, 140, 14,

                    WS_GROUP

    DEFPUSHBUTTON   "OK", IDOK, 4, 166, 44, 14, WS_GROUP

    PUSHBUTTON      "Cancel", IDCANCEL, 52, 166, 44, 14, WS_GROUP

    PUSHBUTTON      "&Help", 1038, 100, 166, 44, 14, WS_GROUP

    CONTROL         "", COLOR_RAINBOW, "Static", SS_BLACKFRAME, 152, 4, 118,

                    116

    CONTROL         "", COLOR_LUMSCROLL, "Static", SS_SIMPLE, 280, 4, 8, 116

    CONTROL         "", COLOR_CURRENT, "Static", SS_BLACKFRAME, 152, 124,

                    40, 26

    RTEXT           "Color|", -1, 152, 151, 20, 9

    LTEXT           "S&olid", -1, 172, 151, 20, 9

    PUSHBUTTON      "&o", COLOR_SOLID, 300, 200, 4, 14, WS_GROUP

    RTEXT           "&Hue:", COLOR_HUEACCEL, 194, 126, 20, 9

    EDITTEXT        COLOR_HUE, 216, 124, 18, 12, WS_GROUP

    RTEXT           "&Sat:", COLOR_SATACCEL, 194, 140, 20, 9

    EDITTEXT        COLOR_SAT, 216, 138, 18, 12, WS_GROUP

    RTEXT           "&Lum:", COLOR_LUMACCEL, 194, 154, 20, 9

    EDITTEXT        COLOR_LUM, 216, 152, 18, 12, WS_GROUP

    RTEXT           "&Red:", COLOR_REDACCEL, 243, 126, 24, 9

    EDITTEXT        COLOR_RED, 269, 124, 18, 12, WS_GROUP

    RTEXT           "&Green:", COLOR_GREENACCEL, 243, 140, 24, 9

    EDITTEXT        COLOR_GREEN, 269, 138, 18, 12, WS_GROUP

    RTEXT           "Bl&ue:", COLOR_BLUEACCEL, 243, 154, 24, 9

    EDITTEXT        COLOR_BLUE, 269, 152, 18, 12, WS_GROUP

    PUSHBUTTON      "&Add to Custom Colors", COLOR_ADD, 152, 166, 142, 14,

                    WS_GROUP

    LISTBOX         101, 3, 113, 80, 52, LBS_SORT | WS_VSCROLL | WS_TABSTOP

    LTEXT           "Pen Style", 102, 3, 102, 57, 10

    LTEXT           "Pen Width", 103, 93, 103, 37, 8

    EDITTEXT        104, 94, 113, 32, 12, ES_AUTOHSCROLL

    LTEXT           "Join Style", 105, 93, 129, 40, 8

    LISTBOX         106, 94, 138, 48, 24, LBS_SORT | WS_VSCROLL | WS_TABSTOP

END


  31.2.2  Processing Dialog Box Input

After the dialog box template is modified, it is necessary to provide a callback function that initializes the new controls in the dialog box and processes the corresponding input. The following excerpt from the application's source file shows the callback function.

DWORD dwPenStyle;

DWORD dwJoinStyle;

DWORD dwWidth;

UINT FAR PASCAL SetPenAttr(HWND hwndDlg, UINT uMsg, UINT wParam,

                          LONG lParam)

{

    static HWND hwndLineStyles;

    static HWND hwndJoinStyles;

    static HWND hwndWidth;

    DWORD adwPenStyle[] = {

                            PS_DASH,

                            PS_DASHDOT,

                            PS_DOT,

                            PS_INSIDEFRAME,

                            PS_NULL,

                            PS_SOLID

                          };

    DWORD adwJoinStyle[] = {

                            PS_JOIN_BEVEL,

                            PS_JOIN_MITER,

                            PS_JOIN_ROUND

                           };

    CHAR  chWidth[3];

    int iCount;

    int  index;

    switch(uMsg){

        case WM_INITDIALOG:

            /* Initialize each custom control with the required data. */

            hwndLineStyles = GetDlgItem(hwndDlg, IDD_PEN_STYLE);

            /* Use the PenStyle constants as indices. */

            SendMessage(hwndLineStyles, LB_ADDSTRING, 0,

                        (LONG) "DASH");

            SendMessage(hwndLineStyles, LB_ADDSTRING, 0,

                        (LONG) "DASHDOT");

            SendMessage(hwndLineStyles, LB_ADDSTRING, 0,

                        (LONG) "DOT");

            SendMessage(hwndLineStyles, LB_ADDSTRING, 0,

                        (LONG) "INSIDEFRAME");

            SendMessage(hwndLineStyles, LB_ADDSTRING, 0,

                        (LONG) "NULL");

            SendMessage(hwndLineStyles, LB_ADDSTRING, 0,

                        (LONG) "SOLID");

            hwndJoinStyles = GetDlgItem(hwndDlg, IDD_JOIN_STYLE);

            /* Use the JoinStyle constants as indices. */

            SendMessage(hwndJoinStyles, LB_ADDSTRING, PS_JOIN_BEVEL,

                        (LONG) "BEVEL");

            SendMessage(hwndJoinStyles, LB_ADDSTRING, PS_JOIN_MITER,

                        (LONG) "MITER");

            SendMessage(hwndJoinStyles, LB_ADDSTRING, PS_JOIN_ROUND,

                        (LONG) "ROUND");

            hwndWidth = GetDlgItem(hwndDlg, IDD_PEN_WIDTH);

            SetWindowText(hwndWidth, (LPTSTR)"1");

        return TRUE;

        case WM_COMMAND:

            /* Retrieve the requested pen style. */

            index = SendMessage(hwndLineStyles, LB_GETCURSEL, 0, 0L);

            dwPenStyle = adwPenStyle[index];

            /* Retrieve the requested join style. */

            index = SendMessage(hwndJoinStyles, LB_GETCURSEL, 0, 0L);

            dwJoinStyle = adwJoinStyle[index];

            /* Retrieve the requested width. */

            GetDlgItemText(hwndDlg, IDD_PEN_WIDTH, chWidth, 3);

            dwWidth = RetrieveWidth(chWidth, GetStrLngth(chWidth));

        return FALSE;

    }

    return FALSE;

    UNREFERENCED_PARAMETER(wParam);

    UNREFERENCED_PARAMETER(lParam);

    UNREFERENCED_PARAMETER(iCount);

}

You must register the callback function with the common dialog box procedure by initializing the appropriate members of a CHOOSECOLOR structure, which is passed to the ChooseColor function. The following excerpt from the application's source file shows how this can be done.

static CHOOSECOLOR cc; /* structure required for Color dialog box */

static COLORREF clr;

static COLORREF aclrCust[256];

                    /*

                     * Initialize the necessary CHOOSECOLOR

                     * members.

                     */

                    cc.lStructSize = sizeof(CHOOSECOLOR);

                    cc.hwndOwner = hwnd;

                    cc.hInstance = (HWND)hInst;

                    cc.rgbResult = clr;

                    cc.lpCustColors = aclrCust;

                    cc.Flags =  CC_ENABLEHOOK | CC_ENABLETEMPLATE;

                    cc.lpfnHook = (LPCCHOOKPROC)SetPenAttr;

                    cc.lpTemplateName = "CHOOSECOLOR";

After the ChooseColor function executes, the rgbResult member of the CHOOSECOLOR structure contains the user-requested color, the dwPenStyle parameter specifies the requested pen style, the dwJoinStyle parameter specifies the requested join, and the dwWidth parameter specifies the requested width. These values are passed to the ExtCreatePen function and used to create a geometric pen, which is selected into a device context and used for various line-drawing operations.

if (ChooseColor(&cc)){

    hdc = GetDC(hwnd);

    /* Initialize the pen's "brush." */

    logbrush.lbStyle = BS_SOLID;

    logbrush.lbColor = cc.rgbResult;

    logbrush.lbHatch = 0;

    /* Create a pen and select it into the DC. */

    hpenOld = SelectObject(hdc,

              ExtCreatePen(PS_GEOMETRIC | dwPenStyle

                           | dwJoinStyle, dwWidth,

                           &logbrush, (DWORD) NULL,

                           (LPDWORD) NULL));

    /* Perform drawing operations. */

    MoveToEx(hdc, 100, 100, NULL);

    LineTo(hdc, 100, 200);

    LineTo(hdc, 200, 200);

    LineTo(hdc, 200, 100);

    LineTo(hdc, 100, 100);

    ReleaseDC(hwnd, hdc);

    }

For more information about customizing common dialog boxes, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.


  31.3  Functions

Following are the functions that support the pen interface.

CreatePen
CreatePenIndirect
ExtCreatePen
GetStockObject


32.1  About Regions
  Chapter 32    Regions

32.1  About Regions

In Microsoft® Windows (™) , a region is a rectangle, polygon, or ellipse (or a combination of two or more of these shapes) that can be filled, painted, inverted, framed, and used to perform hit testing (testing for the cursor location).

»This illustration« shows three types of regions that have been filled and framed.


  32.1.1  Region Creation and Selection

An application creates a region by calling a function associated with a specific shape. The following table shows the function(s) associated with each of the standard shapes.

Shape	Function
Rectangular region	CreateRectRgn, CreateRectRgnIndirect
Rectangular region with rounded corners	CreateRoundRectRgn
Elliptical region	CreateEllipticRgn, CreateEllipticRgnIndirect
Polygonal region	CreatePolygonRgn, CreatePolygonRgnIndirect
Each region-creation function returns a handle that identifies the new region. An application can use this handle of select the region into a device context by calling the SelectObject function and supplying this handle as the second argument. After a region is selected into a device context, an application can perform various operations on it.


  32.1.2  Region Operations

Applications can combine regions, compare them, paint or invert their interiors, draw a frame around them, retrieve their dimensions, and test to see whether the cursor lies within their boundaries.


  32.1.2.1  Combining

An application combines two regions by calling the CombineRgn function. Using this function, an application can combine the intersecting parts of two regions, all but the intersecting parts of two regions, the two original regions in their entirety, and so on. Following are the five region combinations.

Value	Description
RGN_AND	The intersecting parts of two original regions define a new region.
RGN_COPY	A copy of the first (of the two original regions) defines a new region.
RGN_DIFF	The part of the first region that does not intersect the second defines a new region.
RGN_OR	The two original regions define a new region.
RGN_XOR	Those parts of the two original regions that do not overlap define a new region.
»This illustration« shows the five possible combinations of a square and a circular region resulting from a call to the CombineRgn function.


  32.1.2.2  Comparing

An application compares two regions to determine whether or not they are identical by calling the EqualRgn function. EqualRgn considers two regions identical if they are equal in size and shape.


  32.1.2.3  Filling

An application fills the interior of a region by calling the FillRgn function and supplying a handle that identifies a specific brush. When an application calls FillRgn, Windows fills the region with the brush by using the current fill mode for the specified device context. There are two fill modes: alternate and winding. The application can set the fill mode for a device context by calling the SetPolyFillMode function. An application can retrieve the current fill mode for a device context by calling the GetPolyFillMode function.

»This illustration« shows two identical regions: one filled using alternate mode, the other filled using winding mode.

Alternate Mode

To determine which pixels Windows highlights when alternate mode is specified, perform the following test:

1.	Select a pixel within the region's interior.

2.	Draw an imaginary ray, in the positive x-direction, from that pixel towards infinity.

3.	Each time the ray intersects a boundary line, increment a count value.

Windows highlights the pixel if the count value is an odd number.

Winding Mode

To determine which pixels Windows highlights when winding mode is specified, perform the following test:

1.	Determine the direction in which each boundary line is drawn.

2.	Select a pixel within the region's interior.

3.	Draw an imaginary ray, in the positive x-direction, from the pixel toward infinity.

4.	Each time the ray intersects a boundary line with a positive y-component, increment a count value; each time the ray intersects a boundary line with a negative y-component, decrement the count value.

Windows highlights the pixel if the count value is nonzero.


  32.1.2.4  Painting

An application fills the interior of a region by using the brush currently selected into a device context by the PaintRgn function. This function uses the current polygon fill modes (alternate and winding).


  32.1.2.5  Inverting

An application inverts the colors that appear within a region by calling the InvertRgn function. On monochrome displays, the InvertRgn function makes white pixels black and black pixels white. On color screens, this inversion is dependent on the type of technology used to generate the colors for the screen.


  32.1.2.6  Framing

An application draws a border around a region by calling the FrameRgn function and specifying the border width and brush pattern that Windows uses when drawing the frame.


  32.1.2.7  Retrieving a Bounding Rectangle

An application retrieves the dimensions of a region's bounding rectangle by calling the GetRgnBox function. If the region is rectangular, GetRgnBox returns the dimensions of the region. If the region is elliptical, the function returns the dimensions of the smallest rectangle that can be drawn around the ellipse. The long sides of the rectangle are the same length as the ellipse's major axis; the short sides of the rectangle are the same length as the ellipse's minor axis. If the region is polygonal, GetRgnBox returns the dimensions of the smallest rectangle that can be drawn around the entire polygon.


  32.1.2.8  Moving

An application moves a region by calling the OffsetRgn function. The given offsets along the x-axis and y-axis determine the number of logical units to move left or right and up or down.


  32.1.2.9  Hit Testing

An application performs hit testing on regions to determine the coordinates of the current cursor position. It then passes these coordinates — as well as a handle identifying the region — to the PtInRegion function. The cursor coordinates can be retrieved by processing the various mouse messages such as WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP. The PtInRegion return value indicates whether the cursor position is within the given region.


  32.2  Using Regions

The examples in this section show how applications can manipulate regions to perform the following tasks:

•	Define a clipping region.

•	Clip output.

•	Perform hit testing.


  32.2.1  Using Regions to Clip Output

This section contains a single example that demonstrates how you can use regions to enable the user to define how a part of the client area output can appear. Regions used for this purpose are called clipping regions.

The example for this section is taken from a Windows-based application that enables a user to capture the entire desktop as a bitmap and then isolate and save a part of this image as a .BMP file. »This illustration« shows the application's window and client area immediately after the user has captured the desktop contents.

By selecting the Define Clip Region option from the application's menu, the user is able to select a clipping region by clicking the left mouse button and dragging the mouse. As the user drags the mouse, the application draws a rectangle that corresponds to the new clipping region. »This illustration« shows the application's window, client area, and the rectangle created by the user.

By selecting the Clip option, the user is able to redraw the isolated part of the image within the boundaries of the specified rectangle. »This illustration« shows the application's window, the client area, and the clipped output.


  32.2.1.1  Defining the Clipping Region

When the user selects the Define Clip Region option, Windows issues a WM_COMMAND message. The wParam parameter of this message contains an application-defined constant, IDM_DEFINE, that indicates that the user selected this option from the menu. The application processes this input by setting a Boolean flag, fDefineRegion, as shown in the following code.

case WM_COMMAND:

    switch (wParam) {

case IDM_DEFINE:

    fDefineRegion = TRUE;

break;

After selecting the Define Clipping Region option, the user can begin drawing the rectangle by clicking and dragging the mouse while the cursor is in the application's client area.

When the user presses the left button, Windows issues a WM_LBUTTONDOWN message. The lParam parameter of this message contains the cursor coordinates, which correspond to the upper left corner of a rectangle used to define the clipping region. The application processes the WM_LBUTTONDOWN message as follows:

/* These variables are required for clipping. */

static POINT ptUpperLeft;

static POINT ptLowerRight;

static POINT aptRect[5];

static POINT ptTmp;

static POINTS ptsTmp;

static BOOL fDefineRegion;

static BOOL fRegionExists;

static HRGN hrgn;

static RECT rctTmp;

int i;

switch (message) {

case WM_LBUTTONDOWN:

    if (fDefineRegion) {

        /* Retrieve the new upper left corner. */

        ptsTmp = MAKEPOINTS(lParam);

        ptUpperLeft.x = (LONG) ptsTmp.x;

        ptUpperLeft.y = (LONG) ptsTmp.y;

    }

    if (fRegionExists) {

        /* Erase the previous rectangle. */

        hdc = GetDC(hwnd);

        SetROP2(hdc, R2_NOTXORPEN);

        if (!Polyline(hdc, (CONST POINT *) aptRect, 5))

            errhandler("Polyline Failed", hwnd);

        ReleaseDC(hwnd, hdc);

        /* Clear the rectangle coordinates. */

        for (i = 0; i < 4; i++) {

               aptRect[i].x = 0;

               aptRect[i].y = 0;

        }

        /* Clear the temporary point structure. */

        ptTmp.x = 0;

        ptTmp.y = 0;

        /* Clear the lower right coordinates. */

        ptLowerRight.x = 0;

        ptLowerRight.y = 0;

        /* Reset the flag. */

        fRegionExists = FALSE;

        fDefineRegion = TRUE;

        /* Retrieve the new upper left corner. */

        ptsTmp = MAKEPOINTS(lParam);

        ptUpperLeft.x = (LONG) ptsTmp.x;

        ptUpperLeft.y = (LONG) ptsTmp.y;

    }

break;

As the user drags the mouse, Windows issues WM_MOUSEMOVE messages and stores the new cursor coordinates in the lParam parameter. Each time the application receives a new WM_MOUSEMOVE message, it erases the previous rectangle (if one exists) and draws the new rectangle by calling the Polyline function and passing the coordinates of the four corners of the rectangle. The application performs these tasks as shown in the following example.

/* These variables are required for clipping. */

static POINT ptUpperLeft;

static POINT ptLowerRight;

static POINT aptRect[5];

static POINT ptTmp;

static POINTS ptsTmp;

static BOOL fDefineRegion;

static BOOL fRegionExists;

static HRGN hrgn;

static RECT rctTmp;

int i;

switch (message) {

case WM_MOUSEMOVE:

    if (wParam & MK_LBUTTON && fDefineRegion) {

        /* Get a window DC. */

        hdc = GetDC(hwnd);

        if (!SetROP2(hdc, R2_NOTXORPEN))

            errhandler("SetROP2 Failed", hwnd);

        /*

         * If previous mouse movement occurred, store the original

         * lower right corner coordinates in a temporary structure.

         */

        if (ptLowerRight.x) {

            ptTmp.x = ptLowerRight.x;

            ptTmp.y = ptLowerRight.y;

        }

        /*

         * Get the new coordinates of the clipping region's lower

         * right corner.

         */

        ptsTmp = MAKEPOINTS(lParam);

        ptLowerRight.x = (LONG) ptsTmp.x;

        ptLowerRight.y = (LONG) ptsTmp.y;

        /*

         * If previous mouse movement occurred, erase the original

         * rectangle.

         */

        if (ptTmp.x) {

            aptRect[0].x = ptUpperLeft.x;

            aptRect[0].y = ptUpperLeft.y;

            aptRect[1].x = ptTmp.x;

            aptRect[1].y = ptUpperLeft.y;

            aptRect[2].x = ptTmp.x;

            aptRect[2].y = ptTmp.y;

            aptRect[3].x = ptUpperLeft.x;

            aptRect[3].y = ptTmp.y;

            aptRect[4].x = aptRect[0].x;

            aptRect[4].y = aptRect[0].y;

            if (!Polyline(hdc, (CONST POINT *) aptRect, 5))

                errhandler("Polyline Failed", hwnd);

        }

        aptRect[0].x = ptUpperLeft.x;

        aptRect[0].y = ptUpperLeft.y;

        aptRect[1].x = ptLowerRight.x;

        aptRect[1].y = ptUpperLeft.y;

        aptRect[2].x = ptLowerRight.x;

        aptRect[2].y = ptLowerRight.y;

        aptRect[3].x = ptUpperLeft.x;

        aptRect[3].y = ptLowerRight.y;

        aptRect[4].x = aptRect[0].x;

        aptRect[4].y = aptRect[0].y;

        if (!Polyline(hdc, (CONST POINT *) aptRect, 5))

             errhandler("Polyline Failed", hwnd);

        ReleaseDC(hwnd, hdc);

    }

    break;


  32.2.1.2  Clipping Output

After the user chooses the Clip option from the menu, the application uses the coordinates of the rectangle the user created to define a clipping region. After defining the clipping region and selecting it into the application's device context, the application redraws the bitmapped image. The application performs these tasks as shown in the following example.

/* These variables are required for clipping. */

static POINT ptUpperLeft;

static POINT ptLowerRight;

static POINT aptRect[5];

static POINT ptTmp;

static POINTS ptsTmp;

static BOOL fDefineRegion;

static BOOL fRegionExists;

static HRGN hrgn;

static RECT rctTmp;

int i;

case WM_COMMAND:

    switch (wParam) {

case IDM_CLIP:

    hdc = GetDC(hwnd);

    /*

     * Retrieve the application's client rectangle and paint

     * with the default (white) brush.

     */

    GetClientRect(hwnd, &rctTmp);

    FillRect(hdc, &rctTmp, GetStockObject(WHITE_BRUSH));

    /* Use the rectangle coordinates to define a clipping region. */

    hrgn = CreateRectRgn(aptRect[0].x, aptRect[0].y,

        aptRect[2].x, aptRect[2].y);

    SelectClipRgn(hdc, hrgn);

    /* Transfer (draw) the bitmap into the clipped rectangle. */

    BitBlt(hdc,

       0, 0,

       bmp.bmWidth, bmp.bmHeight,

       hdcCompatible,

       0, 0,

       SRCCOPY);

    ReleaseDC(hwnd, hdc);

break;


  32.2.2  Using Regions to Perform Hit Testing

The example in Chapter 30, »Brushes«, uses regions to simulate a "zoomed" view of an 8- by 8-pixel monochrome bitmap. By clicking on the pixels in this bitmap, the user creates a custom brush suitable for drawing operations. This example shows how to use the PtInRegion function to perform hit testing and the InvertRgn function to invert the colors in a region.


  32.3  Functions

Following are the functions used with regions.

CombineRgn
CreateEllipticRgn
CreateEllipticRgnIndirect
CreatePolygonRgn
CreatePolyPolygonRgn
CreateRectRgn
CreateRectRgnIndirect
CreateRoundRectRgn
EqualRgn
ExtCreateRegion
FillRgn
FrameRgn
GetPolyFillMode
GetRgnBox
GetRegionData
InvertRgn
OffsetRgn
PaintRgn
PtInRegion
RectInRegion
SetPolyFillMode


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


33.1  About Lines and Curves
  Chapter 33    Lines and Curves

33.1  About Lines and Curves

All types of applications written for Microsoft® Windows (™)  use lines and curves to draw graphics output on raster devices. Computer-aided design (CAD) and drawing applications use lines and curves to outline objects, specify the centers of objects, the dimensions of objects, and so on. Spreadsheet applications use lines and curves to draw grids, charts, and graphs. Word processing applications use lines to create rules and borders on a page of text.


  33.1.1  Lines

A line is a set of highlighted pixels on a raster display (or a set of dots on a printed page) identified by two points: a starting point and an ending point. In Windows, the pixel located at the starting point is always included in the line, and the pixel located at the ending point is always excluded (these lines are sometimes called inclusive-exclusive).

When an application calls one of the Windows line-drawing functions, the graphics device interface (GDI), or in some cases a device driver, determines which pixels should be highlighted. GDI is a dynamic-link library that processes graphics function calls from a Windows-based application and passes those calls to a device driver. A device driver is a dynamic-link library that receives input from GDI, converts the input to device commands, and passes these commands to the appropriate device. GDI uses a digital differential analyzer (DDA) to determine the set of pixels that define a line. A DDA determines the set of pixels by examining each point on the line and identifying those pixels on the display surface (or dots on a printed page) that correspond to these points. »This illustration« shows a line, its starting point, its ending point, and the pixels highlighted by using a simple DDA.

The simplest and most common DDA is the Bresenham, or incremental DDA. A modified version of this algorithm draws lines in Windows versions 3.x. The incremental DDA is noted for its simplicity, but it is also noted for its inaccuracy; because it rounds off to the nearest integer value, it sometimes fails to represent the original line requested by the application. The DDA used by the new GDI does not round off to the nearest integer. As a result, it produces output that is sometimes much closer in appearance to the original line requested by the application.

Note   If an application requires line output that cannot be achieved with the new Win32 DDA, it can draw its own lines by calling the LineDDA function and supplying a private DDA. However, the LineDDA function draws lines much slower than the Windows line-drawing functions; do not use this function within an application if speed is a primary concern.

An application can use the new Win32 DDA to draw single lines and multiple, connected line segments. An application can draw a single line by calling the LineTo function. This function draws a line from a device context's current position to a specified ending point. An application can draw a series of connected line segments by calling the Polyline function, supplying an array of points that specify the ending point of each line segment. An application can draw multiple, disjointed series of connected line segments by calling the PolyPolyline function, supplying the required ending points.

»This illustration« shows line output created by calling the LineTo, Polyline, and PolyPolyline functions.


  33.1.2  Curves

A regular curve is a set of highlighted pixels on a raster display (or dots on a printed page) that define the perimeter (or part of the perimeter) of a conic section. An irregular curve is a set of pixels that define a curve that does not fit the perimeter of a conic section. In Windows, the ending point is excluded from a curve just as it is excluded from a line.

When an application calls one of the Windows curve-drawing functions, GDI breaks the curve into a number of extremely small, discrete line segments. After determining the ending points for each of these line segments, GDI determines which pixels (or dots) define each line by applying its DDA.

An application can draw an ellipse or part of an ellipse by calling the Arc function. This function draws the curve within the perimeter of an invisible rectangle called a bounding rectangle. The size of the ellipse is specified by two invisible radials extending from the center of the rectangle to the sides of the rectangle. »This illustration« shows an arc (part of an ellipse) drawn using the Arc function.

When calling the Arc function, an application specifies the coordinates of the bounding rectangle and radials. The preceding illustration shows the rectangle and radials with dashed lines while the actual arc was drawn using a solid line.

When drawing the arc of another object, the application can call the SetArcDirect and GetArcDirection functions to control the direction (clockwise, counterclockwise) in which the object is drawn. The default direction for drawing arcs and other objects is counterclockwise.

In addition to drawing ellipses or parts of ellipses, Windows-based applications can draw irregular curves called Bézier splines. Originally, the term spline referred to a tool used by draftsmen to draw irregular curves. With the development of graphical interfaces, however, the term has come to refer to the curve itself. A Bézier spline is an irregular curve with the following characteristics: The curvature of the spline is defined by four control points (p1, p2, p3, and p4). The control points p1 and p4 define the starting and ending points of the curve; the control points p2 and p3 define the shape of the curve by marking points where the curve reverses orientation. »This illustration« shows two Bézier splines, their starting and ending points, and control points.

An application can draw irregular curves by calling the PolyBezier function, supplying the appropriate control points.


  33.1.3  Combined Lines and Curves

In addition to drawing lines or curves, Windows-based applications can draw combinations of line and curve output by calling a single function. For example, an application can draw the outline of a pie chart by calling the AngleArc function, as shown in »this illustration«.

The AngleArc function draws an arc along a circle's perimeter and draws a line connecting the starting point of the arc to the circle's center. The pie chart in the preceding illustration was created by calling the AngleArc function five consecutive times. In addition to using the AngleArc function, a Windows-based application could also combine line and irregular curve output by using the PolyDraw function.


  33.1.4  Line and Curve Attributes

A device context contains attributes that affect line and curve output. These attributes include current position, brush style, brush color, pen style, pen color, transformation, and so on.

The default current position for any device context is located at the point (0,0) in logical (or world) space. You can set these coordinates to a new position by calling the MoveToEx function and passing a new set of coordinates.

Note   Windows provides two sets of line- and curve-drawing functions: the first set retains the current position in a device context; the second set alters the position. You can identify the functions that alter the current position by examining the function name. If the function name ends with the preposition "To", the function sets the current position to the ending point of the last line drawn (LineTo, ArcTo, PolylineTo, or PolyBezierTo). If the function name does not end with this preposition, it leaves the current position intact (Arc, Polyline, PolyBezier).

The default brush is a solid white brush. An application can create a new brush by calling the CreateBrushIndirect function. After creating a brush, your application can select it into its device context by calling the SelectObject function. Windows provides a complete set of functions to create, select, and alter the brush in your application's device context. For more information about these functions and about brushes in general, see Chapter 30, »Brushes«.

The default pen is a cosmetic, solid black pen that is one pixel wide. The application can create a pen by using the ExtCreatePen function. After creating a pen, your application can select it into its device context by calling the SelectObject function. Windows provides a complete set of functions to create, select, and alter the pen in your application's device context. For more information about these functions and about pens in general, see Chapter 31, »Pens«

The default transformation is the unity transformation (specified by the identity matrix). An application can specify a new transformation by calling the SetWorldTransform function. Windows provides a complete set of functions to transform lines and curves by altering their width, location, and general appearance. For more information about these functions, see Chapter 39, »Coordinate Spaces and Transformations«.


  33.2  Using Lines and Curves

You can use the line and curve functions to draw virtually any shape or object in the client area of the application window. This section contains two code samples that illustrate how these functions might be used.


  33.2.1  Drawing Markers

You can use the line functions to draw markers. A marker is a symbol centered over a point. Drawing applications use markers to designate starting points, ending points, and control points. Spreadsheet applications use markers to designate points of interest on a chart or graph. »This illustration« shows a screen from a drawing application that uses markers to designate the ending points and control points for a Bézier spline.

In the following code sample, the application-defined Marker function creates a marker by using the MoveToEx and LineTo functions. These functions draw two intersecting lines, 20 pixels in length, centered over the cursor coordinates.

void Marker(LONG x, LONG y, HWND hwnd)

{

    HDC hdc;

    hdc = GetDC(hwnd);

        MoveToEx(hdc, (int) x - 10, (int) y, (LPPOINT) NULL);

        LineTo(hdc, (int) x + 10, (int) y);

        MoveToEx(hdc, (int) x, (int) y - 10, (LPPOINT) NULL);

        LineTo(hdc, (int) x, (int) y + 10);

    ReleaseDC(hwnd, hdc);

}

Windows stores the coordinates of the cursor in the lParam parameter of the WM_LBUTTONDOWN message when the user presses the left mouse button. The following code demonstrates how an application gets these coordinates, determines whether they lie within its client area, and passes them to the Marker function to draw the marker.

/* Line- and arc-drawing variables */

static BOOL bCollectPoints;

static POINT ptMouseDown[32];

static int index;

POINTS ptTmp;

RECT rc;

    case WM_LBUTTONDOWN:

        if (bCollectPoints && index < 32){

            /* Create the region from the client area. */

            GetClientRect(hwnd, &rc);

            hrgn = CreateRectRgn(rc.left, rc.top,

                rc.right, rc.bottom);

            ptTmp = MAKEPOINTS((POINTS FAR *) lParam);

            ptMouseDown[index].x = (LONG) ptTmp.x;

            ptMouseDown[index].y = (LONG) ptTmp.y;

            /* Test for a hit in the client rectangle. */

            if (PtInRegion(hrgn, ptMouseDown[index].x,

                    ptMouseDown[index].y)) {

                /* If a hit occurs, record the mouse coordinates. */

                Marker(ptMouseDown[index].x, ptMouseDown[index].y,

                    hwnd);

                index++;

            }

        }

        break;


  33.2.2  Drawing a Pie Chart

You can use the line and curve functions to draw a pie chart. The primary function used to draw pie charts is the AngleArc function, which requires you to supply the coordinates of the center of the pie, the radius of the pie, a start angle, and a sweep angle. »This illustration« shows a dialog box that the user can use to enter these values.

The following example shows the dialog box template found in the application's resource script (.RC) file. This template specifies characteristics of the preceding dialog box (its height, the controls it contains, and its style).

AngleArc DIALOG 6, 18, 160, 100

STYLE WS_DLGFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION

CAPTION "Pie Chart"

FONT 8, "MS Sans Serif"

BEGIN

    EDITTEXT        IDD_X, 18, 22, 25, 12, ES_AUTOHSCROLL

    LTEXT           "X", 102, 4, 24, 9, 8

    EDITTEXT        IDD_Y, 18, 39, 25, 12, ES_AUTOHSCROLL

    LTEXT           "Y", 104, 5, 42, 12, 8

    LTEXT           "Center", 105, 19, 11, 23, 8

    EDITTEXT        IDD_RADIUS, 103, 9, 32, 12, ES_AUTOHSCROLL

    EDITTEXT        IDD_STARTANGLE, 103, 31, 32, 12, ES_AUTOHSCROLL

    EDITTEXT        IDD_SWEEPANGLE, 103, 53, 32, 12, ES_AUTOHSCROLL

    LTEXT           "Radius", 109, 73, 11, 25, 8

    LTEXT           "Start Angle", 110, 59, 33, 42, 8

    LTEXT           "Sweep Angle", 111, 55, 55, 43, 8

    PUSHBUTTON      "OK", IDD_OK, 9, 82, 40, 14

    PUSHBUTTON      "Cancel", IDD_CANCEL, 110, 82, 40, 14

END

The following example shows the dialog box procedure, found in the application's source file. This procedure retrieves data (center coordinates, arc radius, and start and sweep angles) by following these steps:

1.	The application-defined ClearBits function initializes the array receiving the user-input to zero.

2.	The application-defined GetStrLngth function retrieves the length of the string entered by the user.

3.	The application-defined RetrieveInput function retrieves the value entered by the user.

BOOL CALLBACK ArcDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam,

                       LPARAM lParam)

{

    CHAR chInput[4];    /* receives control-window input  */

    int cch;            /* array-size and count variable  */

    switch (uMsg) {

        case WM_INITDIALOG:

            return FALSE;

        case WM_COMMAND:

            switch (wParam){

                /*

                 * If the user pressed the OK button, retrieve the

                 * data that was entered in the various AngleArc

                 * controls.

                 */

                case IDD_OK:

                    /*

                     * Retrieve the x-coordinate of the arc's

                     * center.

                     */

                    ClearBits(chInput, sizeof(chInput));

                    GetDlgItemText(hdlg, IDD_X, chInput,

                        sizeof(chInput));

                    cch = GetStrLngth(chInput);

                    nX = (int)RetrieveInput(chInput, cch);

                    /*

                     * Retrieve the y-coordinate of the arc's

                     * center.

                     */

                    ClearBits(chInput, sizeof(chInput));

                    GetDlgItemText(hdlg, IDD_Y, chInput,

                        sizeof(chInput));

                    cch = GetStrLngth(chInput);

                    nY = (int)RetrieveInput(chInput, cch);

                    /* Retrieve the radius of the arc. */

                    ClearBits(chInput, sizeof(chInput));

                    GetDlgItemText(hdlg, IDD_RADIUS, chInput,

                        sizeof(chInput));

                    cch = GetStrLngth(chInput);

                    dwRadius = (DWORD) RetrieveInput(chInput, cch);

                    /* Retrieve the start angle. */

                    ClearBits(chInput, sizeof(chInput));

                    GetDlgItemText(hdlg, IDD_STARTANGLE, chInput,

                        sizeof(chInput));

                    cch = GetStrLngth(chInput);

                    xStartAngle = (float) RetrieveInput(chInput, cch);

                    /* Retrieve the sweep angle. */

                    ClearBits(chInput, sizeof(chInput));

                    GetDlgItemText(hdlg, IDD_SWEEPANGLE, chInput,

                        sizeof(chInput));

                    cch = GetStrLngth(chInput);

                    xSweepAngle = (float) RetrieveInput(chInput, cch);

                    EndDialog(hdlg, FALSE);

                    return TRUE;

                /*

                 * If user presses the CANCEL button, close the

                 * dialog box.

                 */

                case IDD_CANCEL:

                    EndDialog(hdlg, FALSE);

                    return TRUE;

            } /* end switch (wParam) */

            break;

        default:

            return FALSE;

    } /* end switch (message) */

    UNREFERENCED_PARAMETER(lParam);

}

void ClearBits(LPTSTR cArray, int iLength)

{

    int i;

    for (i = 0; i < iLength; i++)

        cArray[i] = 0;

}

int GetStrLngth(LPTSTR cArray)

{

    int i = 0;

    while (cArray[i++] != 0);

        return i - 1;

}

DWORD RetrieveInput(LPTSTR cArray, int iLength)

{

    int i, iTmp;

    double dVal, dCount;

    dVal = 0.0;

    dCount = (double) (iLength - 1);

    /* Convert ASCII input to a floating-point value. */

    for (i = 0; i < iLength; i++) {

        iTmp = cArray[i] - 0x30;

        dVal = dVal + (((double)iTmp) * pow(10.0, dCount--));

    }

    return (DWORD) dVal;

}

To draw each section of the pie chart, pass the values entered by the user to the AngleArc function. To fill the pie chart using the current brush, embed the call to the AngleArc function in a path bracket. The following example shows the defined path bracket and the AngleArc function call.

int nX;

int nY;

DWORD dwRadius;

float xStartAngle;

float xSweepAngle;

                    case (IDM_ANGLEARC):

                       DialogBox((HINSTANCE) GetModuleHandle (NULL),

                                 (LPTSTR) "AngleArc",

                                 hwnd, (DLGPROC) ArcDlgProc);

                        hdc = GetDC(hwnd);

                            BeginPath(hdc);

                                SelectObject(hdc,

                                    GetStockObject(GRAY_BRUSH));

                                MoveToEx(hdc, nX, nY, (LPPOINT) NULL);

                                AngleArc(hdc, nX, nY, dwRadius,

                                    xStartAngle, xSweepAngle);

                                LineTo(hdc, nX, nY);

                            EndPath(hdc);

                        StrokeAndFillPath(hdc);

                        ReleaseDC(hwnd, hdc);

                        break;


  33.3  Functions

Following are the functions used with lines and curves.

AngleArc
Arc
ArcTo
GetArcDirection
LineDDA
LineDDAProc
LineTo
MoveToEx
PolyBezier
PolyBezierTo
PolyDraw
Polyline
PolylineTo
PolyPolyline
SetArcDirection


34.1  About Filled Shapes
  Chapter 34    Filled Shapes

34.1  About Filled Shapes

Filled shapes are geometric shapes that are outlined by using the current pen and filled by using the current brush. There are five filled shapes: ellipse, chord, pie, polygon, and rectangle. An application written for Microsoft® Windows (™)  uses filled shapes in a variety of ways. Spreadsheet applications, for example, use filled shapes to construct charts and graphs; drawing and painting applications use filled shapes to allow the user to draw figures and illustrations.


  34.1.1  Ellipse

An ellipse is a closed curve defined by two fixed points (f1 and f2) such that the sum of the distances (d1 + d2) from any point on the curve to the two fixed points is constant. »This illustration« shows an ellipse drawn by using the Ellipse function.

When calling the Ellipse function, an application supplies the coordinates of the upper-left and lower-right corners of the ellipse's bounding rectangle. A bounding rectangle is the smallest rectangle completely surrounding the ellipse. When Windows draws the ellipse, it excludes the right and lower sides if no world transformations are set. Therefore, for any rectangle measuring x units wide by y units high, the associated ellipse measures x−1 units wide by y−1 units high. If the application set a world transformation by calling the SetWorldTransform or ModifyWorldTransform function, Windows includes the right and lower sides.


  34.1.2  Chord

A chord is a region bounded by the intersection of an ellipse and a line segment called a secant. »This illustration« shows a chord drawn by using the Chord function.

When calling the Chord function, an application supplies the coordinates of the upper-left and lower-right corners of the ellipse's bounding rectangle, as well as the coordinates of two points defining two radials. A radial is a line drawn from the center of an ellipse's bounding rectangle to a point on the ellipse.

When Windows draws the curved part of the chord, it does so by using the current arc direction for the specified device context. The default arc direction is counterclockwise. You can have your application reset the arc direction by calling the SetArcDirection function.


  34.1.3  Pie

A pie is a region bounded by the intersection of an ellipse curve and two radials. »This illustration« shows a pie drawn by using the Pie function.

When calling the Pie function, an application supplies the coordinates of the upper-left and lower-right corners of the ellipse's bounding rectangle, as well as the coordinates of two points defining two radials.

When Windows draws the curved part of the pie, it uses the current arc direction for the given device context. The default arc direction is counterclockwise. An application can reset the arc direction by calling the SetArcDirection function.


  34.1.4  Polygon

A polygon is a filled shape with straight sides. The sides of a polygon are drawn by using the current pen. When Windows fills a polygon, it uses the current brush and the current polygon fill mode. The two fill modes — alternate (the default) and winding — determine whether regions within a complex polygon are filled or left unpainted. An application can select either mode by calling the SetPolyFillMode function. For more information about polygon fill modes, see Chapter 32, »Regions«.

»This illustration« shows a polygon drawn by using the Polygon function.

In addition to drawing a single polygon with the Polygon function, an application can draw multiple polygons by using the PolyPolygon function.


  34.1.5  Rectangle

A rectangle is a four-sided polygon whose opposing sides are parallel and equal in length. Although an application can draw a rectangle by calling the Polygon function, supplying the coordinates of each corner, Windows provides a simpler method: the Rectangle function. This function requires only the coordinates for the upper-left and the lower-right corners. When an application calls the Rectangle function, Windows draws the rectangle, excluding the right and lower sides if no world transformation is set for the given device context.

If a world transformation has been set by using the SetWorldTransform or the ModifyWorldTransform functions, Windows includes the right and lower edges.

In addition to drawing a normal rectangle, the Win32 application programming interface (API) provides a function that applications can use to draw rectangles with rounded corners. This function, RoundRect, requires that the application supply the coordinates of the lower-left and upper-right corners, as well as the width and height of the ellipse used to round each corner.

The Win32 API also provides three functions that applications can use to manipulate rectangles as described in the following table.

Function	Description
FillRect	Repaints the interior of a rectangle.
FrameRect	Redraws the sides of a rectangle.
InvertRect	Inverts the colors that appear within the interior of a rectangle.


  34.2  Using Filled Shapes

This section contains a code sample that illustrates how to use filled shape functions. The example uses the main window procedure from an application that enables the user to draw ellipses, rectangles, and rectangles with rounded corners.

The user draws a filled shape by selecting a particular shape from the menu, positioning the cursor at the upper-left corner of the shape (or the shape's bounding rectangle in the case of an ellipse), and then dragging the mouse until the desired dimensions are obtained.

»This illustration« shows three filled shapes drawn using the code that follows.

To enable the user to draw filled shapes, include the following code in your application.

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)

HWND hwnd;      /* handle of window         */

UINT uMsg;      /* message                  */

WPARAM wParam;  /* first message parameter  */

LPARAM lParam;  /* second message parameter */

{

  HDC hdc;                    /* handle of device context (DC)        */

  PAINTSTRUCT ps;             /* paint data for Begin/EndPaint        */

  POINT ptClientUL;           /* client area upper-left corner        */

  POINT ptClientLR;           /* client area lower-right corner       */

  static HDC hdcCompat;       /* handle of DC for copying bitmap      */

  static POINT pt;            /* x- and y-coordinates of cursor       */

  static RECT rcTarget;       /* rectangle to receive filled shape    */

  static RECT rcClient;       /* client area rectangle                */

  static BOOL fSizeEllipse;   /* TRUE if ellipse is being sized       */

  static BOOL fDrawEllipse;   /* TRUE if ellipse is being drawn       */

  static BOOL fDrawRectangle; /* TRUE if rectangle is being drawn     */

  static BOOL fSizeRectangle; /* TRUE if rectangle is being sized     */

  static BOOL fSizeRoundRect; /* TRUE if rounded rect. is being sized */

  static BOOL fDrawRoundRect; /* TRUE if rounded rect. is being drawn */

  static int nEllipseWidth;   /* ellipse width for round corners      */

  static int nEllipseHeight;  /* ellipse height for round corners     */

    switch (uMsg) {

        case WM_COMMAND:

            switch (wParam) {

                /*

                 * Set the appropriate flag to indicate which

                 * filled shape the user is drawing.

                 */

                case IDM_ELLIPSE:

                    fSizeEllipse = TRUE;

                break;

                case IDM_RECTANGLE:

                    fSizeRectangle = TRUE;

                break;

                case IDM_ROUNDRECT:

                    fSizeRoundRect = TRUE;

                break;

                default:

                    return DefWindowProc(hwnd, uMsg, wParam, lParam);

            }

            break;

        case WM_CREATE:

            nEllipseWidth = 20;

            nEllipseHeight = 20;

            return 0;

        case WM_PAINT:

            BeginPaint(hwnd, &ps);

            /*

             * Because the default brush is white, select

             * a different brush into the device context

             * to demonstrate the painting of filled shapes.

             */

            SelectObject(ps.hdc, GetStockObject(GRAY_BRUSH));

            /*

             * If one of the filled shape "draw" flags is TRUE,

             * draw the corresponding shape.

             */

            if (fDrawEllipse) { /* draws ellipse */

                Ellipse(ps.hdc, rcTarget.left, rcTarget.top,

                    rcTarget.right, rcTarget.bottom);

                    fDrawEllipse = FALSE;

                    rcTarget.left = rcTarget.right = 0;

                    rcTarget.top = rcTarget.bottom = 0;

                    }

            if (fDrawRectangle) { /* Draws rectangle */

                Rectangle(ps.hdc, rcTarget.left, rcTarget.top,

                    rcTarget.right, rcTarget.bottom);

                    fDrawRectangle = FALSE;

                    rcTarget.left = rcTarget.right = 0;

                    rcTarget.top = rcTarget.bottom = 0;

                    }

            if (fDrawRoundRect) { /* Draws rounded rectangle */

                RoundRect(ps.hdc, rcTarget.left, rcTarget.top,

                    rcTarget.right, rcTarget.bottom,

                    nEllipseWidth, nEllipseHeight);

                    fDrawRectangle = FALSE;

                    rcTarget.left = rcTarget.right = 0;

                    rcTarget.top = rcTarget.bottom = 0;

                    }

            EndPaint(hwnd, &ps);

            break;

        case WM_SIZE:

            /*

             * Convert the client coordinates of the client area

             * rectangle to screen coordinates and save them in a

             * rectangle. The rectangle is passed to the ClipCursor

             * function during WM_LBUTTONDOWN processing.

             */

            GetClientRect(hwnd, &rcClient);

            ptClientUL.x = rcClient.left;

            ptClientUL.y = rcClient.top;

            ptClientLR.x = rcClient.right;

            ptClientLR.y = rcClient.bottom;

            ClientToScreen(hwnd, &ptClientUL);

            ClientToScreen(hwnd, &ptClientLR);

            SetRect(&rcClient, ptClientUL.x, ptClientUL.y,

                ptClientLR.x, ptClientLR.y);

            return 0;

        case WM_LBUTTONDOWN:

            /*

             * Restrict the cursor to the client area.

             * This ensures that the window receives a matching

             * WM_LBUTTONUP message.

             */

            ClipCursor(&rcClient);

            /* Save the coordinates of the cursor. */

            pt.x = (LONG) LOWORD(lParam);

            pt.y = (LONG) HIWORD(lParam);

            /*

             * If the user chooses one of the filled shapes,

             * set the appropriate flag to indicate that the

             * shape is being sized.

             */

             if (fDrawEllipse)

                fSizeEllipse = TRUE;

            return 0;

        case WM_MOUSEMOVE:

            /*

             *

             * If one of the "size" flags is set, draw

             * the target rectangle as the user drags

             * the mouse.

             */

            if ((wParam && MK_LBUTTON)

                    && (fSizeEllipse || fSizeRectangle

                    || fSizeRoundRect)) {  /* draws target rect. */

                /*

                 * Set the mixing mode so that the pen color is the

                 * inverse of the background color. The previous

                 * rectangle can then be erased by drawing

                 * another rectangle on top of it.

                 */

                hdc = GetDC(hwnd);

                SetROP2(hdc, R2_NOTXORPEN);

                /*

                 * If a previous target rectangle exists, erase

                 * it by drawing another rectangle on top.

                 */

                 if (!IsRectEmpty(&rcTarget))

                     Rectangle(hdc, rcTarget.left, rcTarget.top,

                         rcTarget.right, rcTarget.bottom);

                /*

                 * Save the coordinates of the target rectangle.

                 * Avoid invalid rectangles by ensuring that the

                 * value of the left coordinate is greater than

                 * that of the right, and that the value of the

                 * bottom coordinate is greater than that of

                 * the top.

                 */

                if ((pt.x < (LONG) LOWORD(lParam)) &&

                        (pt.y > (LONG) HIWORD(lParam)))

                    SetRect(&rcTarget, pt.x, HIWORD(lParam),

                        LOWORD(lParam), pt.y);

                else if ((pt.x > (LONG) LOWORD(lParam)) &&

                        (pt.y > (LONG) HIWORD(lParam)))

                    SetRect(&rcTarget, LOWORD(lParam),

                        HIWORD(lParam), pt.x, pt.y);

                else if ((pt.x > (LONG) LOWORD(lParam)) &&

                        (pt.y < (LONG) HIWORD(lParam)))

                    SetRect(&rcTarget, LOWORD(lParam), pt.y,

                        pt.x, HIWORD(lParam));

                else

                    SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam),

                        HIWORD(lParam));

                /* Draw the new target rectangle. */

                Rectangle(hdc, rcTarget.left, rcTarget.top,

                    rcTarget.right, rcTarget.bottom);

                ReleaseDC(hwnd, hdc);

            }

            return 0;

        case WM_LBUTTONUP:

            /*

             * If one of the "size" flags is TRUE, reset

             * it to FALSE, and then set the corresponding "draw" flag.

             * Invalidate the appropriate rectangle and issue

             * a WM_PAINT message.

             */

             if (fSizeEllipse) {

                 fSizeEllipse = FALSE;

                 fDrawEllipse = TRUE;

                }

             if (fSizeRectangle) {

                 fSizeRectangle = FALSE;

                 fDrawRectangle = TRUE;

                }

             if (fSizeRoundRect) {

                 fSizeRoundRect = FALSE;

                 fDrawRoundRect = TRUE;

                }

             if (fDrawEllipse || fDrawRectangle || fDrawRoundRect) {

                 InvalidateRect(hwnd, &rcTarget, TRUE);

                 UpdateWindow(hwnd);

                }

            /* Release the cursor. */

            ClipCursor((LPRECT) NULL);

            return 0;

        case WM_DESTROY:

            /*

             * Destroy the background brush, compatible bitmap,

             * and bitmap.

             */

            DeleteDC(hdcCompat);

            PostQuitMessage(0);

            break;

        default:

            return DefWindowProc(hwnd, uMsg, wParam, lParam);

    }

    return (LRESULT) NULL;

}


  34.3  Functions

The following functions are used with filled shapes.

Chord
Ellipse
FillRect
FrameRect
InvertRect
Pie
Polygon
PolyPolygon
Rectangle
RoundRect


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


35.1  About Fonts
  Chapter 35    Fonts and Text

35.1  About Fonts

Fonts are used to draw text on video displays and other output devices. Microsoft® Windows (™)  provides a set of functions that developers can use to install, select, and query different fonts.

To a person trained in the mechanics of manuscript composition or familiar with standard typography, some of the typographic terms used in Windows may be unusual. Most of the differences between standard typography and Windows reflect changes in technology. The original typographic terms were based on hot-metal composition, whereas the terms used in Windows, which appear as member names for the font and text output structures, reflect a new technology based on laser-printer output and composition performed on a personal computer using desktop publishing software.


  35.1.1  Fonts

In Windows, a font is a collection of characters and symbols that share a common design. The three major elements of this design are referred to as typeface, style, and size.

Typeface

The term typeface refers to specific characteristics of characters and symbols in the font such as the width of the thick and thin strokes that compose the characters and the presence or absence of serifs. A serif is the short cross line at the ends of an unconnected stroke. A font or typeface without serifs is usually called a sans-serif font.

Style

The term style refers to the weight and slant of a font. Font weights can range from thin to black. The following list identifies possible weights for Windows fonts (beginning with the lightest and ending with the heaviest).

Thin
Extralight
Light
Normal
Medium
Semibold
Bold
Extrabold
Heavy

Three terms categorize the slant of a Windows font: roman, oblique, and italic.

The characters in a roman font are upright. The characters in an oblique font are artificially slanted. The slant is achieved by performing a shear transformation on the characters from a roman font. The characters in an italic font are truly slanted and appear as they were designed. For more information on shearing, see Chapter 39, »Coordinate Spaces and Transformations«.

Size

In Windows, the size of a font is an imprecise value. It can generally be determined by measuring the distance from the bottom of a lowercase "g" to the top of an adjacent uppercase "M," as shown in »this illustration«.

A font's size is specified in units called points. A point is .013837 of an inch. Following the point system devised by Pierre Simon Fournier, it is common practice to approximate a point as 1/72 inch.

»This illustration« shows characters drawn using two different fonts. The first font, from the Century Gothic® typeface, measures 20 points and the second font, from the Bookman Old Style® typeface, measures 20 points. One distinguishing characteristic of the two typefaces is the stroke width: The vertical and horizontal strokes of the Century typeface are of equal width while the vertical strokes of the Bookman typeface are wider than the horizontal strokes. Another distinguishing characteristic is the absence or presence of serifs: the Century typeface does not contain serifs while the Bookman typeface does.


  35.1.2  Font Families

Windows organizes fonts by family; a family is a set of fonts having common stroke width and serif characteristics. Windows categorizes families with five family names. A sixth name ("Dontcare") allows an application to use the default font. The following table describes the font-family names.

Font-family name	Description
Decorative	Specifies a novelty font. An example is Old English.
Dontcare	Specifies a generic family name. This name is used when information about a font does not exist or does not matter.
Modern	Specifies a font that is fixed-pitch with or without serifs. Fixed-pitch fonts are usually modern; examples include Pica, Elite, and Courier New®.
Roman	Specifies a font that is variable pitch, with serifs. An example is Times New Roman.
Script	Specifies a font that is designed to look like handwriting; examples include Script and Cursive.
Swiss	Specifies a font that is fixed-pitch, without serifs. An example is Arial.
These family names correspond to constants found in the WINGDI.H file: FF_DECORATIVE, FF_DONTCARE, FF_MODERN, FF_ROMAN, FF_SCRIPT, and FF_SWISS. An application uses these constants when it creates a font, selects a font, or retrieves information about a font.

Fonts within a family are distinguished by size (10 point, 24 point, etc.) and style (regular, italic, etc.).


  35.1.3  Raster, Vector, and TrueType Fonts

Windows-based applications can use three different kinds of font technologies to display and print text: raster, vector, and TrueType. The differences between these fonts reflect the way that the glyph for each character or symbol is stored in the respective font-resource file. In raster fonts, a glyph is a bitmap that Windows uses to draw a character or symbol in the font. In vector fonts, a glyph is a collection of line endpoints that define the line segments Windows uses to draw a character or symbol in the font. In TrueType fonts, a glyph is a collection of line and curve commands as well as a collection of hints. Windows uses the line and curve commands to define the outline of the bitmap for a character or symbol in the TrueType font. Windows uses the hints to adjust the length of the lines and shapes of the curves used to draw the character or symbol. These hints and the respective adjustments are based on the amount of scaling used to reduce or increase the size of the bitmap.

Because the bitmaps for each glyph in a raster font are designed for a specific resolution of device, raster fonts are generally considered to be device dependent. Vector fonts, on the other hand, are not device dependent, because each glyph is stored as a collection of scalable lines. However, vector fonts are generally drawn more slowly than raster or TrueType fonts. TrueType fonts provide both relatively fast drawing speed and true device independence. By using the hints associated with a glyph, a developer can scale the characters from a TrueType font up or down and still maintain their original shape.

As previously mentioned, the glyphs for a font are stored in a font-resource file. A font-resource file is actually a Windows library that contains only data — there is no code. For raster and vector fonts, this data is divided into two parts: a header describing the font's metrics and the glyph data. A font-resource file for a raster or vector font is identified by the .FON filename extension. For TrueType fonts, there are two files for each font: the first file contains a relatively short header and the second contains the actual font data. The first file is identified by a .FOT extension and the second is identified by a .TTF extension.


  35.1.4  Character Sets Used by Fonts

All fonts use a character set. A character set contains punctuation marks, numerals, uppercase and lowercase letters, and all other printable characters. Each element of a character set is identified by a number.

Most character sets used in Windows are supersets of the U.S. ASCII character set, which defines characters for the 96 numeric values from 32 through 127. There are five major groups of character sets:

•	Windows

•	Unicode (™)

•	OEM (original equipment manufacturer)

•	Symbol

•	Vendor-specific

Windows Character Set

The Windows character set is the most commonly used character set in Windows programming. It is essentially equivalent to the ANSI character set. The blank character is the first character in the Windows character set. It has a hexadecimal value of 0x20 (decimal 32). The last character in the Windows character set has a hexadecimal value of 0xFF (decimal 255).

Many fonts specify a default character. Whenever a request is made for a character that is not in the font, Windows provides this default character. Many fonts using the Windows character set specify the period (.) as the default character. TrueType fonts typically use an open box as the default character.

Fonts use a break character called a quad to separate words and justify text. Most fonts using the Windows character set specify that the blank character will serve as the break character.

Windows version 3.1 added 24 characters to the Windows code page, as shown in the following table.

Character	Name	Windows character code
‚	base line single quote	130
å	florin	131
„	base line double quote	132
…	ellipsis	133
†	dagger	134
‡	double dagger	135
ˆ	circumflex	136
‰	permille	137
Š	S Hacek	138
‹	left single guillemet	139
Œ	OE ligature	140
'	left single quote	145
'	right single quote	146
"	left double quote	147
"	right double quote	148
	bullet	149
−	en dash	150
—	em dash	151
˜	tilde	152
œ	trademark ligature	153
š	s Hacek	154
	right single guillemet	155
œ	oe ligature	156
Ÿ	Y Dieresis	159
It should be noted that the characters for left and right single quote were first added to the character set for the release of Windows version 3.0.

Unicode Character Set

The Windows ANSI character uses 8 bits to represent each character; therefore, the maximum number of characters that can be expressed using 8 bits is 256 (28). This is usually sufficient for Western languages, including the diacritical marks used in French, German, Spanish, and other languages. However, Eastern languages employ thousands of separate characters, which cannot be encoded by using a single-byte coding scheme. With the proliferation of computer commerce, double-byte coding schemes were developed so that characters could be represented in 8-bit, 16-bit, 24-bit, or 32-bit sequences. This requires complicated passing algorithms; even so, using different code sets could yield entirely different results on two different computers.

To address the problem of multiple coding schemes, the Unicode standard for data representation was developed. A 16-bit character coding scheme, Unicode can represent 65,536 (216) characters, which is enough to include all languages in computer commerce today, as well as punctuation marks, mathematical symbols, and room for future expansion. Unicode establishes a unique code for every character to ensure that character translation is always accurate.

OEM Character Set

The OEM character set is typically used in full-screen MS-DOS® sessions for screen display. Characters 32 through 127 are usually the same in the OEM, U.S. ASCII, and Windows character sets. The other characters in the OEM character set (0 through 31 and 128 through 255) correspond to the characters that can be displayed in a full-screen MS-DOS session. These characters are generally different from the Windows characters.

Symbol Character Set

The Symbol character set contains special characters typically used to represent mathematical and scientific formulas.

Vendor-Specific Character Sets

Many printers and other output devices provide fonts based on character sets that differ from the Windows and OEM sets — for example, the Extended Binary Coded Decimal Interchange Code (EBCDIC) character set. To use one of these character sets, the printer driver translates from the Windows character set to the vendor-specific character set.


  35.1.5  Font Installation and Deletion

A font must already be resident on a given device or installed in the Windows font table in order for an application to draw text using glyphs from that font. The Windows font table is an internal array that identifies all nondevice fonts that are available to a Windows-based application. An application can retrieve the names of fonts currently installed on a device and stored in the internal font table by calling the EnumFonts or ChooseFont function.

An application can install a font by calling one of the two font installation functions: AddFontResource or AddFontModule. The AddFontResource function loads a font that is stored in a font-resource file. The AddFontModule function loads a font that is stored as a resource in a Windows executable file or a dynamic-link library (DLL). Because fonts are typically stored in font-resource files, applications call the AddFontResource function in most cases; however, there are some instances where an application stores a font resource for a unique font as part of the executable file or as part of a DLL. In these cases, the application must call AddFontModule to extract the font resource and install it.

In the case of TrueType fonts, an additional step is sometimes necessary before the font can be installed in the font table. Some font manufacturers ship only the TrueType font-data files (identified by the .TTF extension). Before Windows can load these fonts, it requires a corresponding header file (identified by the .FOT extension). To create this header file, an application must call the CreateScalableFontResource function and pass the name of the font-data file as the third parameter. When this header file is created, an application can install the font by calling the AddFontResource function and passing the name of the new header file.

When an application finishes using an installed font, it must remove that font by calling either the RemoveFontResource function (for fonts installed with the AddFontResource function) or the RemoveFontModule function (for fonts installed by calling the AddFontModule function).

Whenever an application calls the functions that add and delete font resources, it should also call the SendMessage function and send a WM_FONTCHANGE message to all top-level windows in the system. This message notifies other applications that the internal font table has been altered by an application that added or removed a font.


  35.1.6  Font Creation and Selection

Previous versions of Windows required that the application developer provide source code and a dialog box template to support an interface that displayed the available fonts from which the user could choose. The new Font common dialog box simplifies the creation and selection process. By initializing the CHOOSEFONT structure and calling the ChooseFont function, an application can support the same font-selection interface that previously required many lines of code. (For more information about the Font common dialog box, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.) »This illustration« shows the dialog box displayed when an application calls the ChooseFont function.

Selection by the User

Most font creation and selection operations involve the user. For example, word processing applications let the user select unique fonts for headings, footnotes, and body text. After the user selects a font by using the Font dialog box and presses the OK button, the ChooseFont function initializes the members of a LOGFONT structure with the attributes of the requested font. To use this font for text-output operations, an application must first create a logical font and then select that font into its device context. A logical font is an application-supplied description of an ideal font. A developer can create a logical font by calling the CreateFont or the CreateFontIndirect functions. In this case, the application would call CreateFontIndirect and supply a pointer to the LOGFONT structure initialized by ChooseFont. In general, it is more efficient to call CreateFontIndirect because CreateFont requires 4 parameters while CreateFontIndirect requires only 1, a pointer to LOGFONT.

Before an application can actually begin drawing text with a logical font, it must find the closest match from the fonts stored internally on the device and the fonts whose resources have been loaded into the operating system. The fonts stored on the device or in the operating system are called physical fonts. The process of finding the physical font that most closely matches a specified logical font is referred to as font mapping. This process occurs when an application calls the SelectObject function and supplies a handle identifying a logical font. Font mapping is performed by using an internal algorithm that compares the attributes of the requested logical font against the attributes of available physical fonts. When the font mapper algorithm completes its search and determines the closest possible match, the SelectObject function returns and the application can begin drawing text with the new font.

The SetMapperFlags function specifies whether or not the font mapper algorithm searches only for physical fonts with aspect ratios that match the physical device. The aspect ratio for a device is the ratio formed by the width and the height of a pixel on that device.


  35.1.6.1  Special Font Selection Considerations

Although most font selection operations involve the user, there are some instances where this is not true. For example, a developer may want to use a unique font in an application to draw text in a control window. To select an appropriate font, the application must be able to determine what fonts are available, create a logical font that describes one of these available fonts, and then select that font into the appropriate device context.

An application can enumerate the available fonts by using the EnumFontFamilies function. This can be useful when an application must determine which fonts are available from a given family. (The EnumFonts function is an obsolete version of the EnumFontFamilies function.)

Once an application has enumerated the available fonts and located an appropriate match, it should use the values returned by the font enumeration function to initialize the members of a LOGFONT structure and call the CreateFontIndirect function, passing a pointer to the initialized LOGFONT structure. If the CreateFontIndirect function is successful, the application can select the logical font by calling the SelectObject function.


  35.1.7  Embedded Fonts

Embedding a font is the technique of bundling a document and the fonts it contains into a file for transmission to another computer. Embedding a font guarantees that a font specified in a transmitted file will be present on the computer receiving the file. Not all fonts can be moved from computer to computer, however, since most fonts are licensed to only one computer at a time. In Windows, only TrueType fonts can be embedded.

Applications should embed a font in a document only when requested by a user. An application cannot be distributed along with documents that contain embedded fonts, nor can an application itself contain an embedded font. Whenever an application distributes a font, in any format, the proprietary rights of the owner of the font must be acknowledged.

It may be a violation of a font vendor's proprietary rights and/or user license agreement to embed any fonts where embedding is not permitted or to fail to observe the following guidelines on embedding fonts. A font's license may give only read-write permission for a font to be installed and used on the destination computer; or it may give read-only permission. Read-only permission allows a document to be viewed and printed (but not modified) by the destination computer; documents with read-only embedded fonts are themselves read-only. Read-only embedded fonts may not be unbundled from the document and installed on the destination computer.

An application can determine the license status, and thus whether or not a font can be embedded in a document, by calling the GetOutlineTextMetrics function and examining the otmfsType member of the OUTLINETEXTMETRIC structure. If bit 1 of otmfsType is set, embedding is not permitted for the font. If bit 1 is clear, the font can be embedded. If bit 2 is set, the embedding is read-only.

To determine if a font can be embedded, an application can use the GetFontData function to read the font file. Setting the dwTable and dwOffset parameters of GetFontData to 0L and the cbData parameter to −1L ensures that the application reads the entire font file from the beginning.

After an application retrieves the font data, it can store the data with the document by using any applicable format. Most applications build a font directory in the document, listing the embedded fonts and whether the embedding is read-write or read-only. An application can use the otmpStyleName and otmFamilyName members of the OUTLINETEXTMETRIC structure to identify the font.

If the read-only bit is set for the embedded font, applications must encrypt the font data before storing it with the document. The encryption method need not be complicated; for example, using the XOR operator to combine the font data with an application-specified constant is adequate and fast.


  35.2  About Text Output

Text output is the most common type of graphic output found within the client area of Windows-based applications. It is used by Windows-based applications in different ways. Word processing and desktop publishing applications create documents with formatted text; spreadsheet applications use text, numbers, and symbols to specify formulas, label columns, and list values; database applications create records and display queries with text, and CAD applications use text to label objects and display dimensions.

The Win32 application programming interface (API) provides a complete set of functions to format and draw text in an application's client area and on a page of printer paper. These functions can be divided into two categories: those that format the text (or prepare it for output) and those that actually draw the text. The formatting functions align text, set the intercharacter spacing, set the text and text-background colors, and justify text. The drawing functions draw individual characters (or symbols) or entire strings of text.


  35.2.1  Formatting Text

The formatting functions can be divided into three categories: those that retrieve or set the text-formatting attributes for a device context, those that retrieve character widths, and those that retrieve string widths and heights.


  35.2.1.1  Text-Formatting Attributes

An application can use six functions to set the text-formatting attributes for a device context: SetBKColor, SetBKMode, SetTextAlign, SetTextCharacterExtra, SetTextColor, and SetTextJustification. These functions affect the text alignment, the intercharacter spacing, the text justification, and text and background colors. In addition to these six functions, six other functions can be used to retrieve the current text formatting attributes for any device context: GetBkColor, GetBkMode, GetTextAlign, GetTextCharacterExtra, GetTextColor, and GetTextExtentPoint.

Text Alignment

Applications can use the SetTextAlign function to specify how Windows should position the characters in a string of text when they call one of the drawing functions. This function can be used to position headings, page numbers, callouts, and so on. Windows positions a string of text by aligning a reference point on an imaginary rectangle that surrounds the string, with the current cursor position or with a point passed as an argument to one of the text drawing functions. The SetTextAlign function lets the application specify the location of this reference point. The list below identifies the possible reference point locations.

Location	Description
left/bottom	The reference point is located at the bottom-left corner of the rectangle.
left/base line	The reference point is located at the intersection of the character-cell base line and the left edge of the rectangle.
left/top	The reference point is located at the top-left corner of the rectangle.
center/bottom	The reference point is located at the center of the bottom of the rectangle.
center/base line	The reference point is located at the intersection of the character-cell base line and the center of the rectangle.
center/top	The reference point is located at the center of the top of the rectangle.
right/bottom	The reference point is located at the bottom-right corner of the rectangle.
right/base line	The reference point is located at the intersection of the character-cell base line and the right edge of the rectangle.
right/top	The reference point is located at the top-right corner of the rectangle.
(For a description of the character-cell base line, see Section 35.1, »About Fonts«.)

»This illustration« shows a string of text drawn by calling the TextOut function. Before drawing the text, the SetTextAlign function was called to relocate the reference point at each one of the nine possible locations.

The default text alignment for a device context is the upper left corner of the imaginary rectangle that surrounds the text. An application can retrieve the current text alignment setting for any device context by calling the GetTextAlign function.

Intercharacter Spacing

Applications can use the SetTextCharacterExtra function to alter the intercharacter spacing for all text output operations in a given device context. »This illustration« shows a string of text drawn twice by calling the TextOut function. Before drawing the text the second time, the SetTextCharacterExtra function was called to increment the intercharacter spacing.

The default intercharacter spacing value for any device context is zero. An application can retrieve the current intercharacter spacing value for a device context by calling the GetTextCharacterExtra function.

Text Justification

Applications can use the GetTextExtentPoint and SetTextJustification functions to justify a line of text. Text justification is a common operation in any desktop publishing and in most word processing applications. The GetTextExtentPoint function computes the width and height of a string of text. After the width is computed, the application can call the SetTextJustification function to distribute extra spacing between each of the words in a line of text. »This illustration« shows a paragraph of text printed twice: in the first paragraph, the text was not justified; in the second paragraph, the text was justified by calling the GetTextExtentPoint and SetTextJustification functions.

Text and Background Color

Applications can use the SetTextColor function to set the color of text drawn in the client-area of their windows, as well as the color of text drawn on a color printer. An application can use the SetBkColor function to set the color that appears behind each character and the SetBkMode function to specify how Windows should blend the selected background color with the current color(s) on the video display.

The default text color for a display device context is black; the default background color is white; and the default background mode is opaque. An application can retrieve the current text color for a device context by calling the GetTextColor function. An application can retrieve the current background color for a device context by calling the GetBkColor function and the current background mode by calling the GetBkMode function.


  35.2.1.2  Character Widths

Applications need to retrieve character-width data when they fit strings of text to page or column widths as they prepare to alter the appearance of a string of text, and so forth. There are four functions that an application can use to retrieve character-width data. Two of these functions retrieve the character-advance width and two of these functions retrieve actual character-width data.

An application can use the GetCharWidth and GetCharWidthFloat functions to retrieve the advance width for individual characters or symbols in a string of text. The advance width is the distance that the cursor on a video display or the print-head on a printer must advance before printing the next character in a string of text. The GetCharWidth function returns the advance width as an integer value. If greater precision is required, an application can use the GetCharWidthFloat function to retrieve fractional advance-width values.

An application can retrieve actual character-width data by using the GetCharABCWidths and GetCharABCWidthsFloat functions. To retrieve character widths for characters in a string of text that will be printed using a TrueType font, an application can call the GetCharABCWidths function; however, for any other font, the application should call the GetCharABCWidthsFloat function. (For more information about TrueType fonts, see Section 35.1, »About Fonts«). »This illustration« shows the three components of the ABC width:

The "A" spacing is the width to add to the current position before placing the character. The "B" spacing is the width of the character itself. The "C" spacing is the white space to the right of the character. The total advance width is determined by calculating the sum of A+B+C. The character cell is an imaginary rectangle that surrounds each character or symbol in a Windows font. Because characters can overhang or underhang the character cell, either or both of the A and C increments can be a negative number.


  35.2.1.3  String Widths and Heights

In addition to retrieving character-width data for individual characters, applications also need to compute the width and height of entire strings. Two functions retrieve string-width and height measurements: GetTextExtentPoint, and GetTabbedTextExtent. If the string does not contain tab characters, an application can use the GetTextExtentPoint function to retrieve the width and height of a specified string. If the string contains tab characters, an application should call the GetTabbedTextExtent function.

Windows also supports a special function that applications can use for word-wrapping operations called GetTextExtentExPoint. This function returns the number of characters from a specified string that fit within a given space.

Font Ascenders and Descenders

Some applications determine the line spacing between text lines of different sizes by using a font's maximum ascender and descender. An application can retrieve these values by calling the GetTextMetrics function and then checking the tmAscent and tmDescent members of the TEXTMETRIC or NEWTEXTMETRIC structure. (The TEXTMETRIC structure is returned for raster fonts; the NEWTEXTMETRIC structure is returned for TrueType fonts).

The maximum ascent and descent are different from the typographic ascent and descent; in TrueType fonts, the typographic ascent and descent are typically the top of the "f" glyph and bottom of the "g" glyph. An application can retrieve the typographic ascender and descender for a TrueType font by calling the GetOutlineTextMetrics function and checking the values in the otmMacAscent and otmMacDescent members of the OUTLINETEXTMETRIC structure. It is important to note that TrueType font metrics do not correspond exactly to the metrics for Windows raster fonts, because TrueType font metrics have been designed by Apple Computer, Inc. for consistency across a variety of display and output devices.

»This illustration« shows the difference between the vertical text metric values returned in the NEWTEXTMETRIC and OUTLINETEXTMETRIC structures. (The names beginning with otm are members of the OUTLINETEXTMETRIC structure.)

Font Dimensions

An application can retrieve the physical dimensions of a TrueType font by calling the GetOutlineTextMetrics function. An application can retrieve the physical dimensions of any other font by calling the GetTextMetrics function. To determine the dimensions of an output device, an application can call the GetDeviceCaps function. GetDeviceCaps returns both physical and logical dimensions.

A logical inch is a measure Windows uses to present legible fonts on the screen and is approximately 30 to 40 percent larger than a physical inch. The use of logical inches precludes an exact match between the output of the screen and printer. Developers should be aware that the text on a screen is not simply a scaled version of the text that will appear on the page, particularly if graphics are incorporated into the text.


  35.2.2  Drawing Text

After an application selects the appropriate font, sets the required text-formatting options, and computes the necessary character width and height values for a string of text, it can begin drawing characters and symbols by calling any of the four text-output functions. Two of these functions, DrawText and TabbedTextOut, are part of Window Manager and the remaining two functions are part of GDI. When an application calls one of these functions, the operating system passes the call to the graphics engine, which in turn passes the call to the appropriate device driver. At the device driver level, all of these calls are supported by one or more calls to the driver's own ExtTextOut or TextOut function. An application will achieve the fastest execution by calling the ExtTextOut function, which is quickly converted into an ExtTextOut call for the device. However, there are instances when an application should call one of the other three functions; for example, to draw multiple lines of text within the borders of a specified rectangular region, it is more efficient to call the DrawText function. To create a multicolumn table with justified columns of text, it is more efficient to call the TabbedTextOut function.


  35.3  Using the Font and Text-Output Functions

This section describes how you can use the font and text-output functions to draw normal text, draw text from different fonts on the same line, rotate lines of text, display the font-selection common dialog-box, enumerate fonts, and so on.


  35.3.1  Using a Stock Font to Draw Text

Windows provides six stock fonts. A stock font is a logical font that an application can obtain by calling the GetStockObject function and passing a value that identifies the requested font. The following list contains the six values that you can specify to obtain a stock font.

Value	Meaning
ANSI_FIXED_FONT	Specifies a fixed-pitch font based on the Windows character set. A Courier font is typically used.
ANSI_VAR_FONT	Specifies a variable-pitch font based on the Windows character set. MS Sans Serif is typically used.
DEVICE_DEFAULT_FONT	Specifies the preferred font for the given device. This is typically the System font for display devices; however, for some dot-matrix printers this is a font that is resident on the device. (Printing with this font is usually faster than printing with a downloaded, bitmapped font).
OEM_FIXED_FONT	Specifies a fixed-pitch font based on an OEM character set. For IBM® computers and compatibles, the OEM font is based on the IBM PC character set.
SYSTEM_FONT	Specifies the System font. This is a variable-pitch font based on the Windows character set, and is used by the operating system to display window titles, menu names, and text in dialog boxes. The System font is always available. Other fonts are available only if they have been installed.
SYSTEM_FIXED_FONT	Specifies a fixed-pitch font compatible with the System font in Windows versions earlier than 3.0.
The following example retrieves a handle of the Windows variable stock font, selects it into a device context, and then writes a string using that font:

HFONT hfnt, hOldFont;

    hfnt = GetStockObject(ANSI_VAR_FONT);

    if (hOldFont = SelectObject(hdc, hfnt)) {

        TextOut(hdc, 10, 50, "Sample ANSI_VAR_FONT text.", 26);

        SelectObject(hdc, hOldFont);

    }

If other stock fonts are not available, GetStockObject returns a handle to the System font (SYSTEM_FONT). You should use stock fonts only if the mapping mode for your application's device context is MM_TEXT.


  35.3.2  Creating a Logical Font

You can use the Font common dialog box to display available fonts. The ChooseFont dialog box is displayed after an application initializes the members of a CHOOSEFONT structure and calls the ChooseFont function. After the user chooses one of the available fonts and presses the OK button, the ChooseFont function initializes a LOGFONT structure with the relevant data. Your application can then call the CreateLogFont function and create a logical font based on the user's request. The following example demonstrates how this is done.

HFONT FAR PASCAL MyCreateFont( void )

{

CHOOSEFONT cf;

LOGFONT lf;

HFONT hfont;

    /* Initialize members of the CHOOSEFONT structure. */

    cf.lStructSize = sizeof(CHOOSEFONT);

    cf.hwndOwner = (HWND)NULL;

    cf.hDC = (HDC)NULL;

    cf.lpLogFont = &lf;

    cf.iPointSize = 0;

    cf.Flags = CF_SCREENFONTS;

    cf.rgbColors = RGB(0,0,0);

    cf.lCustData = 0L;

    cf.lpfnHook = (LPCFHOOKPROC)NULL;

    cf.lpTemplateName = (LPSTR)NULL;

    cf.hInstance = (HINSTANCE) NULL;

    cf.lpszStyle = (LPSTR)NULL;

    cf.nFontType = SCREEN_FONTTYPE;

    cf.nSizeMin = 0;

    cf.nSizeMax = 0;

    /* Display the CHOOSEFONT common-dialog box. */

    ChooseFont(&cf);

    /* Create a logical font based on the user's   */

    /* selection and return a handle identifying   */

    /* that font. */

    hfont = CreateFontIndirect(cf.lpLogFont);

    return (hfont);

}


  35.3.3  Enumerating the Installed Fonts

In some instances, an application must be able to enumerate the available fonts and select the one most appropriate for a particular operation. An application can enumerate the available fonts by calling the EnumFonts or EnumFontFamilies function. These functions send information about the available fonts to a callback function that the application supplies. The callback function receives information in LOGFONT and NEWTEXTMETRIC structures. (The NEWTEXTMETRIC structure contains information about a TrueType font. When the callback function receives information about a non-TrueType font, the information is contained in a TEXTMETRIC structure.) By using this information, an application can limit the user's choices to only those fonts that are available.

The EnumFontFamilies function is similar to the EnumFonts function but includes some extra functionality. EnumFontFamilies allows an application to take advantage of styles available with TrueType fonts. New and upgraded applications should use EnumFontFamilies instead of EnumFonts.

In previous versions of Windows, the only style attributes were weight and italic; any other styles were specified in the family name for the font. For example, when an application used the EnumFonts function to query the available Courier fonts, EnumFonts might return information for Courier, Courier Bold, Courier Bold Italic, and Courier Italic. It would not return information about any other Courier fonts that might be installed, because any other Courier fonts would typically have a different family name.

TrueType fonts are organized around a family name (for example, Courier New) and style names (for example, italic, bold, and extra-bold). The EnumFontFamilies function enumerates all the styles associated with a given family name, not simply the bold and italic attributes; when the system includes a TrueType font called Courier New Extra-Bold, EnumFontFamilies lists it with the other Courier New fonts. The capabilities of EnumFontFamilies are helpful for fonts with many or unusual styles and for fonts that cross international borders.

If an application does not supply a typeface name, the EnumFonts and EnumFontFamilies functions supply information about one font in each available family. To enumerate all the fonts in a device context, the application can specify NULL for the typeface name, compile a list of the available typefaces, and then list each font in each typeface.

The following example uses the EnumFontFamilies function to retrieve the number of available raster, vector, and TrueType font families.

    UINT uAlignPrev;

    int aFontCount[] = { 0, 0, 0 };

    char szCount[8];

    EnumFontFamilies(hdc, (LPCTSTR) NULL,

        (FONTENUMPROC) EnumFamCallBack, (LPARAM) aFontCount);

    uAlignPrev = SetTextAlign(hdc, TA_UPDATECP);

    MoveToEx(hdc, 10, 50, (LPPOINT)NULL);

    TextOut(hdc, 0, 0, "Number of raster fonts: ", 24);

    itoa(aFontCount[0], szCount, 10);

    TextOut(hdc, 0, 0, szCount, strlen(szCount));

    MoveToEx(hdc, 10, 75, (LPPOINT)NULL);

    TextOut(hdc, 0, 0, "Number of vector fonts: ", 24);

    itoa(aFontCount[1], szCount, 10);

    TextOut(hdc, 0, 0, szCount, strlen(szCount));

    MoveToEx(hdc, 10, 100, (LPPOINT)NULL);

    TextOut(hdc, 0, 0, "Number of TrueType fonts: ", 26);

    itoa(aFontCount[2], szCount, 10);

    TextOut(hdc, 0, 0, szCount, strlen(szCount));

    SetTextAlign(hdc, uAlignPrev);

        .

        .

        .

BOOL FAR PASCAL EnumFamCallBack(lplf, lpntm, FontType, aFontCount)

LPLOGFONT lplf;

LPNEWTEXTMETRIC lpntm;

DWORD FontType;

LPVOID aFontCount;

{

    int far * aiFontCount = (int far *) aFontCount;

    /*

     * Record the number of raster, TrueType, and vector

     * fonts in the font-count array.

     */

    if (FontType & RASTER_FONTTYPE)

        aiFontCount[0]++;

    else if (FontType & TRUETYPE_FONTTYPE)

        aiFontCount[2]++;

    else

        aiFontCount[1]++;

    if (aiFontCount[0] || aiFontCount[1] || aiFontCount[2])

        return TRUE;

    else

        return FALSE;

    UNREFERENCED_PARAMETER( lplf );

    UNREFERENCED_PARAMETER( lpntm );

}

This example uses two masks, RASTER_FONTTYPE and TRUETYPE_FONTTYPE, to determine the type of font being enumerated. If the RASTER_FONTTYPE bit is set, the font is a raster font. If the TRUETYPE_FONTTYPE bit is set, the font is a TrueType font. If neither bit is set, the font is a vector font. A third mask, DEVICE_FONTTYPE, is set when a device (for example, a laser printer) supports downloading TrueType fonts; it is zero if the device is a display adapter, dot-matrix printer, or other raster device. An application can also use the DEVICE_FONTTYPE mask to distinguish GDI-supplied raster fonts from device-supplied fonts. Windows can simulate bold, italic, underline, and strikeout attributes for GDI-supplied raster fonts, but not for device-supplied fonts.

An application can also check bits 1 and 2 in the tmPitchAndFamily member of the NEWTEXTMETRIC structure to identify a TrueType font. If bit 1 is 0 and bit 2 is 1, the font is a TrueType font.

Vector fonts are categorized as OEM_CHARSET instead of ANSI_CHARSET. Some applications identify vector fonts by using this information, checking the tmCharSet member of the NEWTEXTMETRIC structure. This categorization usually prevents the font mapper from choosing vector fonts unless they are specifically requested. (Most applications no longer use vector fonts, because their strokes are single lines and they take longer to draw than TrueType fonts, which offer many of the same scaling and rotation features that required vector fonts in earlier versions of Windows.)


  35.3.4  Checking the Text Capabilities of a Device

You can use the EnumFonts and EnumFontFamilies functions to enumerate the fonts that are available in a printer-compatible memory device context. You can also use the GetDeviceCaps function to retrieve information about the text capabilities of a device. By calling the GetDeviceCaps function with the NUMFONTS index, you can determine the minimum number of fonts supported by a printer. (An individual printer may support more fonts than specified in the return value from GetDeviceCaps with the NUMFONTS index.) By using the TEXTCAPS index, you can identify many of the text capabilities of the specified device.


  35.3.5  Setting the Text Alignment

You can query and set the text alignment for a device context by using the GetTextAlign and SetTextAlign functions. The text-alignment settings determine how text is positioned relative to a given location. Text can be aligned to the right or left of the position or centered over it; it can also be aligned above or below the point.

The following example shows a method for determining which horizontal alignment flag is set:

switch ((TA_LEFT | TA_RIGHT | TA_CENTER) & GetTextAlign(hdc))

{

case TA_LEFT:

   .

   .

   .

case TA_RIGHT:

   .

   .

   .

case TA_CENTER:

   .

   .

   .

}

You can also use the SetTextAlign function to update the current position when a text-output function is called. For instance, the following example uses the SetTextAlign function to update the current position when the TextOut function is called. In this example, the cArial parameter is an integer that specifies the number of Arial fonts.

UINT uAlignPrev;

char szCount[8];

uAlignPrev = SetTextAlign(hdc, TA_UPDATECP);

MoveToEx(hdc, 10, 50, (LPPOINT) NULL);

TextOut(hdc, 0, 0, "Number of Arial fonts: ", 23);

itoa(cArial, szCount, 10);

TextOut(hdc, 0, 0, (LPSTR) szCount, strlen(szCount));

SetTextAlign(hdc, uAlignPrev);


  35.3.6  Drawing Text From Different Fonts on the Same Line

Different type styles within a font family can have different widths. For example, bold and italic styles of a family are always wider than the roman style for a given point size. When you display or print several type styles on a single line, you must keep track of the width of the line to avoid having characters displayed or printed on top of one another.

You can use two functions to retrieve the width (or extent) of text in the current font. The GetTabbedTextExtent function computes the width and height of a character string. If the string contains one or more tab characters, the width of the string is based upon a specified array of tab-stop positions. The GetTextExtent function computes the width and height of a line of text.

When necessary, Windows synthesizes a font by changing the character bitmaps. To synthesize a character in a bold font, Windows draws the character twice: once at the starting point, and again one pixel to the right of the starting point. To synthesize a character in an italic font, Windows draws two rows of pixels at the bottom of the character cell, moves the starting point one pixel to the right, draws the next two rows, and continues until the character has been drawn. By shifting pixels, each character appears to be sheared to the right. The amount of shear is a function of the height of the character.

One way to write a line of text that contains multiple fonts is to use the GetTextExtent function after each call to TextOut and add the length to a current position. The following example writes the line "This is a sample string." using bold characters for "This is a", switches to italic characters for "sample", then returns to bold characters for "string." After printing all the strings, it restores the system default characters.

int XIncrement;

int YStart;

TEXTMETRIC tm;

HFONT hfntDefault, hfntItalic, hfntBold;

SIZE sz;

LPSTR lpszString1 = "This is a ";

LPSTR lpszString2 = "sample ";

LPSTR lpszString3 = "string.";

/* Create a bold and an italic logical font. */

hfntItalic = MyCreateFont();

hfntBold = MyCreateFont();

/* Select the bold font and draw the first string         */

/* beginning at the specified point (XIncrement, YStart). */

XIncrement = 10;

YStart = 50;

hfntDefault = SelectObject(hdc, hfntBold);

TextOut(hdc, XIncrement, YStart, lpszString1,

        lstrlen(lpszString1));

/*

 * Compute the length of the first string and add

 * this value to the x-increment that is used for the

 * text-output operation.

 */

GetTextExtentPoint(hdc, lpszString1,

                   lstrlen(lpszString1), &sz);

XIncrement += sz.cx;

/*

 * Retrieve the overhang value from the TEXTMETRIC

 * structure and subtract it from the x-increment.

 * (This is only necessary for non-TrueType raster

 * fonts.)

 */

GetTextMetrics(hdc, &tm);

XIncrement -= tm.tmOverhang;

/*

 * Select an italic font and draw the second string

 * beginning at the point (XIncrement, YStart).

 */

hfntBold = SelectObject(hdc, hfntItalic);

GetTextMetrics(hdc, &tm);

XIncrement -= tm.tmOverhang;

TextOut(hdc, XIncrement, YStart, lpszString2,

        lstrlen(lpszString2));

/*

 * Compute the length of the second string and add

 * this value to the x-increment that is used for the

 * text-output operation.

 */

GetTextExtentPoint(hdc, lpszString2, lstrlen(lpszString2), &sz);

XIncrement += sz.cx;

/*

 * Re-select the bold font and draw the third string

 * beginning at the point (XIncrement, YStart).

 */

SelectObject(hdc, hfntBold);

TextOut(hdc, XIncrement - tm.tmOverhang, YStart, lpszString3,

            lstrlen(lpszString3));

/* Re-select the original font. */

SelectObject(hdc, hfntDefault);

/* Delete the bold and italic fonts. */

DeleteObject(hfntItalic);

DeleteObject(hfntBold);

In this example, the GetTextExtentPoint function initializes the members of a SIZE structure with the length and height of the specified string. The GetTextMetrics function retrieves the overhang for the current font. Because the overhang is zero if the font is a TrueType font, the overhang value does not change the string placement. For raster fonts, however, it is important to use the overhang value.

The overhang is subtracted from the bold string once, to bring subsequent characters closer to the end of the string if the font is a raster font. Because overhang affects both the beginning and end of the italic string in a raster font, the glyphs start at the right of the specified location and end at the left of the endpoint of the last character cell. (The GetTextExtent function retrieves the extent of the character cells, not the extent of the glyphs.) To account for the overhang in the raster italic string, the example subtracts the overhang before placing the string and subtracts it again before placing subsequent characters.

The SetTextJustification function adds extra space to the break characters in a line of text. You can use the GetTextExtent function to determine the extent of a string, then subtract that extent from the total amount of space the line should occupy, and use the SetTextJustification function to distribute the extra space among the break characters in the string. The SetTextCharacterExtra function adds extra space to every character cell in the selected font, including the break character. (You can use the GetTextCharacterExtra function to determine the current amount of extra space being added to the character cells; the default setting is zero.)

You can place characters with greater precision by using the GetCharWidth or GetCharABCWidths function to retrieve the widths of individual characters in a font. The GetCharABCWidths function is more accurate than the GetCharWidth function, but only when it is used with TrueType fonts; when you use GetCharABCWidths with non-TrueType fonts, it retrieves the same information as GetCharWidth.

ABC spacing also allows an application to perform very accurate text alignment. For example, when the application right aligns a raster roman font without using ABC spacing, the advance width is calculated as the character width. This means the white space to the right of the glyph in the bitmap is aligned, not the glyph itself. By using ABC widths, applications have more flexibility in the placement and removal of white space when aligning text, because they have information that allows them to finely control intercharacter spacing.


  35.3.7  Rotating Lines of Text

You can rotate TrueType fonts at any angle. This is useful for labeling charts and other illustrations. The following example rotates a string in 10-degree increments around the center of the client area by changing the value of the lfEscapement and lfOrientation members of the LOGFONT structure used to create the font.

RECT rc;

int angle;

HFONT hfnt, hfntPrev;

LPSTR lpszRotate = "String to be rotated.";

/* Allocate memory for a LOGFONT structure. */

PLOGFONT plf = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));

/* Specify a font typeface name and weight. */

lstrcpy(plf->lfFaceName, "Arial");

plf->lfWeight = FW_NORMAL;

/* Retrieve the client-rectangle dimensions. */

GetClientRect(hwnd, &rc);

/*

 * Set the background mode to transparent for the

 * text-output operation.

 */

SetBkMode(hdc, TRANSPARENT);

/*

 * Draw the string 36 times, rotating 10 degrees

 * counter-clockwise each time.

 */

for (angle = 0; angle < 3600; angle += 100) {

    plf->lfEscapement = angle;

    hfnt = CreateFontIndirect(plf);

    hfntPrev = SelectObject(hdc, hfnt);

    TextOut(hdc, rc.right / 2, rc.bottom / 2,

        lpszRotate, lstrlen(lpszRotate));

    SelectObject(hdc, hfntPrev);

    DeleteObject(hfnt);

}

/* Reset the background mode to its default. */

SetBkMode(hdc, OPAQUE);

/* Free the memory allocated for the LOGFONT structure. */

LocalFree((LOCALHANDLE) plf);


  35.3.8  Retrieving Character Outlines

You can use the GetGlyphOutline function to retrieve the outline of a glyph from a TrueType font. The glyph outline returned by the GetGlyphOutline function is for a grid-fitted glyph. (A grid-fitted glyph has been modified so that its bitmap image conforms as closely as possible to the original design of the glyph.) If your application requires an unmodified glyph outline, request the glyph outline for a character in a font whose size is equal to the font's em units. (To create a font with this size, set the lfHeight member of the LOGFONT structure to the negative of the value of the ntmSizeEM member of the NEWTEXTMETRIC structure.)

GetGlyphOutline returns the outline as a bitmap or as a series of polylines and splines. When an application retrieves a glyph outline as a series of polylines and splines, the information is returned in a TTPOLYGONHEADER structure followed by as many TTPOLYCURVE structures as required to describe the glyph. All points are returned as POINTFX structures and represent absolute positions, not relative moves. The starting point given by the pfxStart member of the TTPOLYGONHEADER structure is the point where the outline for a contour begins. The TTPOLYCURVE structures that follow can be either polyline records or spline records.

To render a TrueType character outline in Windows, you must use both the polyline and the spline records. Windows can render both polylines and splines easily. Each polyline and spline record contains as many sequential points as possible, to minimize the number of records returned.

The starting point given in the TTPOLYGONHEADER structure is always on the outline of the glyph. The specified point serves as both the starting and ending points for the contour.


  35.3.8.1  Polyline Records

Polyline records are a series of points; lines drawn between the points describe the outline of the character. A polyline record begins with the last point in the previous record (or, for the first record in the contour, the starting point). Each point in the record is on the glyph outline and can be connected simply by using straight lines.


  35.3.8.2  Spline Records

Spline records represent the quadratic curves (that is, quadratic b-splines) used by TrueType. A spline record begins with the last point in the previous record (or for the first record in the contour, with the starting point). For the first spline record, the starting point and the last point in the record are on the glyph outline. For all other spline records, only the last point is on the glyph outline. All other points in the spline records are off the glyph outline and must be rendered as the control points of b-splines.

The last spline or polyline record in a contour always ends with the contour's starting point. This arrangement ensures that every contour is closed.

Because b-splines require three points (one point off the glyph outline between two points that are on the outline), you must perform some calculations when a spline record contains more than one off-curve point.

For example, if a spline record contains three points (A, B, and C) and it is not the first record, points A and B are off the glyph outline. To interpret point A, use the current position (which is always on the glyph outline) and the point on the glyph outline between points A and B. To find the midpoint (M) between A and B, you can perform the following calculation.

M = A + (B − A)/2

The midpoint between consecutive off-outline points in a spline record is a point on the glyph outline, according to the definition of the spline format used in TrueType fonts.

If the current position is designated by P, the two quadratic splines defined by this spline record are (P, A, M) and (M, B, C).


  35.3.9  Using Portable TrueType Metrics

Applications that use the TrueType text metrics can achieve a high degree of printer and document portability; even applications that must maintain compatibility with earlier versions of Windows can use the TrueType metrics.

Design widths overcome most of the problems of device-dependent text introduced by physical devices. Design widths are a kind of logical width. Independent of any rasterization problems or scaling transformations, each glyph has a logical width and height. Composed to a logical page, each character in a string has a place that is independent of the physical device widths. Although a logical width implies that widths can be scaled linearly at all point sizes, this is not necessarily true for either nonportable or most TrueType fonts. At smaller point sizes, some glyphs are made wider relative to their height for better readability.

The characters in TrueType core fonts are designed against a 2048 by 2048 grid. The design width is the width of a character in these grid units. (TrueType supports any integer grid size up to 16,384 by 16,384; grid sizes that are integer powers of 2 scale faster than other grid sizes.)

The font outline is designed in notional units. The em square is the notional grid against which the font outline is fitted. (You can use the otmEMSquare member of OUTLINETEXTMETRIC and the ntmSizeEM member of NEWTEXTMETRIC to retrieve the size of the em square in notional units.) When a font is created that has a point size (in device units) equal to the size of its em square, the ABC widths for this font are the desired design widths. For example, assume the size of an em square is 1000 and the ABC widths of a character in the font are 150, 400, and 150. A character in this font that is 10 device units high would have ABC widths of 1.5, 4, and 1.5, respectively. Since the MM_TEXT mapping mode is most commonly used with fonts (and MM_TEXT is equivalent to device units), this is a simple calculation.

Because of the high resolution of TrueType design widths, applications that use them must take into account the large numeric values that can be created.


  35.3.9.1  Device vs. Design Units

An application can retrieve font metrics for a physical font only after the font has been selected into a device context. When a font is selected into a device context, it is scaled for the device. The font metrics specific to the device are known as device units.

Portable metrics in fonts are known as design units. To apply to a given device, design units must be converted to device units. Use the following formula to convert design units to device units.

DeviceUnits = (DesignUnits/unitsPerEm) * (PointSize/72) * DeviceResolution

The variables in this formula have the following meanings.

Variable	Description
DeviceUnits	Specifies the DesignUnits font metric converted to device units. This value is in the same units as the value given for DeviceResolution.
DesignUnits	Specifies the font metric to be converted to device units. This value can be any font metric, including the width of a character or the ascender value for an entire font.
unitsPerEm	Specifies the em square size for the font.
PointSize	Specifies size of the font, in points. (One point equals 1/72 of an inch.)
DeviceResolution	Specifies number of device units (pixels) per inch. Typical values might be 300 for a laser printer or 96 for a VGA screen.
This formula should not be used to convert device units back to design units. Device units are always rounded to the nearest pixel. The propagated round-off error can become very large, especially when an application is working with screen sizes.

To request design units, you should create a logical font whose height is specified as −unitsPerEm. Your applications can retrieve the value for unitsPerEm by calling the EnumFontFamilies function and checking the ntmSizeEM member of the NEWTEXTMETRIC structure.


  35.3.9.2  Metrics for Portable Documents

The following table specifies the most important font metrics for applications that require portable documents and the functions that allow an application to retrieve them.

Function	Metric	Use
EnumFontFamilies	ntmSizeEM	Retrieval of design metrics; conversion to device metrics
GetCharABCWidths	ABCWidths	Accurate placement of characters at the start and end of margins, picture boundaries, and other text breaks
GetCharWidth	AdvanceWidths	Placement of characters on a line
GetOutlineTextMetrics	otmfsType	Font-embedding bits
	otmsCharSlopeRise	Y-component for slope of cursor for italic fonts
	otmsCharSlopeRun	X-component for slope of cursor for italic fonts
	otmAscent	Line spacing
	otmDescent	Line spacing
	otmLineGap	Line spacing
	otmpFamilyName	Font identification
	otmpStyleName	Font identification
	otmpFullName	Font identification (typically, family and style name)
The otmsCharSlopeRise, otmsCharSlopeRun, otmAscent, otmDescent, and otmLineGap members of the OUTLINETEXTMETRIC structure are scaled or transformed to correspond to the current device mode and physical height (as given in the tmHeight member of the NEWTEXTMETRIC structure).

Font identification is important in those instances when an application must select the same font — for example, when a document is reopened or moved to a different operating system. The font mapper always selects the correct font when an application requests a font by full name. The family and style names provide input to the standard font dialog box, which ensures that the selection bars are properly placed.

The otmsCharSlopeRise and otmsCharSlopeRun values are used to produce a close approximation of the main italic angle of the font. For typical roman fonts, otmsCharSlopeRise is 1 and otmsCharSlopeRun is 0. For italic fonts, the values attempt to approximate the sine and cosine of the main italic angle of the font (in counterclockwise degrees past vertical); note that the italic angle for upright fonts is 0. Because these values are not expressed in design units, they should not be converted into device units.

The character placement and line spacing metrics enable an application to compute device-independent line breaks that are portable across screens, printers, typesetters, and even platforms.

Device-independent page layout requires the following seven basic steps:

1.	Normalize all design metrics to a common ultra-high resolution (UHR) value (for example, 65,536 DPI); this prevents round-off errors.

2.	Compute line breaks based on UHR metrics and physical page width; this yields a starting point and an ending point of a line within the text stream.

3.	Compute the device page width in device units (for example, pixels).

4.	Fit each line of text into the device page width, using the line breaks computed in step 2.

5.	Compute page breaks by using UHR metrics and the physical page length; this yields the number of lines per page.

6.	Compute the line heights in device units.

7.	Fit the lines of text onto the page, using the lines per page from step 5 and the line heights from step 6.

If all applications adopt these techniques, developers can virtually guarantee that documents moved from one application to another will retain their original appearance and format.


  35.3.10  Using PANOSE Numbers

TrueType font files include PANOSE numbers, which applications can use to choose a font that closely matches their specifications. The PANOSE system classifies faces by 10 different attributes. For more information about these attributes, see the PANOSE structure. A PANOSE structure is part of the OUTLINETEXTMETRIC structure (whose values are filled in by calling the GetOutlineTextMetrics function).

The PANOSE attributes are rated individually on a scale. The resulting values are concatenated to produce a number. Given this number for a font and a mathematical metric to measure distances in the PANOSE space, an application can determine the nearest neighbors.


  35.3.11  Creating Customized Fonts

Windows keeps a operating system font table containing all the fonts that applications can use. Windows chooses a font from this table when an application calls the CreateFont or CreateFontIndirect function. There can be up to 253 entries in the table.

A font resource is a group of individual fonts representing characters in a given character set that have various combinations of heights, widths, and pitches. You can load font resources and add the fonts in each resource to the operating system font table by using the AddFontResource function. To remove a font resource from the font table, you can use the RemoveFontResource function.

After you add a font resource to the operating system font table, you can use the individual fonts in the resource. In other words, the CreateFont function takes the fonts into account when it tries to match a physical font to the specified logical font. (Fonts in the table are never directly accessible to an application. They are available only through the CreateFontIndirect and CreateFont functions, which return the handles of the fonts, not their memory addresses.)

Whenever your application adds or removes a font resource, it should inform all other applications of the change by sending a WM_FONTCHANGE message to them. Use the following call to the SendMessage function to send the message to all windows.

SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

You can use the GetProfileString function to search the [Fonts] section of the WIN.INI file for the list of fonts that the user has used Control Panel to install.


  35.3.11.1  Creating Font Resources

A font resource file is an empty Windows dynamic-link library; it contains no code or data, but it does contain resources. You can create font resources by creating font files and adding them as resources to a font resource file. To create a font resource file, your application should follow these steps:

1.	Create the font files.

2.	Create a resource-definition file for the font.

3.	Create a dummy code module.

4.	Create a module-definition file that describes the fonts and the devices that use the fonts.

5.	Compile and link the source files.

You can add a font file to an empty library, along with such resources as icons, cursors, and menus, by using resource compiler.

Note   A complete explanation of how to create a font resource file is beyond the scope of this book. For more information on this topic, see the documentation provided with your application development tools.


  35.3.11.2  Installing and Using an Embedded Font

You must separate an embedded font from the containing document and install it in the user's operating system before Windows can use it. Although the exact procedure for separating the font from the document depends on the method used to embed it, your application should always perform these steps:

1.	Resolve name conflicts before installing the font.

2.	Write the font data to a file, decoding read-only fonts as necessary.

3.	Use the CreateScalableFontResource function to create a font resource file for the unembedded font.

Only a TrueType font can be embedded in Windows.

Your application should avoid installing a font with the same name as a font that is already on the system. To determine whether there are duplicate style names, an application can compare the information returned by EnumFontFamilies against the family name and style name stored with the embedded font.

Read-Write Permission

Embedded fonts that have read-write permission (and that therefore can be permanently installed on the user's system) should be written to a file that has the .TTF filename extension.

Most applications put the files for embedded fonts that have read-write permission into either the SYSTEM subdirectory of the user's Windows directory or into the application's working directory. Files for read-only embedded fonts are typically put into a temporary directory.

Before installing an embedded font, you must use the CreateScalableFontResource function to create a font resource file. Because Windows cannot directly interpret the native TrueType font file format, it requires a file that mimics the standard .FON file (called a .FOT file) to make internal bookkeeping and enumeration easier. The CreateScalableFontResource function produces a .FOT file that points to the TrueType font file. Once this .FOT file is produced, Windows applications can use TrueType fonts transparently by using the AddFontResource and RemoveFontResource functions. You can also use the CreateScalableFontResource function to install special fonts for logos, icons, and other graphics. Font resource files for read-only fonts should use a different extension (for example, .FOR) and should be hidden from other applications in the system by specifying 1 for the first parameter of CreateScalableFontResource.

Your application should offer users the option of permanently installing embedded fonts that have read-write permission. To permanently install a font, applications should concatenate the family and style names and then use the WriteProfileString function to insert this string along with the .FOT file name in the [Fonts] section of the WIN.INI file. A typical font entry in the [Fonts] section looks like the following example.

Times New Roman Bold (TrueType)=TIMESBD.FOT

Read-Only Permission

Embedded fonts with read-only permission should not use the .TTF extension and should avoid the .FOT and .FON extensions. A typical filename extension for read-only embedded fonts is .TTR. Files for read-only embedded fonts must be removed from the operating system and from both physical and logical memory as soon as the containing document is closed, so their names do not need to be meaningful except to the application.

If a document contains one or more read-only embedded fonts, the user must not be permitted to edit the document. If the user is allowed to edit the document in any way, your application must first strip away and delete the read-only embedded fonts. As mentioned earlier, read-only embedded fonts must be removed from the operating system and memory immediately when the document in which they are bundled is closed.

To delete read-only embedded fonts, your application should follow these steps:

1.	Call the RemoveFontResource function for each font to be deleted.

2.	Delete the font resource file for each font.

3.	Delete each TrueType font file for each font.

When an application creates a file for a read-only embedded font and specifies 1 for the first parameter of the CreateScalableFontResource function, the EnumFonts and EnumFontFamilies functions will not enumerate this font. Hiding read-only embedded fonts in this manner makes it unlikely that another application can use them, even though Windows resources are theoretically available to all processes in Windows. The RemoveFontResource function does not delete a font currently in use. If your application uses a read-only embedded font installed by another application, it can be difficult for the installing application to delete the font. In this case, your application should delete the resource file and the TrueType font file when the user closes the document containing the read-only fonts.

It is very important that applications delete the TrueType font file for read-only embedded fonts. If the delete operation fails when the user closes the document, the application should periodically attempt to delete the file as the application runs, when it closes, and the next time it starts.

In some cases, an application is unable to delete a TrueType font file for a read-only embedded font because of external events (such as a system failure). There is no legal liability for events that are out of the control of the application.


  35.4  Font and Text Functions

The following list identifies the font and text functions:

AddFontModule
AddFontResource
CreateFont
CreateFontIndirect
CreateScalableFontResource
DrawText
EnumFontFamilies
EnumFontFamProc
EnumFonts
EnumFontsProc
ExtCreateFontIndirect
ExtTextOut
GetAspectRatioFilter
GetAspectRatioFilterEx
GetCharABCWidths
GetCharABCWidthsFloat
GetCharWidth
GetCharWidthFloat
GetFontData
GetGlyphOutline
GetKerningPairs
GetOutlineTextMetrics
GetRasterizerCaps
GetTabbedTextExtent
GetTextAlign
GetTextCharacterExtra
GetTextColor
GetTextExtent
GetTextExtentExPoint
GetTextExtentPoint
GetTextFace
GetTextMetrics
MulDiv
PolyTextOut
RemoveFontModule
RemoveFontResource
SetMapperFlags
SetTextAlign
SetTextCharacterExtra
SetTextColor
SetTextJustification
TabbedTextOut
TextOut


36.1  About Color
  Chapter 36    Colors

36.1  About Color

Color functions, messages, and structures enable applications written for Microsoft® Windows (™)  to take advantage of recent improvements in display-adapter and printer technology. Colors are used by Windows-based applications in a variety of ways. Word-processing applications display and print text by using a variety of foreground and background colors, spreadsheet applications display and print charts and graphs that have been outlined and filled with a variety of pen and brush colors, and image-editing applications display and print bitmapped pictures by using a rich set of colors that give the images a realistic appearance. This chapter focuses on the use of colors on video displays.


  36.1.1  Colors and Light

Light is a form of electromagnetic radiation consisting of millions of small particles called photons. Although light consists of particles, it is analyzed as a wave form. It can be divided into three color groups, each characterized by a specific wavelength. The first group with the shortest wavelength is blue, the second with medium wavelength is green, and the third group with the longest wavelength is red. The RGB format uses these groups (red,green, and blue) to identify a color.

Three different elements characterize human perception of color: hue, luminosity, and saturation. Each of these elements loosely corresponds to one of the physical characteristics of light: hue corresponds to wavelength, luminosity corresponds to intensity, and saturation corresponds to purity. The HLS format uses these elements (hue, luminosity, and saturation) to identify a color.

The HLS format is supported in the Color common dialog box, shown in »this illustration«. The Color common dialog box enables users to specify an HLS triplet that identifies a specific color.

Note   Although colors can be specified in the Color common dialog box by using the HLS format Windows stores colors internally by using the RGB format.

For more information about the Color common dialog box, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.)


  36.1.2  Colors and Video Display Technology

The 8514, Video Graphics Adapter (VGA), and super-VGA video adapters are significant improvements over the early video displays such as the Color Graphics Adapter (CGA) and the Enhanced Graphics Adapter (EGA). The CGA is capable of producing a maximum of 4 colors with a resolution of 320 by 200 pixels. The EGA is capable of producing a maximum of 16 simultaneous colors from an array of 64 total available colors with a resolution of 640 by 350 pixels. The more recent VGA is capable of producing 16 simultaneous colors from an array of 262,144 colors with a resolution of 640 by 480 pixels. The 8514 and super VGA displays offer resolutions and color capabilities beyond that of the standard VGA. Some super VGA displays are capable of displaying over 16 million colors at a resolution of 1024 by 768 pixels. The improvements in color capabilities and resolution have finally made it possible to display realistic bitmapped images in the client area of an application's window without dithering or mixing colors to produce shades.

A color video display is normally a raster device that treats the display surface as a coordinate space and draws lines, curves, text, and filled objects by repeatedly scanning rows of picture elements called pixels from left to right and from top to bottom. A pixel becomes visible when one or more electron guns in the back of the display fire an electron beam onto a phosphor coating on the back of the display surface. When struck by the electron beam, the phosphor emits visible light. In the simplest case, a single pixel is created by combining the light produced by three electron guns. When the beam of each gun strikes the phosphor coating, it generates red, green, or blue light of varying intensity. When viewed by the human eye, the three dots produced by the three guns appear to merge and form a single color. The point at which the three dots merge is a pixel.

Color video technology is often called an additive technology because the color of each pixel on a display is specified by adding the intensity values for each of the primaries: red, green, and blue. For example, if the minimum intensity on a given display was specified as 0 and maximum intensity was specified as 255, a white pixel would be identified by the RGB triplet (255, 255, 255), a black pixel would be identified by the RGB triplet (0, 0, 0), and a cyan pixel would be identified by the RGB triplet (0, 255, 255).


  36.1.3  Color Operations

Most of the 8514 and super VGA display adapters impose a limit on the number of colors that can appear simultaneously on the screen. This limit is a function of the resolution of the display and the amount of memory on the adapter card. For example, an adapter with 512 kilobytes (K) of video memory could display as many as 256 colors simultaneously on a display with a resolution of 640 by 480 pixels. If the display resolution were increased to 1024 by 768 pixels, the memory limitations of the adapter card would prevent the simultaneous display of 256 colors — instead, only 16 different colors could appear at the same time. This problem is fairly common on a number of displays — only a subset of the total number of colors can appear simultaneously. The array which identifies this subset is called the system palette. Windows adds entries from another palette, the logical palette, to the system palette when an application realizes its logical palette. The two palettes are described in the following sections.


  36.1.3.1  System Palette

The system palette is an array identifying a subset of the total number of colors that can appear simultaneously on a display. It is shared by all Windows-based applications. Windows provides a set of palette-manager functions that are used to alter the colors in the system palette. These functions are designed for applications that require realistic colors when displaying bitmapped images.The code supporting these functions is part of a dynamic-link library (DLL) called the display driver. A display driver is a Windows DLL that converts graphics device interface (GDI) function calls to corresponding device commands. Not all display drivers support the palette-manager functions. For example, standard VGA display drivers do not support the palette-manager functions, super-VGA display drivers do. You can determine whether or not a device supports a system palette by calling the GetDeviceCaps function and specifying the RASTERCAPS constant. If a device supports a system palette, you can retrieve the system palette size by calling the GetDeviceCaps function and specifying the NUMCOLORS constant as the second argument.

The palette-manager functions are powerful but potentially problematic; by altering colors in the system palette can could also change the colors in every window on the desktop. In order to prevent this from happening, Windows provides the following:

•	An object called a logical palette that is associated with each application's device context. For more information about the logical palette, see Section 36.1.3.2, »Logical Palette«.

•	A set of messages that informs an application that changes have been made to the system palette.

•	A set of functions used to create, alter, and remove a logical palette.


  36.1.3.2  Logical Palette

A logical palette is an array of colors that an application can use when drawing graphics output using the device context. Each device context has a default logical palette containing 20 entries. Of these 20 entries, 16 of the colors correspond to the colors found on a standard VGA display while the remaining 4 correspond to unique colors used by Window Manager. The following table shows the default logical palette and the RGB triplets found in each entry:

Index value	Red	Green	Blue
0	0x00	0x00	0x00
1	0x80	0x00	0x00
2	0x00	0x80	0x00
3	0x80	0x80	0x00
4	0x00	0x00	0x80
5	0x80	0x00	0x80
6	0x00	0x80	0x80
7	0xC0	0xC0	0xC0
8	0xC0	0xDC	0xC0
9	0xA6	0xCA	0xF0
10	0xFF	0xFB	0xF0
11	0xA0	0xA0	0xA4
12	0x80	0x80	0x80
13	0xFF	0x00	0x00
14	0x00	0xFF	0x00
15	0xFF	0xFF	0x00
16	0x00	0x00	0xFF
17	0xFF	0x00	0xFF
18	0x00	0xFF	0xFF
19	0xFF	0xFF	0xFF
The 16 standard VGA colors are found at locations 0−7 and locations 12−19; the nonstandard colors are found at locations 8−11.


  36.1.3.3  Custom Logical Palette

If an application creates or displays bitmapped images, it may be necessary to use more than the 20 default colors. It may also be necessary to replace the 20 default colors with colors that are better suited to the image that is created or displayed. Before creating a custom logical palette, an application must determine the number of colors that are supported by the device. This is done by calling the GetDeviceCaps function and passing the NUMCOLORS constant as the second argument.

The colors requested in the logical palette are mapped to the system palette when the application's window is the active window on the desktop and when the application realizes its logical palette by calling the RealizePalette function. If an application replaces the entire system palette with new colors, it must call the SetSystemPaletteUse function before to realizing its logical palette.

In order to prevent one application from altering the colors in other application's windows, three messages are supported by window manager. If the currently active application realizes a custom palette by calling the RealizePalette function, Windows sends the WM_PALETTEISCHANGING message to all top-level and overlapped windows, indicating the system palette is about to change. If the function executes successfully, Windows sends the WM_PALETTECHANGED message to the windows, indicating the system palette has changed. When one of the top-level or overlapped windows is about to be activated, Windows sends the WM_QUERYNEWPALETTE message. Upon receiving this message, the corresponding application must call the RealizePalette function to realize its own logical palette.

To create a custom logical palette, an application first needs to create a LOGPALETTE structure, call the CreatePalette function, and pass a pointer to the structure. An application can select a logical palette into the application device context by calling the SelectPalette function. However, before you can draw in the client area of your application's window by using the colors specified in the custom logical palette, you'll need to call the RealizePalette function. If your application's window is currently the active window, the colors requested in your logical palette are stored in the system palette, and you can begin drawing. If the application's window is not the active window, the colors requested in the custom logical palette may not be matched to the system palette. Whether or not a match occurs depends on such things as the size of the system palette, the size of the custom palette, the size of the logical palette associated with the active window, and the colors specified in both logical palettes.

Once a logical palette is created, an application can change or update its colors by calling the AnimatePalette or SetPaletteEntries function. If the application's window is active, the application can update the colors on the screen immediately by calling the AnimatePalette function. To update the logical-palette colors but continue displaying the current colors for a period of time, it can call the SetPaletteEntries function to alter the logical palette and then later call the RealizePalette function when it is appropriate to actually update the image on the screen.


  36.1.3.4  Colored Pens, Brushes, and Text

Applications can use the palette manager and the Color common dialog box to let a user select a custom color. The dialog box is displayed by calling the ChooseColor function, which returns an RGB triplet for the requested color. To retrieve the logical-palette index for the closest color in the logical palette, call the GetNearestPaletteIndex function. Use this index to create a pen, brush, or text output with the closest match to the requested color.

When creating color pens, brushes, and text, it is actually faster to use an RGB triplet (instead of a Palette index) to set the colors of objects in a device context. Once the ChooseColor function returns an RGB triplet, determine the closest match by calling the GetNearestColor function. Use the triplet returned by GetNearestColor to create a colored pen by calling the CreatePenIndirect function, create a colored brush by calling the CreateBrushIndirect function, or create colored text by calling the SetTextColor function.


  36.2  Using Color

This section contains sample code demonstrating common tasks performed with the color and palette manager functions.


  36.2.1  Creating a Colored Pen

You can use the Color common dialog box to let the user choose pen, brush, and text colors. This dialog box is displayed by initializing a CHOOSECOLOR structure and calling the ChooseColor function. Upon executing successfully, the ChooseColor function stores an RGB triplet corresponding to the user's selection in the rgbResult member of the CHOOSECOLOR structure. You can use this member to specify a pen, brush, or text color by calling the CreatePenIndirect, CreateBrushIndirect, or SetTextColor function and copying the RGB data from this member to the appropriate argument.

In the following example, the data contained in the rgbResult member is copied into the lopnColor member of a LOGPEN structure and is used to create a new pen.

case IDM_PENCOLOR:

    /* Retrieve the default logical palette entries. */

    iRet = GetPaletteEntries(hpal, 0, 20, ape);

    /* Set the custom color controls to white. */

    for (i = 0; i < 16; i++)

        aclrCust[i] = RGB(255, 255, 255);

    /* Initialize clr to black. */

    clr = RGB(0, 0, 0);

    /* Set all structure members to zero. */

    memset(&cc, 0, sizeof(CHOOSECOLOR));

    /* Initialize the necessary CHOOSECOLOR members. */

    cc.lStructSize = sizeof(CHOOSECOLOR);

    cc.hwndOwner = hWnd;

    cc.rgbResult = clr;

    cc.lpCustColors = aclrCust;

    cc.Flags = CC_PREVENTFULLOPEN;

    if (ChooseColor(&cc)) {

        /* Initialize the LOGPEN structure. */

        lp.lopnStyle = PS_SOLID;

        lp.lopnWidth.x = 1;

        lp.lopnColor = cc.rgbResult;

        /* Select the new pen and draw. */

        hdc = GetDC(hWnd);

        hpenOld = SelectObject(hdc, CreatePenIndirect(&lp));

        MoveToEx(hdc, 100, 100, NULL);

        LineTo(hdc, 100, 200);

        /*   . */

        /*   . */

        /*   . */

        ReleaseDC(hWnd, hdc);

    }

    break;


  36.3  Functions and Messages

Following are the functions and messages that support the use of color in a Win32 application.


  Functions

AnimatePalette
CreateHalftonePalette
CreatePalette
GetColorAdjustment
GetNearestColor
GetNearestPaletteIndex
GetPaletteEntries
GetSystemPaletteEntries
GetSystemPaletteUse
RealizePalette
ResizePalette
SelectPalette
SetColorAdjustment
SetPaletteEntries
SetSystemPaletteUse
UpdateColors


  Messages

WM_PALETTECHANGED
WM_PALETTEISCHANGING
WM_QUERYNEWPALETTE
WM_SYSCOLORCHANGE


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


37.1  About Paths
  Chapter 37    Paths

37.1  About Paths

A path is one or more figures (or shapes) that are filled, outlined, or both filled and outlined. Applications written for Microsoft® Windows (™)  use paths in many ways. Paths are used in drawing and painting applications. Computer-aided design (CAD) applications use paths to create unique clipping regions, to draw outlines of irregular shapes, and to fill the interiors of irregular shapes. An irregular shape is a shape composed of Bézier curves and straight lines. (A regular shape is an ellipse, a circle, a rectangle, or a polygon.)

A path is one of the objects associated with a device context (DC). However, unlike the default objects (the pen, the brush, and the font) that are part of any new DC, there is no default path. For more information about device contexts, see Chapter 28, »Device Contexts«.

To create a path and select it into a device context, it is first necessary to define the points that describe it. This is done by calling the BeginPath function, specifying the appropriate drawing functions, and then by calling the EndPath function. This combination of functions (BeginPath, drawing functions, and EndPath) constitute a path bracket. The following functions can be used in a path bracket:

AngleArc	LineTo	Polyline
Arc	MoveToEx	PolylineTo
ArcTo	Pie	PolyPolygon
Chord	PolyBezier	PolyPolyline
CloseFigure	PolyBezierTo	Rectangle
Ellipse	PolyDraw	RoundRect
ExtTextOut	Polygon	TextOut
When an application calls the EndPath function, Windows selects the associated path into the specified DC. (If another path had previously been selected into the DC, Windows deletes that path without saving it.) After Windows selects the path into the DC, an application can operate on the path in one of the following ways:

•	Draw the outline of the path (using the current pen).

•	Paint the interior of the path (using the current brush).

•	Draw the outline and fill the interior of the path.

•	Modify the path (by converting curves to line segments).

•	Convert the path into a clip path.

•	Convert the path into a region.

•	Flatten the path by converting each curve in the path into a series of line segments.

•	Retrieve the coordinates of the lines and curves that compose a path.


  37.1.1  Outlined and Filled Paths

An application can draw the outline of a path by calling the StrokePath function; it can fill the interior of a path by calling the FillPath function; and it can both outline and fill the path by calling the StrokeAndFillPath function.

Whenever an application fills a path, Windows uses the device context's current fill mode. An application can retrieve this mode by calling the GetPolyFillMode function and, it can set a new fill mode by calling the SetPolyFillMode function. For a description of the two fill modes, see Chapter 32, »Regions«.

»This illustration« shows the cross-section of an object created by a computer-aided design (CAD) application using paths that were both outlined and filled.


  37.1.2  Transformations of Paths

Paths are defined by using logical units and current transformations. (If the SetWorldTransform function has been called, the logical units are world units; if this function has not been called, the logical units are page units.) An application can use world transformations to scale, rotate, shear, translate, and reflect the lines and Bézier curves which define a path.

Note   A world transformation within a path bracket only affects those lines and curves drawn after the transformation was set. It will have no affect on those lines and curves that were drawn before setting the transformation. For a description of world transformation, see Chapter 39, »Coordinate Spaces and Transformations«.

An application can also use the SetWorldTransform function to outline the shape of the pen used to outline a path if the pen is a geometric pen. For a description of geometric pens, see Chapter 31, »Pens«.


  37.1.3  Clip Paths

An application can use clipping and paths to create special graphic effects. »This illustration« shows a string of text drawn by using a large Arial font.

»This illustration« shows the result of selecting the text as a clip path and drawing radial lines for a circle whose center is located above and left of the string.

Note   Before GDI adds text created with a bitmapped font to a path, it converts the font to an outline or vector font.

An application creates a clip path by generating a path bracket and then by calling the SelectClipPath function. After a clip path is selected into a DC, output only appears within the borders of the path.

In addition to creating special graphic effects, clip paths are also useful in applications that save images as enhanced metafiles. By using a clip path, an application is able to ensure device independence because the units used to specify a path are logical units (as opposed to device units that are used to specify a region).


  37.1.4  Conversion of Paths to Regions

An application can convert a path into a region by calling the PathToRegion function. Like the SelectClipPath function, PathToRegion is useful in the creation of special graphic effects. For example, there are no functions that allow an application to offset a path; however, there is a function that enables an application to offset a region (OffsetRgn). Using PathToRegion, an application can create the effect of animating a complex shape by creating a path that defines the shape, converting the path into a region (by calling PathToRegion), and then repeatedly painting, moving, and erasing the region (by calling functions such as FillRgn, OffsetRgn, FillRgn).


  37.1.5  Curved Paths

An application can flatten the curves in a path by calling the FlattenPath function. This function is especially useful in applications that fit text onto the contour of a path which contains curves. To fit the text, the application must perform the following steps:

1.	Create the path where the text appears.

2.	Call the FlattenPath function to convert the curves in a path into line segments.

3.	Call the GetPath function to retrieve these line segments.

4.	Calculate the length of each line and the width of each character in the string.

5.	Use the line-width and character-width data to position each character along the curve.


  37.2  Using Paths

This section contains a code sample that enables the user to select a font of a particular point size (by using the Choose Font dialog box), select a clip path (by using text drawn with this font), and then view the result of clipping to the text.

This code was used to create the illustrations that appear in Section 37.1.3, »Clip Paths«.

CHOOSEFONT cf;          /* common dialog box font structure              */

LOGFONT lf;             /* logical font structure                        */

HFONT hfont;            /* new logical font handle                       */

HFONT hfontOld;         /* original logical font handle                  */

HDC hdc;                /* display DC handle                             */

int nXStart, nYStart;   /* drawing coordinates                           */

RECT rc;                /* rectangle structure for painting window       */

SIZE sz;                /* size structure that receives text extents     */

double aflSin[90];      /* sine of 0-90 degrees in 1 degree increments   */

double aflCos[90];      /* cosine of 0-90 degrees in 1 degree increments */

double flRadius,a;      /* radius of circle                              */

int iMode;              /* clipping mode                                 */

HRGN hrgn;              /* clip region handle                            */

LRESULT APIENTRY MainWndProc(

    HWND hwnd,                /* window handle                   */

    UINT message,             /* type of message                 */

    WPARAM wParam,            /* additional information          */

    LPARAM lParam)            /* additional information          */

{

    PAINTSTRUCT ps;

    switch (message) {

        case WM_PAINT:

            hdc = BeginPaint(hwnd, &ps);

            EndPaint(hwnd, &ps);

            break;

        case WM_COMMAND: /* message: command from application menu */

            switch (wParam) {

                case IDM_VANISH: /* erases client area */

                    hdc = GetDC(hwnd);

                    GetClientRect(hwnd, &rc);

                    FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH));

                    ReleaseDC(hwnd, hdc);

                    break;

                case IDM_AND: /* sets clip mode to RGN_AND */

                    iMode = RGN_AND;

                    break;

                case IDM_COPY: /* sets clip mode to RGN_COPY */

                    iMode = RGN_COPY;

                    break;

                case IDM_DIFF: /* sets clip mode to RGN_DIFF */

                    iMode = RGN_DIFF;

                    break;

                case IDM_OR: /* sets clip mode to RGN_OR */

                    iMode = RGN_OR;

                    break;

                case IDM_XOR: /* sets clip mode to RGN_XOR */

                    iMode = RGN_XOR;

                    break;

                case IDM_CLIP_PATH:

                    /* Retrieve a cached DC for the window. */

                    hdc = GetDC(hwnd);

                    /*

                     * Use the font requested by the user in the

                     * Choose Font dialog box to create a logical font, and then

                     * select that font into the device context.

                     */

                    hfont = CreateFontIndirect(cf.lpLogFont);

                    hfontOld = SelectObject(hdc, hfont);

                    /*

                     * Retrieve the dimensions of the rectangle

                     * that surrounds the text.

                     */

                     GetTextExtentPoint(hdc, "Clip Path", 9, &sz);

                    /*

                     * Set a clipping region using the rectangle that

                     * surrounds the text.

                     */

                     hrgn = CreateRectRgn(nXStart, nYStart,

                         nXStart + sz.cx,

                         nYStart + sz.cy);

                     SelectClipRgn(hdc, hrgn);

                    /*

                     * Create a clip path using text drawn with

                     * the user's requested font.

                     */

                    BeginPath(hdc);

                        TextOut(hdc, nXStart, nYStart, "Clip Path", 9);

                    EndPath(hdc);

                    SelectClipPath(hdc, iMode);

                    /* Compute the sine of 0, 1, 2, ... 90 degrees. */

                    for (i = 0; i < 90; i++) {

                        aflSin[i] = sin( (((double)i) / 180.0) * 3.14159);

                        }

                    /* Compute the cosine of 0, 1, 2, ... 90 degrees. */

                    for (i = 0; i < 90; i++) {

                        aflCos[i] = cos( (((double)i) / 180.0) * 3.14159);

                        }

                    /* Set the radius value. */

                    flRadius = (double)(2 * sz.cx);

                    /*

                     * Draw the 90 rays extending from the

                     * radius to the edge of the circle.

                     */

                    for (i = 0; i < 90; i++) {

                        MoveToEx(hdc, nXStart, nYStart, (LPPOINT) NULL);

                        LineTo(hdc, nXStart + ((int) (flRadius * aflCos[i])),

                               nYStart + ((int) (flRadius * aflSin[i])));

                        }

                    /* Reselect the original font into the DC. */

                     SelectObject(hdc, hfontOld);

                    /* Delete the user's font. */

                     DeleteObject(hfont);

                    /* Release the DC. */

                    ReleaseDC(hwnd, hdc);

                    break;

                case IDM_FONT:

                    /* Initialize necessary members. */

                    cf.lStructSize = sizeof (CHOOSEFONT);

                    cf.hwndOwner = hwnd;

                    cf.lpLogFont = &lf;

                    cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

                    cf.rgbColors = RGB(0, 255, 255);

                    cf.nFontType = SCREEN_FONTTYPE;

                    /*

                     * Display the Font dialog box, allow the user to

                     * choose a font, and render text in the

                     * window with that selection.

                     */

                    if (ChooseFont(&cf)) {

                        hdc = GetDC(hwnd);

                        hfont = CreateFontIndirect(cf.lpLogFont);

                        hfontOld = SelectObject(hdc, hfont);

                        crOld = SetTextColor(hdc, cf.rgbColors);

                        TextOut(hdc, nXStart, nYStart,

                            "Clip Path", 9);

                        SetTextColor(hdc, crOld);

                        SelectObject(hdc, hfontOld);

                        DeleteObject(hfont);

                        ReleaseDC(hwnd, hdc);

                    }

                    break;

                default:

                    return DefWindowProc(hwnd, message, wParam, lParam);

            }

            break;

        case WM_DESTROY: /* message: window being destroyed    */

            PostQuitMessage(0);

            break;

        default: /* passes it on if unprocessed        */

            return DefWindowProc(hwnd, message, wParam, lParam);

    }

    return 0;

}


  37.3  Functions

Use the following functions to create, alter, or draw paths.

AbortPath
BeginPath
CloseFigure
EndPath
FillPath
FlattenPath
GetMiterLimit
GetPath
PathToRegion
SelectClipPath
SetMiterLimit
StrokeAndFillPath
StrokePath
WidenPath


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


38.1  About Clipping
  Chapter 38    Clipping

38.1  About Clipping

Clipping is the process of limiting output to a region or path within the client area of an application's window. Clipping is used by applications written for Microsoft® Windows (™)  in a variety of ways. Word processing and spreadsheet applications clip keyboard input to keep it from appearing in the margins of a page or spreadsheet. Computer-aided design (CAD) and drawing applications clip graphics output to keep it from overwriting the edges of a drawing or picture.

A clipping region is a region with edges that are either straight lines or curves. A clip path is a region with edges that are straight lines, Bézier curves, or combinations of both. For more information about regions, see Chapter 32, »Regions«. For more information about paths, see Chapter 37, »Paths«.


  38.1.1  Clipping Regions

A clipping region is one of the graphic objects that an application can select into a device context (DC). It is typically rectangular. Some device contexts provide a predefined or default clipping region while others do not. For example, if you obtain a device context handle from the BeginPaint function, the DC contains a predefined, rectangular clipping region that corresponds to the invalid rectangle that requires repainting. However, if you obtain a device context handle by calling the CreateDC or GetDC function, the DC does not contain a default clipping region. For more information about device contexts returned by the BeginPaint function, see Chapter 20, »Painting and Drawing«. For more information about device contexts returned by the CreateDC and GetDC functions, see Chapter 28, »Device Contexts«.

Applications can perform a variety of operations on clipping regions. Some of these operations require a handle identifying the region and some do not. For example, an application can perform the following operations directly on a device context's clipping region:

•	Determine whether graphics output appears within the region's borders by passing coordinates of the corresponding line, arc, bitmap, text, or filled shape to the PtVisible function.

•	Determine whether part of the client area intersects a region by calling the RectVisible function.

•	Move the existing region by a specified offset by calling the OffsetClipRgn function.

•	Exclude a rectangular part of the client area from the current clipping region by calling the ExcludeClipRect function.

•	Combine a rectangular part of the client area with the current clipping region by calling the IntersectClipRect function.

After obtaining a handle identifying the region, an application can perform any operation that is common with regions; for example:

•	Combining a copy of the current clipping region with a second region by calling the CombineRgn function.

•	Compare a copy of the current clipping region to a second region by calling the EqualRgn function.

•	Determine whether a point lies within the interior of a copy of the current clipping region by calling the PtInRegion function.


  38.1.2  Clip Paths

Like a clipping region, a clip path is another graphics object an application can select into a device context. Unlike a clipping region, a clip path is always created by an application and it is used for clipping to one or more irregular shapes. For example, an application can use the lines and curves that form the outlines of characters in a string of text to define a clip path.

To create a clip path, it's first necessary to create a path that describes the required irregular shape. Paths are created by calling the appropriate GDI drawing functions after calling the BeginPath function and before calling the EndPath function. This collection of functions is called a path bracket. For more information about paths and path brackets, see Chapter 37, »Paths«.

After the path is created, it can be converted to a clip path by calling the SelectClipPath function, identifying a device context, and specifying a usage mode. The usage mode determines how Windows combines the new clip path with the device context's original clipping region. The following table describes the usage modes.

Mode	Description
RGN_AND	The clip path includes the intersection (overlapping areas) of the device context's clipping region and the current path.
RGN_COPY	The clip path is the current path.
RGN_DIFF	The clip path includes the device context's clipping region with any intersecting parts of the current path excluded.
RGN_OR	The clip path includes the union (combined areas) of the device context's clipping region and the current path.
RGN_XOR	The clip path includes the union of the device context's clipping region and the current path but excludes the intersection.


  38.2  Using Clipping

This section contains a code example that demonstrates how an application can generate a clip path consisting of the characters "ABC" drawn by using a font specified by the user.

»This illustration« shows the string of text drawn in the usual fashion by using a brush with the current text color.

»This illustration« shows the string of text selected as a clip path and filled by drawing horizontal and vertical lines.

CHOOSEFONT cf;      /* common dialog box font structure          */

LOGFONT lf;         /* logical font structure                    */

HFONT hfont;        /* new logical font handle                   */

HFONT hfontOld;     /* original logical font handle              */

HDC hdc;            /* display DC handle                         */

int nXStart, nYStart; /* drawing coordinates                     */

RECT rc;            /* rectangle structure for painting window   */

SIZE sz;            /* size structure that receives text extents */

    /* Retrieve a cached DC for the window. */

    hdc = GetDC(hwnd);

    /* Erase the current window contents. */

    GetClientRect(hwnd, &rc);

    FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH));

    /*

     * Use the font requested by the user in the

     * Font dialog box to create a logical font, and

     * then select that font into the DC.

     */

    hfont = CreateFontIndirect(cf.lpLogFont);

    hfontOld = SelectObject(hdc, hfont);

    /*

     * Create a clip path using text drawn with

     * the user's requested font.

     */

    BeginPath(hdc);

        TextOut(hdc, nXStart, nYStart, "ABC", 3);

    EndPath(hdc);

    SelectClipPath(hdc, RGN_DIFF);

    /*

     * Retrieve the dimensions of the rectangle

     *that surrounds the text.

     */

     GetTextExtentPoint(hdc, "ABC", 3, &sz);

    /*

     *Draw horizontal lines through the clip

     * path.

     */

     for (i = nYStart + 1; i < (nYStart + sz.cy); i+=3) {

        MoveToEx(hdc, nXStart, i, (LPPOINT) NULL);

        LineTo(hdc, (nXStart + sz.cx), i);

    }

    /* Draw vertical lines through the clip path. */

     for (i = nXStart + 1; i < (nXStart + sz.cx); i+=3){

        MoveToEx(hdc, i, nYStart, (LPPOINT) NULL);

        LineTo(hdc, i, (nYStart + sz.cy));

    }

    /* Reselect the original font into the DC. */

     SelectObject(hdc, hfontOld);

    /* Delete the user's font. */

     DeleteObject(hfont);

    /* Release the DC. */

     ReleaseDC(hwnd, hdc);

For an example that demonstrates how an application creates a rectangular clipping region, see Chapter 32, »Regions«.


  38.3  Functions

Following are the functions used with clipping:

ExcludeClipRect
ExtSelectClipRgn
GetClipBox
GetClipRgn
GetMetaRgn
IntersectClipRect
OffsetClipRgn
PtVisible
RectVisible
SelectClipPath
SelectClipRgn
SetMetaRgn


39.1  About Coordinate Spaces and Transformations
  Chapter 39    Coordinate Spaces and Transformations

39.1  About Coordinate Spaces and Transformations

Applications written for Microsoft® Windows (™)  use coordinate spaces and transformations to scale, rotate, translate, shear, and reflect graphics output. For example, desktop publishing applications use coordinate spaces and transformations to "zoom" parts of a page or to display adjacent pages in a window; computer-aided design (CAD) applications use them to rotate objects, scale drawings, or to create perspective views; and spreadsheet applications use them to move and size graphs.

The following illustrations show successive views of an object created in a drawing application. The first illustration shows the object as it appears in the original drawing; the five remaining illustrations show the effects of applying various transformations.

»Original View«

»Scaled View«

»Translated View«

»Rotated View«

»Sheared View«

»Reflected View«


  39.1.1  Transformation of Coordinate Spaces

A coordinate space is a planar space based on the Cartesian coordinate system. This system provides a means of specifying the location of each point on a plane. It requires two axes that are perpendicular and equal in length. »This illustration« shows a coordinate space.

The Win32 application programming interface (API) uses four coordinate spaces: world, page, device, and physical device. Applications use world space to rotate, shear, or reflect graphics output. World space measures 232 units high by 232 units wide. Page space (referred to as logical space in earlier versions of Windows) also measures 232 units high by 232 units wide. Device space measures 227 units high by 227 units wide. Page space works with device space to provide applications with device-independent units, such as millimeters and inches. The Win32 API refers to both world space and page space as logical space. The final coordinate space, physical device, usually refers to the client area of the application's window; however, it can also include the entire desktop, a complete window (including the frame, title bar, and menu bar), or a page of printer or plotter paper. Physical device dimensions vary according to the dimensions set by the display, printer, or plotter technology.

To depict output on a physical device, Windows copies (or maps) a rectangular region from one coordinate space into the next coordinate space until finally the output appears in its entirety on the physical device. Mapping begins in the application's world space if the application has called the SetWorldTransform function; otherwise, mapping occurs in page space. As Windows copies each point within the rectangular region from one space into another, it applies an algorithm called a transformation. A transformation alters (or transforms) the size, orientation, and shape of objects that are copied from one coordinate space into another. Although a transformation affects an object as a whole, it is applied to each point, or to each line, in the object.

»This illustration« shows a typical transformation performed by using the SetWorldTransform function.


  39.1.2  World-Space to Page-Space Transformations

World-space to page-space transformations are new to Windows. They support translation and scaling that were available in previous versions of Windows. In addition, they support rotation, shear, and reflection capabilities. The following sections describe these transformations, illustrate their effects, and provide the algorithms used to achieve them.


  39.1.2.1  Translation

Some applications translate (or shift) objects drawn in the client area. If your application features this capability, use the SetWorldTransform function to set the appropriate world-space to page-space transformation. This function receives a pointer to an XFORM structure containing the appropriate values. The eDx and eDy members of XFORM specify the horizontal and vertical translation components, respectively.

When translation occurs, each point in an object is shifted vertically, horizontally, or both, by a specified amount. »This illustration« shows a 20- by 20-unit rectangle that was translated to the right by 10 units when copied from world coordinate space to page coordinate space.

In the preceding illustration, the x-coordinate of each point in the rectangle is 10 units greater than the original x-coordinate.

Horizontal translation can be represented by the following algorithm.

x' = x + Dx

Where x' is the new x-coordinate, x is the original x-coordinate, and Dx is the horizontal distance moved.

Vertical translation can be represented by the following algorithm.

y' = y + Dy

Where y' is the new y-coordinate, y is the original y-coordinate, and Dy is the vertical distance moved.

The horizontal and vertical translation transformations can be combined into a single operation by using a 3-by-3 matrix.

                      |1   0   0|

|x' y' 1| = |x y 1| * |0   1   0|

                      |Dx  Dy  1|

(The rules of matrix multiplication state that the number of rows in one matrix must equal the number of columns in the other. The integer 1 in the matrix |x y 1| is a placeholder that was added to meet this requirement.)

The 3-by-3 matrix that produced the illustrated translation transformation contains the following values.

|1  0  0|

|0  1  0|

|10 0  1|


  39.1.2.2  Scaling

Most CAD and drawing applications provide features that scale output created by the user. If your application features scaling (or "zoom") capabilities, use the SetWorldTransform function to set the appropriate world-space to page-space transformation. This function receives a pointer to an XFORM structure containing the appropriate values. The eM11 and eM22 members of XFORM specify the horizontal and vertical scaling components, respectively.

When scaling occurs, the vertical and horizontal lines (or vectors) that constitute an object are stretched or compressed with respect to the x-axis or the y-axis. »This illustration« shows a 20- by 20-unit rectangle scaled vertically to twice its original height when copied from world coordinate space to page coordinate space.

In the preceding illustration, the vertical lines that define the original rectangle's side measure 20 units, while the vertical lines that define the scaled rectangle's sides measure 40 units.

Vertical scaling can be represented by the following algorithm.

y' = y * Dy

Where y' is the new length, y is the original length, and Dy is the vertical scaling factor.

Horizontal scaling can be represented by the following algorithm.

x' = x * Dx

Where x' is the new length, x is the original length, and Dx is the horizontal scaling factor.

The vertical and horizontal scaling transformations can be combined into a single operation by using a 2-by-2 matrix.

|x' y'|  =  |Dx   0|  *  |x y|

            |0   Dy|

The 2-by-2 matrix that produced the illustrated scaling transformation contains the following values.

|1    0|

|0    2|


  39.1.2.3  Rotation

Many CAD applications provide features that rotate objects drawn in the client area. If your application features rotation capabilities, use the SetWorldTransform function to set the appropriate world-space to page-space transformation. This function receives a pointer to an XFORM structure containing the appropriate values. The eM11, eM12, eM21, and eM22 members of XFORM specify, respectively, the cosine, sine, negative cosine, and cosine of the angle of rotation.

When rotation occurs, the points that constitute an object are rotated with respect to the coordinate-space origin. »This illustration« shows a 20- by 20-unit rectangle rotated 30 degrees when copied from world coordinate space to page coordinate space.

In the preceding illustration, each point in the rectangle was rotated 30 degrees with respect to the coordinate-space origin.

The following algorithm computes the new x-coordinate (x') for a point (x,y) that is rotated by angle A with respect to the coordinate-space origin.

x' = (x * cos A) - (y * sin A)

The following algorithm computes the y-coordinate (y') for a point (x,y) that is rotated by the angle A with respect to the origin.

y' = (x * sin A) - (y * cos A)

The two rotation transformations can be combined in a 2-by-2 matrix as follows.

|x' y'| == |x y| * | cos A   sin A|

                   |-sin A   cos A|

The 2-by-2 matrix that produced the rotation contained the following values.

| .8660    .5000|

|-.5000    .8660|


  The Rotation Algorithm Derivation

Rotation algorithms are based on trigonometry's addition theorem stating that the trigonometric function of a sum of two angles (A1 and A2) can be expressed in terms of the trigonometric functions of the two angles.

sin(A1 + A2) = (sin A1 * cos A2) + (cos A1 * sin A2)

cos(A1 + A2) = (cos A1 * cos A2) - (sin A1 * sin A2)

»This illustration« shows a point p rotated counterclockwise to a new position p'. In addition, it shows two triangles formed by a line drawn from the coordinate-space origin to each point and a line drawn from each point through the x-axis.

Using trigonometry, the x-coordinate of point p can be obtained by multiplying the length of the hypotenuse h by the cosine of A1.

x = h * cos A1

The y-coordinate of point p can be obtained by multiplying the length of the hypotenuse h by the sine of A1.

y = h * sin A1

Likewise, the x-coordinate of point p' can be obtained by multiplying the length of the hypotenuse h by the cosine of (A1 + A2).

x' = h * cos (A1 + A2)

Finally, the y-coordinate of point p' can be obtained by multiplying the length of the hypotenuse h by the sine of (A1 + A2).

y' = h * sin (A1 + A2)

Using the addition theorem, the preceding algorithms become the following.

x' = (h * cos A1 * cos A2) - (h * sin A1 * sin A2)

y' = (h * cos A1 * sin A2) - (h * sin A1 * cos A2)

The rotation algorithms for a given point rotated by angle A2 can be obtained by substituting x for each occurrence of (h * cos A1) and substituting y for each occurrence of (h * sin A1).

x' = (x * cos A2) - (y * sin A2)

y' = (x * sin A2) - (y * cos A2)


  39.1.2.4  Shear

Some applications provide features that shear objects drawn in the client area. If your application features shear capabilities, use the SetWorldTransform function to set appropriate values in the world-space to page-space transformation. This function receives a pointer to an XFORM structure containing the appropriate values. The eM12 and eM21 members of XFORM specify the horizontal and vertical proportionality constants, respectively.

There are two components of the shear transformation: The first alters the vertical lines in an object; the second alters the horizontal lines. »This example« shows a 20- by 20-unit rectangle sheared horizontally when copied from world-space to page-space.

A horizontal shear can be represented by the following algorithm.

x' = x + (Sx * y)

Where x is the original x-coordinate, Sx is the proportionality constant, and x' is the result of the shear transformation.

A vertical shear can be represented by the following algorithm.

y' = y + (Sy * x)

Where y is the original y-coordinate, Sy is the proportionality constant, and y' is the result of the shear transformation.

The horizontal-shear and vertical-shear transformations can be combined into a single operation using a 2-by-2 matrix.

|x' y'| == |x y| * |  1   Sx|

                   | Sy    1|

The 2-by-2 matrix that produced the shear contains the following values.

|1    1|

|0    1|


  39.1.2.5  Reflection

Some applications provide features that reflect (or mirror) objects drawn in the client area. If your application features reflection capabilities, use the SetWorldTransform function to set the appropriate values in the world-space to page-space transformation. This function receives a pointer to an XFORM structure containing the appropriate values. The eM11 and eM22 members of XFORM specify the horizontal and vertical reflection components, respectively.

The reflection transformation creates a "mirror" image of an object with respect to either the x-axis or the y-axis. »This illustration« shows a 20- by 20-unit rectangle reflected horizontally and vertically upon being copied from world coordinate space to page coordinate space.

Horizontal reflection can be represented by the following algorithm.

x' = x * Rx

Where x is the x-coordinate, Rx is negative one (−1), and x' is the result of the reflection.

Vertical reflection is represented by the following algorithm.

y' = y * Ry

Where y is the y-coordinate, Ry is negative one (−1), and y' is the result of the reflection.

The horizontal-reflection and vertical-reflection operations can be combined into a single operation using a 2-by-2 matrix.

|x' y'| == |x y| * |Rx    0|

                   |0    Ry|

The 2-by-2 matrix that produced the illustrated reflection contains the following values.

|-1    0|

|0     1|


  39.1.2.6  Combined World-to-Page Space Transformations

You can combine the five world-to-page transformations into a single 3-by-3 matrix. Use these combined transformations to alter output associated with a particular device context by calling the SetWorldTransform function and supplying the elements for this matrix. When an application calls the SetWorldTransform function, it stores the elements of the 3-by-3 matrix in an XFORM structure. The members of this structure correspond to the first two columns of a 3-by-3 matrix; the last column of the matrix is not required, because its values are constant.

You can retrieve the elements of the current world transformation matrix by calling the GetWorldTransform function and supplying a pointer to an XFORM structure.


  39.1.3  Page-Space to Device-Space Transformations

The page-space to device-space transformation was part of the original Windows interface. This transformation determines the mapping mode for all graphics output associated with a particular device context. A mapping mode is a scaling transformation that specifies the size of the units used for drawing operations. In some cases, the mapping mode alters the orientation of the x-axis and the y-axis in device space. The mapping modes are described in the following table.

Mapping mode	Description
MM_ANISOTROPIC	Each unit in page space is mapped to an application-specified unit in device space. The axis may or may not be equally scaled (for example, a circle drawn in world space may appear to be an ellipse when depicted on a given device). The orientation of the axis is also specified by the application.
MM_HIENGLISH	Each unit in page space is mapped to 0.001 inch in device space. Increasing values of x occur as you move to the right; increasing values of y occur as you move up.
MM_HIMETRIC	Each unit in page space is mapped to 0.01 millimeter in device space. Increasing values of x occur as you move to the right; increasing values of y occur as you move up.
MM_ISOTROPIC	Each unit in page space is mapped to an application-defined unit in device space. The axes are always equally scaled. The orientation of the axes may be specified by the application.
MM_LOENGLISH	Each unit in page space is mapped to 0.01 inch in device space. Increasing values of x occur as you move to the right; increasing values of y occur as you move up.
MM_LOMETRIC	Each unit in page space is mapped to 0.1 millimeter in device space. Increasing values of x occur as you move to the right; increasing values of y occur as you move up.
MM_TEXT	Each unit in page space is mapped to one pixel. Increasing values of x occur as you move to the right; increasing values of y occur as you move down.
MM_TWIPS	Each unit in page space is mapped to one twentieth of a printer's point (1/1440 inch). Increasing values of x occur as you move to the right; increasing values of y occur as you move down.
You set a mapping mode by calling the SetMapMode function. You retrieve the current mapping mode for a device context by calling the GetMapMode function.

Unlike the world-space to page-space transformations that use a 3-by-3 matrix, the page-space to device-space transformations use the width and height ratios of two rectangles: the rectangle in page space is called a window and the rectangle in device space is called a viewport. The transformation occurs when Windows maps the window origin to the viewport origin and the window extents to the viewport extents, as shown in »this illustration«.

For the six predefined mapping modes (MM_HIENGLISH, MM_LOENGLISH, MM_HIMETRIC, MM_LOMETRIC, MM_TEXT, and MM_TWIPS), the width and height of these rectangles are set by Windows when you call SetMapMode. They cannot be changed. The other two mapping modes (MM_ISOTROPIC and MM_ANISOTROPIC) require that you specify the width and height of these rectangles. This is done by calling SetMapMode to set the appropriate mode and then calling SetViewportExtEx and SetWindowExtEx to specify the width and height of each rectangle.


  39.1.3.1  Predefined Mapping Modes

Of the six predefined mapping modes, one is device dependent (MM_TEXT), while the remaining five (MM_HIENGLISH, MM_LOENGLISH, MM_HIMETRIC, MM_LOMETRIC, and MM_TWIPS) are device independent.

The device-dependent mapping mode is provided for text-output operations that use device-specific fonts. Device-specific fonts are fonts created for a device with a specific aspect ratio. The aspect ratio of a device is the ratio formed by the width and height of a single pixel. You can retrieve a device's aspect ratio and the total number of device-specific fonts by calling the GetDeviceCaps function. You can limit the user's selection of fonts to only device-specific fonts by calling the ChooseFont function and setting the CF_PRINTERFONTS or CF_SCREENFONTS constants.

The device-independent mapping modes are provided for non-text drawing operations. If your application displays geometric shapes (circles, squares, polygons, and so on), choose one of the device-independent mapping modes. For example, if you are writing code to provide charting capabilities for a spreadsheet application and want to can guarantee that the diameter of each pie chart is 2 inches, you can choose the MM_LOENGLISH mapping mode and call the appropriate functions to draw and fill the charts. By specifying MM_LOENGLISH, you guarantee that the diameter of the charts are consistent on any display or printer. (If you were to choose MM_TEXT instead of MM_LOENGLISH, a chart that appears circular on a VGA display would appear elliptical on an EGA display and would appear very small on a 300 dpi laser printer.)


  39.1.3.2  Application-Defined Mapping Modes

The two application-defined mapping modes (MM_ISOTROPIC and MM_ANISOTROPIC) are provided for application-specific mapping modes. The MM_ISOTROPIC mode guarantees that logical units in the x-direction and in the y-direction are equal, while the MM_ANISOTROPIC mode allows the units to differ. A CAD or drawing application can benefit from the MM_ISOTROPIC mapping mode but may need to specify logical units that correspond to the increments on an engineer's scale (1/64 inch). These units would be difficult to obtain with the predefined mapping modes (MM_HIENGLISH or MM_HIMETRIC); however, they can easily be obtained by selecting the MM_ISOTROPIC mode, setting the window extents to the width and height of the display (expressed in units of 1/64 inch) and setting the viewport width and height to the width and height of the display in pixels.


  39.1.4  Device-Space to Physical-Device Transformation

The device-space to physical-device transformation is unique in several respects: It is limited to translation and is controlled by the window manager component of Windows. The sole purpose of this transformation is to ensure that the origin of device space is mapped to the proper point on the physical device. There are no functions to set this transformation, nor are there any functions to retrieve related data.


  39.1.5  Default Transformations

Whenever an application creates a device context and immediately begins calling GDI drawing or output functions, it takes advantage of the default page-space to device-space, and device-space to client-area transformations. (World-to-page space transformation cannot happen until the application calls the SetWorldTransform function.)

The default page-space to device-space transformation results in a one-to-one mapping; that is, a given point in page space maps to the same point in device space. As previously mentioned, this transformation is not specified by a matrix. Instead, it is obtained by dividing the width of the viewport by the width of the window and the height of the viewport by the height of the window. In the default case, the viewport dimensions are 1-pixel by 1-pixel and the window dimensions are 1-page unit by 1-page unit.

The device-space to physical-device (client area, desktop, or printer paper) transformation always results in a one-to-one mapping; that is, one unit in device space is always equivalent to one unit in the client area, on the desktop, or on a page. The sole purpose of this transformation is translation; it ensures that output appears correctly in an application's window no matter where that window is moved on the desktop.

The one unique aspect of the default transformation is the orientation of the y-axis in device space and the application's window. In the default case, the positive y-axis extends downward and the negative y-axis extends upward.


  39.2  Using Coordinates Spaces and Transformations

This section contains an example that demonstrates the following tasks.

•	Drawing graphics with predefined units

•	Centering graphics in the application's client area

•	Scaling graphics output to half its original size

•	Translating graphics output 3/4 of an inch to the right

•	Rotating graphics 30 degrees

•	Shearing graphics output along the x-axis

•	Reflecting graphics output about an imaginary horizontal axis drawn through its midpoint

The following example was used to create the illustrations that appear earlier in this chapter.

void TransformAndDraw(int iTransform, HWND hWnd)

{

HDC hDC;

XFORM xForm;

RECT rect;

/* Retrieve a DC handle for the application's window. */

hDC = GetDC(hWnd);

/*

 * Set the mapping mode to LOENGLISH. This moves the

 * client-area origin from the upper-left corner of the

 * window to the lower-left corner (this also reorients

 * the y-axis so that drawing operations occur in a true

 * Cartesian space). It guarantees portability so that

 * the object drawn retains its dimensions on any

 * display running Windows.

 */

SetMapMode(hDC, MM_LOENGLISH);

/*

 * Set the appropriate world transformation (based on the

 * user's menu selection).

 */

switch (iTransform) {

        case SCALE: /* Scale to 1/2 of the original size. */

            xForm.eM11 = (FLOAT) 0.5;

            xForm.eM12 = (FLOAT) 0.0;

            xForm.eM21 = (FLOAT) 0.0;

            xForm.eM22 = (FLOAT) 0.5;

            xForm.eDx  = (FLOAT) 0.0;

            xForm.eDy  = (FLOAT) 0.0;

            SetWorldTransform(hDC, &xForm);

            break;

        case TRANSLATE: /* Translate right by 3/4 inch. */

            xForm.eM11 = (FLOAT) 1.0;

            xForm.eM12 = (FLOAT) 0.0;

            xForm.eM21 = (FLOAT) 0.0;

            xForm.eM22 = (FLOAT) 1.0;

            xForm.eDx  = (FLOAT) 75.0;

            xForm.eDy  = (FLOAT) 0.0;

            SetWorldTransform(hDC, &xForm);

            break;

        case ROTATE: /* Rotate 30 degrees counterclockwise. */

            xForm.eM11 = (FLOAT) 0.8660;

            xForm.eM12 = (FLOAT) 0.5000;

            xForm.eM21 = (FLOAT) -0.5000;

            xForm.eM22 = (FLOAT) 0.8660;

            xForm.eDx  = (FLOAT) 0.0;

            xForm.eDy  = (FLOAT) 0.0;

            SetWorldTransform(hDC, &xForm);

            break;

        case SHEAR: /* Shear along the x-axis with a    */

                          /* proportionality constant of 1.0. */

            xForm.eM11 = (FLOAT) 1.0;

            xForm.eM12 = (FLOAT) 1.0;

            xForm.eM21 = (FLOAT) 0.0;

            xForm.eM22 = (FLOAT) 1.0;

            xForm.eDx  = (FLOAT) 0.0;

            xForm.eDy  = (FLOAT) 0.0;

            SetWorldTransform(hDC, &xForm);

            break;

        case REFLECT: /* Reflect about a horizontal axis. */

            xForm.eM11 = (FLOAT) 1.0;

            xForm.eM12 = (FLOAT) 0.0;

            xForm.eM21 = (FLOAT) 0.0;

            xForm.eM22 = (FLOAT) -1.0;

            xForm.eDx  = (FLOAT) 0.0;

            xForm.eDy  = (FLOAT) 0.0;

            SetWorldTransform(hDC, &xForm);

            break;

        case NORMAL: /* Set the unity transformation. */

            xForm.eM11 = (FLOAT) 1.0;

            xForm.eM12 = (FLOAT) 0.0;

            xForm.eM21 = (FLOAT) 0.0;

            xForm.eM22 = (FLOAT) 1.0;

            xForm.eDx  = (FLOAT) 0.0;

            xForm.eDy  = (FLOAT) 0.0;

            SetWorldTransform(hDC, &xForm);

            break;

    }

/* Find the midpoint of the client area. */

GetClientRect(hWnd, (LPRECT) &rect);

DPtoLP(hDC, (LPPOINT) &rect, 2);

/* Select a hollow brush. */

SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));

/* Draw the exterior circle. */

Ellipse(hDC, (rect.right / 2 - 100), (rect.bottom / 2 + 100),

    (rect.right / 2 + 100), (rect.bottom / 2 - 100));

/* Draw the interior circle. */

Ellipse(hDC, (rect.right / 2 -94), (rect.bottom / 2 + 94),

    (rect.right / 2 + 94), (rect.bottom / 2 - 94));

/* Draw the key. */

Rectangle(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 113),

    (rect.right / 2 + 13), (rect.bottom / 2 + 50));

Rectangle(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 96),

    (rect.right / 2 + 13), (rect.bottom / 2 + 50));

/* Draw the horizontal lines. */

MoveToEx(hDC, (rect.right / 2 - 150), (rect.bottom / 2 + 0), NULL);

LineTo(hDC, (rect.right / 2 - 16), (rect.bottom / 2 + 0));

MoveToEx(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 0), NULL);

LineTo(hDC, (rect.right / 2 + 13), (rect.bottom / 2 + 0));

MoveToEx(hDC, (rect.right / 2 + 16), (rect.bottom / 2 + 0), NULL);

LineTo(hDC, (rect.right / 2 + 150), (rect.bottom / 2 + 0));

/* Draw the vertical lines. */

MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 150), NULL);

LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 16));

MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 13), NULL);

LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 13));

MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 16), NULL);

LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 150));

ReleaseDC(hWnd, hDC);

}


  39.3  Functions

Following are the functions used with coordinate spaces and transformations.

ClientToScreen
CombineTransform
DPtoLP
GetCurrentPositionEx
GetMapMode
GetViewportExtEx
GetViewportOrgEx
GetWindowExtEx
GetWindowOrgEx
GetWorldTransform
LPtoDP
ModifyWorldTransform
OffsetViewportOrgEx
OffsetWindowOrgEx
ScaleViewportExtEx
ScaleWindowExtEx
ScreenToClient
SetMapMode
SetViewportExtEx
SetViewportOrgEx
SetWindowExtEx
SetWindowOrgEx
SetWorldTransform


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


40.1  About Metafiles
  Chapter 40    Metafiles

40.1  About Metafiles

Applications written for Microsoft® Windows (™)  use two graphics tools to store pictures: metafiles and bitmaps. For information about bitmaps, see Chapter 29, »Bitmaps«. This chapter describes metafiles.

A metafile is a collection of structures that store a picture in a device-independent format. Device independence is the one feature that sets metafiles apart from bitmaps: Unlike a bitmap, a metafile guarantees device independence. For example, when an application creates a picture measuring 2 by 2 inches on a VGA display and stores that picture in a metafile, the picture maintains its original dimensions when printed on a 300 dpi laser printer or copied over a network and displayed in another application that is running on an 8514/A video display. There is a drawback to metafiles, however: they are generally drawn more slowly than bitmaps. Therefore, if an application requires fast drawing and device independence is not an issue, it should use bitmaps instead of metafiles.

Internally, a metafile is an array of variable-length structures called metafile records. The first records in the metafile specify general information such as the resolution of the device on which the picture was created, the dimensions of the picture, and so on. The remaining records, which constitute the bulk of any metafile, correspond to the graphics device interface (GDI) functions required to draw the picture. These records are stored in the metafile after a special metafile device context (DC) is created. This DC is then used for all drawing operations required to create the picture. When Windows processes a GDI function associated with a metafile DC, it converts the function into the appropriate data and stores this data in a record appended to the metafile.

After a picture is complete and the last record is stored in the metafile, the metafile can be passed to another application by means of the clipboard, embedded within another file, stored on disk, or played repeatedly. A metafile is played when its records are converted to device commands and processed by the appropriate device.

There are two types of metafiles: enhanced and Windows. An enhanced metafile is used in applications written using the Win32 application programming interface (API). The enhanced format consists of a header, a table of handles to GDI objects, a private palette, and an array of metafile records. Enhanced metafiles provide true device independence. (You can think of the picture stored in an enhanced metafile as a "snapshot" of the video display taken at a particular moment. This "snapshot" maintains its dimensions no matter where it appears: on a printer, a plotter, or the desktop, or in the client area of any Win32 application.)

A Windows metafile is used for applications written using the Windows version 3.x application programming interface (API). The Windows format consists of a header and an array of metafile records. Windows-format metafiles are limited in their capabilities and should rarely be used — the Windows-metafile API is supported to maintain backward compatibility with applications that were written to run with Windows version 3.x.


  40.1.1  Enhanced-Format Metafiles

A developer can use enhanced metafiles to store a picture created by using the Win32 GDI functions (including new path and transformation functions). Because the enhanced metafile format is standardized for the Win32 application programming interface (API), pictures that are stored in this format can be copied from one Win32 application to another; and, because the pictures are truly device independent, they are guaranteed to maintain their shape and proportion on any output device.


  40.1.1.1  Enhanced Metafile Records

An enhanced metafile is an array of records. A metafile record is a variable-length ENHMETARECORD structure. This structure identifies the record type, specifies the record length, and contains additional data that is dependent on the record type.

The first record in an enhanced metafile is always the enhanced-metafile header. The header specifies the following information:

•	Size of the metafile, in bytes

•	Dimensions of the picture frame, in device units

•	Dimensions of the picture frame, in .01-millimeter units

•	Number of records in the metafile

•	Offset to an optional text description

•	Size of the optional palette

•	Resolution of the original device, in pixels

•	Resolution of the original device, in millimeters

An optional text description can follow the header record. The text description describes the picture and the author's name. The optional palette specifies the colors used to create the enhanced metafile. The remaining records identify the GDI functions used to create the picture. The following hexadecimal output corresponds to a record generated for a call to the SetMapMode function.

00000011 0000000C 00000004

The value 0x00000011 specifies the record type (corresponds to the EMR_SETMAPMODE constant defined in the file WINGDI.H). The value 0x0000000C specifies the length of the record, in bytes. The value 0x00000004 identifies the mapping mode (corresponds to the MM_LOENGLISH constant defined in the file WINGDI.H).


  40.1.1.2  Enhanced Metafile Operations

A developer creates an enhanced metafile by using the CreateEnhMetaFile function and supplying the appropriate arguments. The Win32 API uses these arguments to maintain picture dimensions, to determine whether the metafile should be stored on a disk or in memory, and so on.

To maintain picture dimensions across output devices, the Win32 API requires the resolution of the reference device. This reference device is the device on which the picture first appeared, and the reference DC is the device context (DC) associated with the reference device. When calling the CreateEnhMetaFile function, the application must supply a handle that identifies this DC. The application can get this handle by calling the GetDC or CreateDC function.

Most applications store pictures permanently and therefore create an enhanced metafile that is stored on a disk; however, there are some instances when this is not necessary. For example, a word processing application that provides chart-drawing capabilities could store a user-defined chart in memory as an enhanced metafile and then copy the enhanced metafile bits from memory into the user's document file. An application that requires a metafile that is stored permanently on a disk must supply the filename when it calls the CreateEnhMetaFile function. If the developer does not supply a filename, Windows automatically treats the metafile as a temporary file and stores it in memory.

The developer can add an optional text description to a metafile containing information about the picture and the author. An application can display these strings in the File Open dialog box to provide the user with information about metafile contents that will help in selecting the appropriate file. If an application includes the text description, the application must supply a pointer to the string when it calls the CreateEnhMetaFile function.

When the CreateEnhMetaFile function is successful, it returns a handle that identifies a special metafile device context. A metafile DC is unique in that it is associated with a file rather than with an output device. When Windows processes a GDI function that received a handle to a metafile DC, it converts the GDI function into an enhanced-metafile record and appends the record to the end of the enhanced metafile.

After a picture is complete and the last record is appended to the enhanced metafile, the application can close the file by calling the CloseEnhMetaFile function. This function closes and deletes the special metafile DC and returns a handle identifying the enhanced metafile. The application can use this handle to accomplish the following tasks:

•	Display the picture stored in the enhanced metafile

•	Create copies of the enhanced metafile

•	Enumerate, edit, or copy the individual records in the enhanced metafile

•	Retrieve the optional description that is stored in the enhanced metafile

•	Retrieve a copy of the enhanced-metafile header

•	Retrieve a binary version of the enhanced metafile

•	Enumerate the colors in the optional palette

•	Convert an enhanced-format metafile into a Windows-format metafile

Some applications create temporary backup (or duplicate) copies of a file before enabling the user to alter the original. An application can create a backup copy of an enhanced metafile by calling the CopyEnhMetaFile function, supplying a handle that identifies the enhanced metafile, and supplying a pointer to the name of the new file.

Most drawing, illustration, and computer-aided design (CAD) applications require a means of editing a picture stored in an enhanced metafile. Although editing an enhanced metafile is a complex task, a developer can use the EnumEnhMetaFile function in combination with other Win32 functions to provide this capability in your application. The EnumEnhMetaFile function and its associated callback function enable the application to process individual records in an enhanced metafile.

Some applications display the text description of an enhanced metafile with the corresponding filename in the File Open dialog box. An application can determine whether this string exists in an enhanced metafile by retrieving the metafile header and examining one of its members. The GetEnhMetaFileHeader function can retrieve the metafile header. If the string exists, the application retrieves it by calling the GetEnhMetaFileDescription function.

Some applications retrieve the contents of a metafile by calling the GetEnhMetaFileBits function; however, before retrieving the contents, the application must specify the size of the file. To get the size, the application can use the GetEnhMetaFileHeader function and examine the appropriate member.

To achieve consistent colors when a picture is displayed on various output devices, an application can call the CreatePalette function and store a logical palette in an enhanced metafile. Other applications that display the picture stored in the enhanced metafile retrieve this palette and call the RealizePalette function before displaying the picture. To determine whether a palette is stored in an enhanced metafile, an application can retrieve the metafile header and examine the appropriate member. If a palette exists, the application can call the GetEnhMetaFilePaletteEntries function to retrieve the logical palette.


  40.1.2  Windows-Format Metafiles

The Win32 API supports the Windows metafile format to maintain compatibility with applications written for Windows version 3.x. Following are the limitations of this format:

•	A Windows-format metafile is application and device dependent. Changes in the application's mapping modes or the device resolution affect the appearance of metafiles created in this format.

•	A Windows-format metafile does not contain a comprehensive header that describes the original picture dimensions, the resolution of the device on which the picture was created, an optional text description, or an optional palette.

•	A Windows-format metafile does not support the new curve, path, and transformation functions.

•	Some Windows-format metafile records cannot be scaled.

•	The metafile device context associated with a Windows-format metafile cannot be queried (that is, an application cannot retrieve device-resolution data, font metrics, and so on).

To convert a Windows-format metafile to an enhanced-format metafile, an application can call the GetMetaFileBitsEx function to retrieve the data from the Windows-format metafile and then call the SetWinMetaFileBits function to convert this data into an enhanced-format metafile.

A developer writing a Win32 application should avoid using the Windows-format functions and use the enhanced-format functions instead.


  40.2  Using Metafiles

This section explains how to perform the following tasks:

•	Create an enhanced metafile to be stored on a disk

•	Display a picture and store it in an enhanced metafile

•	Open an enhanced metafile and play back its contents

•	Edit an enhanced metafile


  40.2.1  Creating an Enhanced Metafile

This section contains an example that demonstrates the creation of an enhanced metafile that is stored on a disk, using a filename specified by the user.

The example uses a device context for the application window as the reference DC. (Windows stores the resolution data for this device in the enhanced-metafile's header.) The application retrieves a handle identifying this DC by calling the GetDC function.

The example uses the dimensions of the application's client area to define the dimensions of the picture frame. Using the rectangle dimensions returned by the GetClientRect function, the application converts the device units to .01-millimeter units and passes the converted values to the CreateEnhMetaFile function.

The example displays a Save As common dialog box that enables the user to specify the filename of the new enhanced metafile. The system appends the three-character .EMF extension to this filename and passes the name to the CreateEnhMetaFile function.

The example also embeds a text description of the picture in the enhanced-metafile header. This description is specified as a resource in the string table of the application's resource file. However, in a working application, this string would be retrieved from a custom control in a common dialog box or from a separate dialog box displayed solely for this purpose.

/* Obtain a handle to a reference DC. */

hdcRef = GetDC(hWnd);

/*

 * Determine the picture frame dimensions.

 * iWidthMM is the display width in millimeters.

 * iHeightMM is the display height in millimeters.

 * iWidthPels is the display width in pixels.

 * iHeightPels is the display height in pixels

 */

iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE);

iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE);

iWidthPels = GetDeviceCaps(hdcRef, HORZRES);

iHeightPels = GetDeviceCaps(hdcRef, VERTRES);

/*

 * Use iWidthMM, iWidthPels, iHeightMM, and

 * iHeightPels to determine the number of

 * .01-millimeter units per pixel in the x-

 *  and y-directions.

 */

iMMPerPelX = (iWidthMM * 100)/iWidthPels;

iMMPerPelY = (iHeightMM * 100)/iHeightPels;

/*

 * Retrieve the coordinates of the client

 * rectangle, in pixels.

 */

GetClientRect(hWnd, &rect);

/* Convert client coordinates to .01-mm units. */

rect.left = rect.left * iMMPerPelX;

rect.top = rect.top * iMMPerPelY;

rect.right = rect.right * iMMPerPelX;

rect.bottom = rect.bottom * iMMPerPelY;

/* Load the filename filter from the string table. */

LoadString(hInst, IDS_FILTERSTRING,

     (LPSTR)szFilter, sizeof(szFilter));

/*

 * Replace the '%' separators that are embedded

 * between the strings in the string-table entry

 * with '\0'.

 */

for (i=0; szFilter[i]!='\0'; i++)

    if (szFilter[i] == '%')

            szFilter[i] = '\0';

/* Load the dialog title string from the table. */

LoadString(hInst, IDS_TITLESTRING,

     (LPSTR)szTitle, sizeof(szTitle));

/* Initialize the OPENFILENAME members. */

szFile[0] = '\0';

Ofn.lStructSize = sizeof(OPENFILENAME);

Ofn.hwndOwner = hWnd;

Ofn.lpstrFilter = szFilter;

Ofn.lpstrFile= szFile;

Ofn.nMaxFile = sizeof(szFile);

Ofn.lpstrFileTitle = szFileTitle;

Ofn.nMaxFileTitle = sizeof(szFileTitle);

Ofn.lpstrInitialDir = (LPSTR)NULL;

Ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;

Ofn.lpstrTitle = szTitle;

/*

 * Display the Filename common dialog box. The

 * filename specified by the user is passed

 * to the CreateEnhMetaFile function and used to

 * store the metafile on disk.

 */

GetSaveFileName(&Ofn);

/* Load the description from the string table. */

LoadString(hInst, IDS_DESCRIPTIONSTRING,

     (LPSTR)szDescription, sizeof(szDescription));

/*

 * Replace the '%' string separators that are

 * embedded between strings in the string-table

 * entry with '\0'.

 */

for (i=0; szDescription[i]!='\0'; i++)

    if (szDescription[i] == '%')

            szDescription[i] = '\0';

/* Create the metafile DC. */

hdcMeta = CreateEnhMetaFile(hdcRef,

          (LPTSTR) Ofn.lpstrFile,

          &rect, (LPSTR)szDescription);

if (!hdcMeta)

    errhandler("CreateEnhMetaFile", hWnd);

/* Release the reference DC. */

ReleaseDC(hWnd, hdcRef);


  40.2.2  Displaying a Picture and Storing It in an Enhanced Metafile

This section contains a code sample demonstrating the creation of a picture and the process of storing the corresponding records in a metafile. The code draws a picture to the display or stores it in a metafile. If a display DC handle is given, it draws a picture to the screen using various GDI functions. If an enhanced metafile DC is given, it stores the same picture in the enhanced metafile.

void DrawOrStore(HWND hwnd, HDC hdcMeta, HDC hdcDisplay)

{

RECT rect;

HDC hDC;

int fnMapModeOld;

HBRUSH hbrOld;

/* Draw it to the display DC or store it in the metafile DC. */

if (hdcMeta)

    hDC = hdcMeta;

else

    hDC = hdcDisplay;

/* Set the mapping mode in the DC. */

fnMapModeOld = SetMapMode(hDC, MM_LOENGLISH);

/* Find the midpoint of the client area. */

GetClientRect(hwnd, (LPRECT)&rect);

DPtoLP(hDC, (LPPOINT)&rect, 2);

/* Select a gray brush. */

hbrOld = SelectObject(hDC, GetStockObject(GRAY_BRUSH));

/* Draw an circle with an one inch raduis. */

Ellipse(hDC, (rect.right/2 - 100), (rect.bottom/2 + 100),

       (rect.right/2 + 100), (rect.bottom/2 - 100));

    .

    . /* Perform remaining drawing and clean-up operations. */

    .

}


  40.2.3  Opening an Enhanced Metafile and Displaying Its Contents

This section contains a code sample demonstrating how an application opens an enhanced metafile stored on disk and displays the associated picture in the client area.

The example uses the Open common dialog box to enable the user to select an enhanced metafile from a list of existing files. It then passes the name of the selected file to the GetEnhMetaFile function, which returns a handle identifying the file. This handle is passed to the PlayEnhMetaFile function in order to display the picture.

LoadString(hInst, IDS_FILTERSTRING,

     (LPSTR)szFilter, sizeof(szFilter));

/*

 * Replace occurrences of '%' string separator

 * with '\0'.

 */

for (i=0; szFilter[i]!='\0'; i++)

    if (szFilter[i] == '%')

            szFilter[i] = '\0';

LoadString(hInst, IDS_DEFEXTSTRING,

     (LPSTR)szDefExt, sizeof(szFilter));

/*

 * Use the OpenFilename common dialog box

 * to obtain the desired filename.

 */

 szFile[0] = '\0';

 Ofn.lStructSize = sizeof(OPENFILENAME);

 Ofn.hwndOwner = hWnd;

 Ofn.lpstrFilter = szFilter;

 Ofn.lpstrCustomFilter = (LPSTR)NULL;

 Ofn.nMaxCustFilter = 0L;

 Ofn.nFilterIndex = 1L;

 Ofn.lpstrFile = szFile;

 Ofn.nMaxFile = sizeof(szFile);

 Ofn.lpstrFileTitle = szFileTitle;

 Ofn.nMaxFileTitle = sizeof(szFileTitle);

 Ofn.lpstrInitialDir = (LPSTR) NULL;

 Ofn.lpstrTitle = (LPSTR)NULL;

 Ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

 Ofn.nFileOffset = 0;

 Ofn.nFileExtension = 0;

 Ofn.lpstrDefExt = szDefExt;

 GetOpenFileName(&Ofn);

/* Open the metafile. */

hemf = GetEnhMetaFile(Ofn.lpstrFile);

/* Retrieve a handle to a window DC. */

hDC = GetDC(hWnd);

/* Retrieve the client rectangle dimensions. */

GetClientRect(hWnd, &rct);

/* Draw the picture. */

PlayEnhMetaFile(hDC, hemf, &rct);

/* Release the metafile handle. */

DeleteEnhMetaFile(hemf);

/* Release the window DC. */

ReleaseDC(hWnd, hDC);


  40.2.4  Editing an Enhanced Metafile

To edit a picture stored in an enhanced metafile, an application must perform the following tasks:

1.	Use hit-testing to capture the cursor coordinates and retrieve the position of the object (line, arc, rectangle, ellipse, polygon, or irregular shape) that the user wants to alter.

2.	Convert these coordinates to logical (or world) units.

3.	Call the EnumEnhMetaFile function and examine each metafile record.

4.	Determine whether a given record corresponds to a GDI drawing function.

5.	If it does, determine whether the coordinates stored in the record correspond to the line, arc, ellipse, or other graphics element that intersects the coordinates specified by the user.

6.	Upon finding the record that corresponds to the output that the user wants to alter, erase the object on the screen that corresponds to the original record.

7.	Delete the corresponding record from the metafile, saving a pointer to its location.

8.	Permit the user to redraw or replace the object.

9.	Convert the GDI functions used to draw the new object into one or more enhanced-metafile records.

10.	Store these records in the enhanced metafile.


  40.3  Functions

Following are the functions used with enhanced format metafiles.

CloseEnhMetaFile
CopyEnhMetaFile
CreateEnhMetaFile
DeleteEnhMetaFile
EnhMetaFileProc
EnumEnhMetaFile
GdiComment
GetEnhMetaFile
GetEnhMetaFileBits
GetEnhMetaFileDescription
GetEnhMetaFileHeader
GetEnhMetaFilePaletteEntries
GetWinMetaFileBits
PlayEnhMetaFile
PlayEnhMetaFileRecord
SetEnhMetaFileBits
SetWinMetaFileBits

The following functions are provided for compatibility with Windows-format metafiles:

CloseMetaFile
CopyMetaFile
CreateMetaFile
DeleteMetaFile
EnumMetaFile
EnumMetaFileProc
GetMetaFile
GetMetaFileBitsEx
PlayMetaFile
PlayMetaFileRecord
SetMetaFileBitsEx


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


41.1  About Printing
  Chapter 41    Printing and Print Spooler

41.1  About Printing

Microsoft® Windows (™)  provides a complete set of functions that allow applications to print on a variety of devices: laser printers, vector plotters, raster printers, and fax machines. One of the chief features of these functions is their support of device independence; instead of issuing device-specific commands to draw output on a particular printer or plotter, an application calls high-level functions from the graphics device interface (GDI). For example, to print a bitmapped image, an application would call the BitBlt function, supplying the coordinates for the bitmap as well as handles identifying the source and destination device contexts. The BitBlt function call would then be converted to raw device commands by a printer device driver. The device driver is a Windows dynamic-link library (DLL) that supports the Windows device-driver interface (DDI). A device driver generates raw device commands when it processes the DDI function calls made by the graphics engine. The graphics engine is a Windows DLL that converts print-processor output into device-driver function calls. These commands are processed by the printer when it prints the image. The syntax, number, and type of these commands vary from device to device.


  41.1.1  Default Printing Interface

In addition to GDI and the device driver, the default in the Win32 API printing interface consists of several other components that process output before it arrives at the printer. These components are the print spooler, the print processor, the graphics engine, and the monitor.


  41.1.1.1  Print Spooler

The primary component of the printing interface is the print spooler. The print spooler is a Windows executable file that manages the printing process. This includes retrieving the location of the correct printer driver, loading that driver, converting high-level-function calls to journal records, storing those journal records on disk as a print job, and so on.

The spooler is loaded at startup and continues to run until the operating system is shut down. Windows Print Manager provides a graphic interface that the user or system administrator can use to access and configure the spooler; however, if Print Manager is disabled or shut down, the spooler continues to run.

Applications that print create a printer device context (DC). When an application creates a printer DC, the spooler performs necessary tasks such as determining the location of the required printer driver, then loading the appropriate printer driver. It also determines the data type used to record the print job. The supported data types include: journal records, ASCII text, and PostScript. A print job is a document stored internally (by using one of the supported data types) that may contain one or more pages of output. It may consist of multiple forms; for example, a job may consist of one envelope and three pages of A4 paper. A print job is defined (or bracketed) by two functions: StartDoc and EndDoc.

The default data type for a print job is the journal record. A journal record is a compact data structure used to store text-output commands, raster-graphics commands, and so on. When an application calls the StartDoc function, the spooler creates a journal file and a data file, and begins storing journal records in the journal file. Each time the application calls one of the GDI drawing functions, one or more new journal records are created and stored in the journal file. The journal and data files are created in an operating-system directory. The spooler uses the journal file to store journal records, and uses the data file to record the type of form, the print-job data type, the target printer, and so on. These files are deleted by the spooler when the job has successfully printed.


  41.1.1.2  Print Processor

The spooler monitors the current print jobs and the target printer to determine the appropriate time to print a job. Once the spooler determines that a job should be printed, it calls the print processor. The print processor is a Windows DLL that reads and converts journal records into DDI calls.


  41.1.1.3  Graphics Engine

The graphics engine converts the print processor output into device-driver function calls. The device driver, in turn, processes these calls and converts them into raw device commands that the device can process.


  41.1.1.4  Monitor

Once a device driver has converted an entire journal file into raw device commands, the file of converted commands is passed back to the spooler. The spooler sends these low-level commands to a monitor. A monitor is a Windows DLL that passes the raw device commands over the network, through a parallel port, or through a serial port and to the device.


  41.1.2  Printer Device Contexts

Just as an application requires a display DC before it can begin drawing in the client area of a window, it needs a special printer DC before it can begin sending output to a printer. A printer DC is similar to a display DC in that it is an internal data structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen (for line drawing), a brush (for painting and filling), and a font (for text output).

Unlike a display DC, printer DCs are not owned by the window manager component and cannot be obtained by calling the GetDC function. Instead, an application must call the CreateDC or PrintDlg function. When an application calls the CreateDC function, it must supply a driver and port name. This data is stored in one of the operating system initialization (.INI) files. It can be retrieved by calling the EnumPrinters function.

When an application calls the PrintDlg function and sets the PD_RETURNDC constant in the Flags member of the PRINTDLG structure, Windows automatically returns a handle identifying the user's selected printer device context. For an example of code that demonstrates this task, see Section 41.2.2, »Displaying a Print Dialog Box and Retrieving a Printer Device Context«.


  41.1.3  Printer Escapes

Windows version 3.x supported as many as 64 special functions called printer escapes that applications used to access special device features. An application calls these functions by specifying one of 64 predefined constants as the second argument to the Escape function. For example, one of these application printing on a PostScript printer could draw a PostScript graphics object called a path by calling the Escape function and supplying the BEGIN_PATH and END_PATH constants. Improvements to GDI in the Win32 API have made many of these escapes obsolete. As a case in point, the Win32 version of GDI supports a complete set of path functions that applications can use to draw paths on any device; thus, these new functions render the previous printer escapes obsolete.

Of the 64 original printer escapes, only 11 are supported in the Win32 API. However, of these 11, only 2 (QUERYESCSUPPORT and PASSTHROUGH) should be called by applications developed for the Win32 API. The remaining 9 are supported strictly for compatibility with applications written for Windows 3.x.

Following are the 11 supported escapes:

•	ABORTDOC

•	ENDDOC

•	GETPHYSPAGESIZE

•	GETPRINTINGOFFSET

•	GETSCALINGFACTOR

•	NEWFRAME

•	NEXTBAND

•	PASSTHROUGH

•	QUERYESCSUPPORT

•	SETABORTPROC

In addition to supporting the original Escape function, the Win32 API supports a new extended escape function ExtEscape. This function allows applications to access capabilities of a particular device not directly available through GDI.


  41.1.4  WYSIWYG Display and Output

Most applications attempt to support what you see is what you get (WYSIWYG) output. This means that text drawn with a 10-point Helvetica Bold font in the application's window should have a similar appearance when it is printed. Obtaining true WYSIWYG output is virtually impossible and even undesirable in most cases. This is due, in part, to the differences in video and printer technologies; a pixel on a screen is generally larger than a dot on a common laser printer. Viewing distances are different as well; a computer user typically sits about two feet away from the screen, but a reader's eyes are usually one foot or less from the printed page.

To compensate for legibility differences between screens and the printed page, Windows supports a unit called the logical inch that is always specified in pixels. For a video display, the logical inch is always greater than the physical inch, to compensate for the longer viewing distance and the (generally) coarser resolution. For printers, the logical inch is always equal to the physical inch.

To obtain WYSIWYG effects when drawing text, applications can use the CreateFont function to specify the typeface name and point size of an ideal (or logical) font, then call the SelectObject function to identify the display or printer DC. When the application calls the SelectObject function, Windows selects a physical font that is the closest possible match to the specified logical font. When Windows selects the display font, it chooses a physical font that is larger than the actual point size. From the user's perspective, however, it appears to be very close to the correct height. When Windows selects the font for the printer, it chooses a physical font that is actually the requested point size. For more information about fonts and text output, see Chapter 35, »Fonts and Text«.

To obtain WYSIWYG effects when drawing bitmapped graphics, applications can retrieve the width and height, in logical inches, of the screen and the printed page. Using these values, the application can create horizontal and vertical scaling factors to maintain the proportion of bitmapped images when they are drawn on a printer. For an example that demonstrates this process, see Section 41.2.4, »Printing a Document«. For more information about bitmaps and bitmap output, see Chapter 29, »Bitmaps«.


  41.2  Using the Printing Functions

This section contains code examples that demonstrate how to print text and graphics. The code was taken from an application that allows a user to open and display a 16-color bitmapped image stored as a .BMP file. »This illustration« shows the application's window after the user opened the file WINLOGO.BMP.

In addition to displaying the bitmapped image, the application allows the user to configure the printer and then print the image, as well as a string of text specifying the location of the file which contained the image. The application prints the text at the top of the page and the image in the center of the page.


  41.2.1  Opening and Displaying a .BMP File

In the sample application, a user is able to open a .BMP file that contains a bitmapped image and display that image in the client area of the application's window. The user selects the file to be opened when the application displays the Open dialog box. (For more information about the Open dialog box, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.)

After the user selects a file and closes the dialog box, the file and path names are stored in members of the OPENFILENAME structure. The application uses this data to open the appropriate file and retrieve the bitmap header and data. The following example shows the code required to retrieve this data:

 /* Retrieve a handle identifying the file. */

 hfbm = CreateFile(ofn.lpstrFile, GENERIC_READ,

        FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES) NULL,

        OPEN_EXISTING, FILE_ATTRIBUTE_READONLY,

        (HANDLE) NULL);

 /* Retrieve the BITMAPFILEHEADER structure. */

 ReadFile(hfbm, &bmfh, sizeof(BITMAPFILEHEADER),

     &dwRead, (LPOVERLAPPED)NULL);

 /* Retrieve the BITMAPFILEHEADER structure. */

 ReadFile(hfbm, &bmih, sizeof(BITMAPINFOHEADER),

     &dwRead, (LPOVERLAPPED)NULL);

 /* Allocate memory for the BITMAPINFO structure. */

 hmem1 = GlobalAlloc(GHND,

     sizeof(BITMAPINFOHEADER) +

     ((1<<bmih.biBitCount) * sizeof(RGBQUAD)));

 lpbmi = GlobalLock(hmem1);

 /*

  * Load BITMAPINFOHEADER into the BITMAPINFO

  * structure.

  */

 lpbmi->bmiHeader.biSize = bmih.biSize;

 lpbmi->bmiHeader.biWidth = bmih.biWidth;

 lpbmi->bmiHeader.biHeight = bmih.biHeight;

 lpbmi->bmiHeader.biPlanes = bmih.biPlanes;

 lpbmi->bmiHeader.biBitCount = bmih.biBitCount;

 lpbmi->bmiHeader.biCompression = bmih.biCompression;

 lpbmi->bmiHeader.biSizeImage = bmih.biSizeImage;

 lpbmi->bmiHeader.biXPelsPerMeter = bmih.biXPelsPerMeter;

 lpbmi->bmiHeader.biYPelsPerMeter = bmih.biYPelsPerMeter;

 lpbmi->bmiHeader.biClrUsed = bmih.biClrUsed;

 lpbmi->bmiHeader.biClrImportant = bmih.biClrImportant;

 /*

  * Retrieve the color table.

  * 1 << bmih.biBitCount == 2 ^ bmih.biBitCount

  */

 ReadFile(hfbm, lpbmi->bmiColors,

     ((1<<bmih.biBitCount) * sizeof(RGBQUAD)),

     &dwRead, (LPOVERLAPPED) NULL);

 /*

  * Allocate memory for the required number of

  * bytes.

  */

 hmem2 = GlobalAlloc(GHND,

     (bmfh.bfSize - bmfh.bfOffBits));

 lpvBits = GlobalLock(hmem2);

 /* Retrieve the bitmap data. */

 ReadFile(hfbm, lpvBits,

     (bmfh.bfSize - bmfh.bfOffBits),

     &dwRead, (LPOVERLAPPED) NULL);

 /*

  * Create a bitmap from the data stored in the

  * .BMP file.

  */

 hbm = CreateDIBitmap(hdc, &bmih,

     CBM_INIT, lpvBits,

     lpbmi, DIB_RGB_COLORS);

/*

 * Unlock the global memory objects and

 * close the .BMP file.

 */

 GlobalUnlock(hmem1);

 GlobalUnlock(hmem2);

 CloseHandle(hfbm);

 /* Set the fDisplayBitmap flag. */

 if (hbm)

     fDisplayBitmap = TRUE;

 else

     TextOut(hdc, 100, 100, "LoadBitmap Failed", 17);

 /* Paint the window (and draw the bitmap). */

 GetClientRect(hwnd, &rect);

 InvalidateRect(hwnd, &rect, TRUE);

 UpdateWindow(hwnd);

Once the bitmap data is retrieved, the bitmapped image can be drawn in the application's client area. The following example shows the code required to draw the bitmap.

case WM_PAINT:

    BeginPaint(hwnd, &ps);

        if (fDisplayBitmap) {

            hdcMem = CreateCompatibleDC(hdc);

            SelectObject(hdcMem, hbm);

            GetObject(hbm, sizeof(BITMAP), (LPSTR) &bm);

            BitBlt(hdc, 0, 0, bmih.biWidth, bmih.biHeight,

                hdcMem, 0, 0, SRCCOPY);

            DeleteDC(hdcMem);

        }

    EndPaint(hwnd, &ps);

    break;


  41.2.2  Displaying a Print Dialog Box and Retrieving a Printer Device Context

The first step in printing involves setting up the printer and obtaining a printer device context. In the sample application, the File menu contains two options: Print and Print Setup. By selecting either option, the user can configure the printer. When the user selects the Print Setup option, the Print Setup dialog box is displayed and the user can select a printer, a page orientation, a paper size, and so on. When the user selects the Print option, the Print dialog box is displayed and the user can select a range of pages, a print quality, a number of copies, and so on. The user can also display the Print Setup dialog box by clicking the Setup push button. »This illustration« shows the Print dialog box that appears when the user selects the Print option.

The Print and the Print Setup dialog boxes are both displayed by initializing the members of a PRINTDLG structure and calling the PrintDlg function. (For more information about displaying the Print Setup dialog box, see Chapter 76, "Common Dialog Box Library," in Microsoft Win32 Programmer's Reference, Volume 2.) In addition to retrieving user-specified data, the PrintDlg function can be used to obtain a printer device context by setting the Flags member of PRINTDLG to PD_RETURNDC. The following example code shows how this can be done.

/* Initialize the PRINTDLG members. */

pd.lStructSize = sizeof(PRINTDLG);

pd.hDevMode = (HANDLE) NULL;

pd.hDevNames = (HANDLE) NULL;

pd.Flags = PD_RETURNDC;

pd.hwndOwner = hwnd;

pd.hDC = (HDC) NULL;

pd.nFromPage = 1;

pd.nToPage = 1;

pd.nMinPage = 0;

pd.nMaxPage = 0;

pd.nCopies = 1;

pd.hInstance = (HANDLE) NULL;

pd.lCustData = 0L;

pd.lpfnPrintHook = (LPPRINTHOOKPROC) NULL;

pd.lpfnSetupHook = (LPSETUPHOOKPROC) NULL;

pd.lpPrintTemplateName = (LPSTR) NULL;

pd.lpSetupTemplateName = (LPSTR)  NULL;

pd.hPrintTemplate = (HANDLE) NULL;

pd.hSetupTemplate = (HANDLE) NULL;

/* Display the PRINT dialog box. */

PrintDlg(&pd);


  41.2.3  Preparing to Print

The following code sample determines whether the selected printer is capable of printing bitmaps by calling the GetDeviceCaps function and specifying the RASTERCAPS flag. By examining this function's return value, the application can determine whether it should print a document or inform the user that the device does not support raster output.

/*

 * Examine the raster capabilities of the device

 * identified by pd.hDC to verify that it supports

 * the BitBlt function.

 */

if (!(GetDeviceCaps(pd.hDC, RASTERCAPS)

    & RC_BITBLT)) {

    DeleteDC(pd.hDC);

    MessageBox(hwnd,

        "Printer cannot display bitmaps.",

        "Device Error",

        MB_OK);

    break;

}

After the sample application determines that the selected printer is capable of printing bitmaps, it follows these steps:

1.	Sets a Boolean flag that the application's abort procedure can examine to determine whether to allow printing to continue.

2.	Registers the application's print-job abort function.

3.	Displays a modeless Cancel dialog box.

4.	Disables the application's window while the dialog box is displayed.

/*

 * Set the flag used by the AbortPrintJob

 * dialog procedure.

 */

 bPrint = TRUE;

/*

 * Register the application's AbortProc

 * function with GDI.

 */

 SetAbortProc(pd.hDC, AbortProc);

/* Display the modeless Cancel dialog box. */

 hdlgCancel = CreateDialog(hinst, (LPTSTR) "AbortDlg",

    hwnd, (DLGPROC) AbortPrintJob);

/* Disable the application's window. */

 EnableWindow(hwnd, FALSE);

Once the application registers its abort procedure with Windows, GDI calls the procedure repeatedly during the printing process to determine whether to cancel a job. In the current version of the Win32 API, GDI calls this function approximately every 2 seconds until the entire job has been spooled.

If the user does choose to cancel the job, GDI notifies the spooler that it should delete the corresponding journal file from the print queue and reset the printer to its default state.


  41.2.3.1  The Abort Procedure

Any application written for Windows that supports printing should provide an abort procedure and a modeless dialog that allow a user to cancel a print job. The abort procedure for the sample application contains a message loop that retrieves messages for the modeless dialog box.

BOOL CALLBACK AbortProc(HDC hdc, int nCode)

{

    MSG msg;

    /*

     * Retrieve and remove messages from the thread's message

     * queue.

     */

    while (PeekMessage((LPMSG) &msg, (HWND) NULL,

            0, 0, PM_REMOVE)) {

        /* Process any messages for the Cancel dialog box. */

        if (!IsDialogMessage(hdlgCancel, (LPMSG) &msg)) {

            TranslateMessage((LPMSG) &msg);

            DispatchMessage((LPMSG) &msg);

         }

    }

    /*

     * Return the global bPrint flag (which is set to FALSE

     * if the user presses the Cancel button).

     */

     return bPrint;

}

This procedure must be exported in the application's module-definition file.


  41.2.3.2  The Cancel Dialog Box

The Cancel dialog box typically contains a single push button that allows the user to cancel a print job. The following template for the Cancel dialog box was taken from the application's resource file.

AbortDlg DIALOG LOADONCALL MOVEABLE DISCARDABLE 33, 32, 160, 70

CAPTION "Sample Printing App"

STYLE WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_VISIBLE |

      WS_POPUP | WS_SYSMENU

BEGIN

    CONTROL "Now Printing: ", IDD_TEXT, "static",

        SS_CENTER | WS_CHILD, 0, 10, 160, 8

    CONTROL "", IDD_FILE, "static",

        SS_CENTER | WS_CHILD, 0, 25, 160, 8

    CONTROL "Cancel", IDD_CANCEL, "button",

        BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD,

        60, 45, 45, 15

END

The example code that follows shows the dialog box procedure for the sample application.

LRESULT CALLBACK AbortPrintJob(

        HWND hwndDlg,             /* window handle of dialog box     */

        UINT message,             /* type of message                 */

        WPARAM wParam,            /* message-specific information    */

        LPARAM lParam)            /* message-specific information    */

{

    switch (message) {

        case WM_INITDIALOG: /* message: initialize dialog box  */

            /* Initialize the static text control. */

            SetDlgItemText(hwndDlg, IDD_FILE, ofn.lpstrFile);

            return TRUE;

        case WM_COMMAND: /* message: received a command */

            /* User pressed "Cancel" button--stop print job. */

            MessageBox(hwndDlg, "Incoming", "WM_COMMAND", MB_OK);

            bPrint = FALSE;

            return TRUE;

        default:

            return FALSE;              /* didn't process a message   */

    }

        UNREFERENCED_PARAMETER(lParam);

        UNREFERENCED_PARAMETER(wParam);

        UNREFERENCED_PARAMETER(message);

}


  41.2.4  Printing a Document

Once the application initializes the necessary variables, registers its abort procedure, and displays its modeless Cancel dialog box, it can start the print job by calling the StartDoc function.

After the application begins a print job, it can define individual pages in the document by calling the StartPage and EndPage functions and embedding the appropriate GDI drawing function calls within this bracket. After the application has defined the last page, it can close the document and end the print job by calling the EndDoc function.

The following example shows the code required to print a string of text and a bitmapped image. The string of text, centered at the top of the page, identifies the path and file name for the file that contains the bitmapped image. The bitmapped image, centered vertically and horizontally on the page, is drawn while maintaining the same proportions used to draw the image in the application's client area.

                /*

                 * Initialize the members of a DOCINFO

                 * structure.

                 */

                 di.cbSize = sizeof(DOCINFO);

                 di.lpszDocName = "Bitmap Printing Test";

                 di.lpszOutput = (LPTSTR) NULL;

                /*

                 * Begin a print job by calling the StartDoc

                 * function.

                 */

                 nError = StartDoc(pd.hDC, &di);

                 if (nError == SP_ERROR) {

                     errhandler("StartDoc", hwnd);

                     goto Error;

                    }

                /*

                 * Inform the driver that the application is

                 * about to begin sending data.

                 */

                 nError = StartPage(pd.hDC);

                 if (nError <= 0) {

                     errhandler("StartPage", hwnd);

                     goto Error;

                    }

                /*

                 * Retrieve the number of pixels-per-logical-inch

                 * in the horizontal and vertical directions

                 * for the display upon which the bitmap

                 * was created.

                 */

                 fLogPelsX1 = (float) GetDeviceCaps(hdc, LOGPIXELSX);

                 fLogPelsY1 = (float) GetDeviceCaps(hdc, LOGPIXELSY);

                /*

                 * Retrieve the number of pixels-per-logical-inch

                 * in the horizontal and vertical directions

                 * for the printer upon which the bitmap

                 * will be printed.

                 */

                 fLogPelsX2 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSX);

                 fLogPelsY2 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSY);

                /*

                 * Determine the scaling factors required to

                 * print the bitmap and retain its original

                 * proportions.

                 */

                 if (fLogPelsX1 > fLogPelsX2)

                    fScaleX = (fLogPelsX1 / fLogPelsX2);

                 else

                    fScaleX = (fLogPelsX2 / fLogPelsX1);

                 if (fLogPelsY1 > fLogPelsY2)

                    fScaleY = (fLogPelsY1 / fLogPelsY2);

                 else

                    fScaleY = (fLogPelsY2 / fLogPelsY1);

                /*

                 * Compute the coordinate of the upper left

                 * corner of the centered bitmap.

                 */

                 cWidthPels = GetDeviceCaps(pd.hDC, HORZRES);

                 xLeft = ((cWidthPels / 2) -

                            ((int) (((float) bmih.biWidth) * fScaleX)) / 2);

                 cHeightPels = GetDeviceCaps(pd.hDC, VERTRES);

                 yTop = ((cHeightPels / 2) -

                            ((int) (((float) bmih.biHeight) * fScaleY)) / 2);

                /*

                 * Create a memory DC that is compatible with

                 * the printer and select the bitmap (which

                 * the user requested) into this DC.

                 */

                 hdcMem = CreateCompatibleDC(pd.hDC);

                 if (!SelectObject(hdcMem, hbm))

                    errhandler("SelectObject Failed", hwnd);

                /*

                 * Use the StretchBlt function to scale the

                 * bitmap and maintain its original proportions

                 * (that is, if the bitmap was square when it

                 * appeared in the application's client area,

                 * it should also appear square on the page).

                 */

                 if (!StretchBlt(pd.hDC, xLeft, yTop,

                         (int) ((float) bmih.biWidth * fScaleX),

                         (int) ((float) bmih.biHeight * fScaleY),

                         hdcMem, 0, 0,

                         bmih.biWidth, bmih.biHeight,

                         SRCCOPY))

                     errhandler("StretchBlt Failed", hwnd);

                /* Delete the memory DC. */

                 DeleteDC(hdcMem);

                /*

                 * Retrieve the width of the string that

                 * specifies the full path and filename for the

                 * file that contains the bitmap.

                 */

                 GetTextExtentPoint(pd.hDC, ofn.lpstrFile,

                     ofn.nFileExtension + 3,

                     &szMetric);

                /*

                 * Compute the starting point for the

                 * text-output operation. The string will

                 * be centered horizontally and positioned

                 * three-lines down from the top of the page.

                 */

                 xLeft = ((cWidthPels / 2) - (szMetric.cx / 2));

                 yTop = (szMetric.cy * 3);

                /*

                 * Print the path and filename for the bitmap,

                 * centered at the top of the page.

                 */

                 TextOut(pd.hDC, xLeft, yTop, ofn.lpstrFile,

                     ofn.nFileExtension + 3);

                /*

                 * Determine whether the user has pressed

                 * the Cancel button in the AbortPrintJob

                 * dialog box; if the button has been pressed,

                 * call the AbortDoc function. Otherwise, inform

                 * the spooler that the page is complete.

                 */

                 nError = EndPage(pd.hDC);

                 if (nError <= 0) {

                    errhandler("EndPage", hwnd);

                    goto Error;

                 }

                /* Inform the driver that the document has ended. */

                 nError = EndDoc(pd.hDC);

                 if (nError <= 0) {

                    errhandler("EndDoc", hwnd);

                 }

Error:

                /* Enable the application's window. */

                EnableWindow(hwnd, TRUE);

                /* Remove the AbortPrintJob dialog box. */

                DestroyWindow(hdlgCancel);

                /* Delete the printer DC. */

                DeleteDC(pd.hDC);

Because the pixels on a screen typically have different dimensions than the dots on a printer, it is necessary to scale bitmapped images to obtain WYSIWYG output. This is done by first obtaining horizontal and vertical scaling factors, then applying these factors to the width and height values passed to the bitmap drawing function StretchBlt. In the sample application, these scaling factors were obtained by retrieving the horizontal and vertical logical-pixel count for the two devices. Once the scaling factors were obtained, they were used to adjust the bitmap width and height.

To center the bitmap on the page, the application first computed the width and height of the scaled bitmap. (The bitmap was scaled in order to maintain the original proportions of the image.) These values were divided by two and then subtracted from half of the width and height of the page. The results define the coordinates of the upper left corner of the bitmap.

To center the text at the top of the page, the application retrieved the width and height of the string specifying the path names and filenames by calling the GetTextExtentPoint function. Once these values were obtained, the application used the height to position the string three lines down the page and the width to position the string horizontally centered on the page.

»This illustration« shows a representation of the page that appeared when the application printed the bitmapped image in the file WINLOGO.BMP. This illustration also depicts the variables used to position the text and to position and scale the bitmap.


  41.3  Functions and Messages

Following are the functions used to print.


  Functions

AbortDoc
CancelDC
DeviceCapabilitiesEx
EndDoc
EndPage
Escape
ExtEscape
SetAbortProc
StartDoc
StartPage

Following are the functions used to access the print spooler.

AbortPrinter
AbortProc
AddForm
AddJob
AddMonitor
AddPort
AddPrinter
AddPrinterDriver
AddPrintProcessor
AddPrintProvidor
AdvancedDocumentProperties
ClosePrinter
ConfigurePort
DeleteForm
DeleteMonitor
DeletePort
DeletePrinter
DeletePrinterDriver
DeletePrintProcessor
DeletePrintProvidor
DocumentProperties
EndDocPrinter
EndPagePrinter
EnumForms
EnumJobs
EnumMonitors
EnumPorts
EnumPrinterDrivers
EnumPrinters
EnumPrintProcessors
GetForm
GetJob
GetPrinter
GetPrinterData
GetPrinterDriver
GetPrinterDriverDirectory
GetPrintProcessorDirectory
OpenPrinter
PrinterProperties
ReadPrinter
ScheduleJob
SetForm
SetJob
SetPrinter
SetPrinterData
StartDocPrinter
StartPagePrinter
WritePrinter


  Messages

WM_SPOOLERSTATUS


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Programmer's Reference, Volume 1:
Window Management and Graphics Device Interface


Application Window


Open Dialog Box


Message Box


Keyboard Input Model


Flags and Values in lParam


Push Buttons


Three-state Check Box


Radio Button


Group Box


Window Procedure for Dialog Box


Simple List Box


Directory Listing in List Box


Owner-drawn List Box


Single-line Edit Controls


Combo Box in Dialog Box


Owner-drawn Combo Box


Tool Bar Window


Scroll Bars


Parts of a Scroll Bar


Scroll Bar Control


Notification Codes


Scrolling Operation for SB_PAGEDOWN


Before ScrollWindows


After ScrollWindow


Icon Static Control


Text Static Controls


Frame Static Controls


Client Area after Processing WM_PAINT


Rectangular Static Controls


File Menu


System Menu


Cascading Menu


Checkmarks in Menu


Grayed Menu Items


Menu Item Position


Mnemonics in menus


Accelerator Keys


Charts in Menus


Fonts in Menus


Check Boxes in Menus


Checked and Unchecked Boxes in Menus


Processing Accelerator Keystrokes


Accelerators in Write Edit Menu


User-editable Accelerators


IntersectRect function


UnionRect function


Drawing Target Rectangle


Dragging Bitmap to Target Rectangle


Bitmap Dropped on Target Rectangle


Standard Cursors and Identifiers


Custom Cursors


Variations in Caret Appearance


Standard Icons and Identifiers


Custom Icons


Selecting Data with the Mouse


Typical Edit Menu


Server Applications Logic


Multipad: A Typical MDI Application


Desktop Wallpaper Bitmap


Before and After Bitmap Scaling


Before and After FloodFill


Windows Bitmap Format


Application-Defined Brush Origin


Logical Brush Types


Logical Stock Brushes


Logical Hatch Brushes


Logical Pattern Brushes


Custom Brush Dialog Box


Style Attributes


Pattern Attributes


Hatch Attributes


End Cap Attributes


Join Attributes


Modified Color Common Dialog Box


Region Types


Square and Circle Combinations


Alternate and Winding Fill Modes


Capture of Desktop Contents


Rectangle Created by User


Clipped Output


Highlighted Pixels


LineTo, Polyline, and PolyPolyline Functions


Arc Function


Bezier Splines


AngleArc Function


Markers Designating Bezier Points


Pie Chart Dialog Box


Ellipse Function


Chord Function


Pie Function


Polygon Function


Filled shapes


Font Size Measurement


Century and Bookman Fonts


ChooseFont Function Dialog Box


TextOut Function


Intercharacter Spacing


Unjustified and Justified Text


The Three ABC Width Components


Vertical Text Metric Values


Color Common Dialog Box


Object Cross-Section


Arial Font Text


Clip Path Graphic Effect


Text String Drawing


Clip Path Text Sting Drawing


Original View


Scaled View


Translated View


Rotated View


Sheared View


Reflected View


A Coordinate Space


SetWorldTransform Function


Translating a Rectangle


Scaling a Rectangle


Rotating a Rectangle


Counterclockwise Rotation of a Point


Shearing a Rectangle


Reflecting a Rectangle


Window to Viewport Origin Mapping


Application Window


Print Dialog Box


Printed Page Representation


Introduction
Programmer's Reference, Volume 2: Systems Services, Multimedia, Extensions, and Application Notes

Introduction

The Microsoft® Win32 (™)  application programming interface (API) allows applications to exploit the power of 32-bits on the Microsoft® Windows (™)  family of operating systems. Applications written to the Win32 API are scalable on single and multiprocessor systems, and portable to RISC architectures. These manuals document the complete Win32 API including window management, graphics, file I/O, threading, memory management, security and networking.


  Organization of this Manual

Following are brief descriptions of the main parts of this manual.

Part 3, "System Services," describes the portion of the Win32 API that applications use to manage the basic multitasking services of Windows. The chapters in this part provide detailed information about processes and threads, memory management, networks, dynamic linking, security, and other information about the system.

Part 4, "Multimedia Services," describes the multimedia portion of the Win32 API. The multimedia API supports audio, media control, multimedia file input and output (I/O), and enhanced timer services.

Part 5, "Extension Libraries," describes the libraries that add additional features to the Win32 API. These features include common dialog boxes, management functions that simplify dynamic data exchange (DDE), such shell enhancements as the drag-drop feature, file installation functions, and data decompression functions.

Part 6, "Application Notes," describes techniques an application can use to implement some Windows features and enhancements. This part of the manual explains how to create a Control Panel application, how to create and install extensions for File Manager, how to use the dynamic data exchange interface of Program Manager, and how to select from among the many interprocess communications methods available to a Win32 application.

Appendix A, "Error Codes," lists and describes the error codes that Win32 API functions return when they fail.

Appendix B, "Virtual-Key Codes," shows the symbolic constant names, hexadecimal values, and keyboard equivalents for Windows virtual-key codes.

Appendix C, "Locale Identifiers," lists and describes the symbolic constants used in adapting an application for the international marketplace.

Appendix D, "Manufacturer and Product Identifiers", lists the manufacturer and product identifiers currently used with the Microsoft Windows operating system with Multimedia Extensions.

Appendix E, "MCI Command String Syntax Summary", lists the Media Control Interface command strings and their syntax.

Appendix F, "Raster Operation Codes", lists and describes the binary and ternary raster operations used by the graphics device interface.

This manual is intended to describe the purpose of the Win32 API and to explain the operating system concepts behind the API. It also shows how the Win32 functions work together to carry out specific tasks. It does not show how to write, compile, and link programs containing these functions.


About the Microsoft Win32 Programmers Reference
  About the Microsoft Win32 Programmer's Reference

The Microsoft Win32 Programmer's Reference, a set of five volumes, fully describes the Win32 API, including functions and related data types, macros, structures, and messages. The Programmer's Reference is the source for specific information about programming for Windows.

Volumes 1 and 2 describe the purpose of the functions in the Win32 API and explains the concepts and principles behind the functions. These volumes are intended for programmers who are new to Windows or who are learning parts of it for the first time. These two volumes provide the basic information needed for an understanding of Windows programming.

Volumes 3 and 4 consist of an alphabetical listing of the Win32 functions. These volumes define the details of the syntax, parameters, and return values of each function. Volume 5 contains alphabetical listings of the Win32 data types, macros, messages, and structures. Volumes 3 through 5 are intended for programmers already acquainted with Windows programming and who need only specifics of particular functions.


  Microsoft Windows and the C Programming Language

The C programming language is the preferred development language for Windows-based applications. Many of the programming features of Windows were designed with C in mind. Windows-based applications can also be developed in other languages, but C is the most straightforward and easiest language to use to access Windows functions. For this reason, all syntax and program samples are written in the C programming language.

The Win32 API uses many types, macros, and structures that are not part of standard C language. These types, macros, and structures have been defined to make the task of creating Windows-based applications simpler and to make application sources clearer and easier to understand. All types, macros, and structures discussed in this manual are defined in the Win32 C-language header files.

Many chapters in Volumes 1 and 2 include code examples. These examples show how to use Win32 functions to accomplish tasks. In nearly all cases, the examples are code fragments, not complete programs. Each example is intended to show the context in which a function can be used; often, an example presumes that variables, structures, and constants used in the example have been defined or initialized, or both. An example may also use comments to describe a task, without presenting the appropriate statements.

Although the examples are not complete, you can use them in your applications by taking the following steps:

•	Include the WINDOWS.H file in your program.

•	Define the appropriate include constants for the functions, structures, and constants used in the example.

•	Define and initialize all variables.

•	Replace comments that represent tasks with appropriate statements.

•	Check return values for errors and take appropriate actions.

Some examples in this manual combine both Win32 and C run-time functions to carry out their tasks.


  Document Conventions

The following conventions are used throughout this manual to define syntax.

Convention	Meaning
Bold text	Denotes a term or character to be typed literally, such as a predefined data type or function name (HWND or CreateWindowEx), a command, or a command-line option (/x). You must type these terms exactly as shown.
Italic text	Denotes a placeholder or variable: You must provide the actual value. For example, the statement SetCursorPos(X,Y) requires you to substitute values for the X and Y parameters.
[ ]	Enclose optional parameters.
|	Separates an either/or choice.
...	Specifies that the preceding item may be repeated.
.	Represents an omitted portion of a sample application.
.
.
In addition, certain text conventions are used to help you understand this material.

Convention	Meaning
SMALL CAPITALS	Indicate the names of keys, key sequences, and key combinations — for example, ALT+SPACEBAR.
FULL CAPITALS	Indicate filenames and paths, most type and structure names (which are also bold), and constants.
monospace	Sets off code examples and shows syntax spacing.


Memory Management
  Chapter 42    Memory Management

42.1  About Memory Management

In the Microsoft Win32 application programming interface (API), each process has its own 32-bit virtual address space that enables addressing up to 4 gigabytes (GB) of memory. The 2 GB in low memory (0x00 to 0x7FFFFFFF) are available to the user, and the 2 GB in high memory (0x80000000 to 0xFFFFFFFF) are reserved for the kernel. The virtual addresses used by a process do not represent the actual physical location of an object in memory. Instead, for each process the kernel maintains a page map, a data structure used to translate virtual addresses into corresponding physical addresses.

This chapter describes Win32 memory management. It also explains how to allocate and use memory.


  42.1.1  Virtual Address Space and Physical Storage

The virtual address space of each process is much larger than the total physical memory, random-access memory (RAM), available to all processes. To increase the size of physical storage, the kernel uses the disk for additional storage. The total amount of storage available to all executing processes is the sum of physical memory, RAM, and the free space on disk available to the paging file, a disk file used to increase the amount of physical storage. Physical storage and the virtual (logical) address space of each process are organized into pages, units of memory, whose size depends on the host computer. For example, on x86 computers the host page size is 4 kilobytes.

To maximize its flexibility in managing memory, the kernel can move the pages of physical memory to and from a paging file on disk. When a page is moved in physical memory, the kernel updates the page maps of the affected processes. When the kernel needs space in physical memory, it moves the least recently used pages of physical memory to the paging file. Manipulation of physical memory by the kernel is completely transparent to applications, which operate only in their virtual address spaces.

The pages of a process's virtual address space can be in one of the following states.

State	Description
Free	A free page is not currently accessible, but it is available to be committed or reserved.
Reserved	A reserved page is a block of the process's virtual address space that has been set aside for future use. The process cannot access a reserved page, and there is no physical storage associated with it. A reserved page reserves a range of virtual addresses that cannot be used subsequently by other allocation operations (that is, by malloc, LocalAlloc, and so on). A process can use the VirtualAlloc function to reserve pages of its address space and later to commit the reserved pages. It can use the VirtualFree function to release them.
Committed	A committed page is one for which physical storage (in memory or on disk) has been allocated. It can be protected to allow either no access or read-only access, or it can have read and write access. A process can use the VirtualAlloc function to allocate committed pages. The GlobalAlloc and LocalAlloc functions allocate committed pages with read-write access. A committed page allocated by VirtualAlloc can be decomitted by the VirtualFree function, which releases the page's storage and changes the state of the page to reserved.


  42.1.2  Global and Local Functions

A process can use the GlobalAlloc and LocalAlloc functions to allocate memory. In the linear 32-bit environment of the Win32 API, the local heap and the global heap are not distinguished. As a result, there is no difference between the memory objects allocated by these functions.

Memory objects allocated by GlobalAlloc and LocalAlloc are in private, committed pages with read-write access. Private memory cannot be accessed by other processes. Memory allocated by using GlobalAlloc with the GMEM_DDESHARE flag is not actually shared globally as it is in Windows version 3.x. However, this flag is available for compatibility purposes and can be used by some implementations to enhance the performance of dynamic data exchange (DDE) operations. Applications requiring shared memory for other purposes must use file-mapping objects. Multiple processes can map a view of the same file-mapping object to provide named shared memory. For more information about file mapping, see Chapter 47, »File Mapping«, and Section 42.1.6, »Shared Memory«.

By using GlobalAlloc and LocalAlloc, you can allocate a block of memory of any size that can be represented by 32 bits. You are limited only by the available physical memory, including storage in the paging file on disk. These functions, along with the other global and local functions that manipulate global and local memory objects, are included in the Win32 API for compatibility with 16-bit versions of Windows. However, the change from a 16-bit segmented memory model to a 32-bit virtual memory model has made some of the functions and their options unnecessary or meaningless. For example, there are no longer near and far pointers, because both local and global allocations return 32-bit virtual addresses.

Both GlobalAlloc and LocalAlloc can allocate fixed or movable memory objects. Movable objects can also be marked as discardable. In earlier versions of Windows, movable memory objects were important for memory management. They enabled the system to compact the heap when necessary to make space available for other memory allocations. By using virtual memory, the system is able to manage memory by moving pages of physical memory without affecting the virtual addresses of the processes using the pages. When the system moves a page of physical memory, it simply maps the process's virtual page to the new location of the physical page. Movable memory is still useful for allocating discardable memory. When the system needs additional physical storage, it can use a "least recently used" algorithm to free discardable memory that is not locked. Use discardable memory for data you need infrequently and can regenerate easily.

When allocating a fixed memory object, GlobalAlloc and LocalAlloc return a 32-bit pointer that the calling process can immediately use to access the memory. For movable memory, the return value is a handle. To get a pointer to a movable memory object, the calling process uses the GlobalLock and LocalLock functions. These functions lock the memory so that it cannot be moved or discarded. The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, GlobalLock and LocalLock increment this count by one, and the GlobalUnlock and LocalUnlock functions decrement the count by one. Locked memory is not moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc or LocalReAlloc function. The memory block of a locked memory object remains locked in memory until its lock count is decreased to zero, at which time it can be moved or discarded.

The actual size of the memory allocated by GlobalAlloc or LocalAlloc can be larger than the requested size. To determine the actual number of bytes allocated, use the GlobalSize or LocalSize function. If the amount allocated is greater than the amount requested, the process can use the entire amount.

The GlobalReAlloc and LocalReAlloc functions change the size, in bytes, or the attributes of a memory object allocated by GlobalAlloc and LocalAlloc. The size can increase or decrease.

The GlobalFree and LocalFree functions release memory allocated by GlobalAlloc, LocalAlloc, GlobalReAlloc, or LocalReAlloc.

Other global and local functions include the GlobalDiscard, LocalDiscard, GlobalFlags, LocalFlags, GlobalHandle, and LocalHandle functions. To discard a specified discardable memory object without invalidating the handle, use GlobalDiscard or LocalDiscard. The handle can be used later by GlobalReAlloc or LocalReAlloc to allocate a new block of memory associated with the same handle. To return information about a specified memory object, use GlobalFlags or LocalFlags. The information includes the object's lock count and indicates whether the object is discardable or has already been discarded. To return the handle of the memory object associated with a specified pointer, use GlobalHandle or LocalHandle.


  42.1.3  Standard C Library Functions

Win32 processes can safely use the standard C library functions (malloc, free, and so on) to manipulate memory. When used with previous versions of Windows, these functions had potential problems that no longer apply to applications using the Win32 API. For example, malloc allocates a fixed pointer that does not take advantage of movable memory. This is no longer a problem because the system is free to manage memory by moving pages of physical memory without affecting the virtual addresses. Similarly, the distinction between near and far pointers is no longer relevant. So, unless you want to allocate discardable memory, it is now reasonable to use the standard C library functions for memory management.


  42.1.4  Virtual Memory Functions

The Win32 API provides a set of virtual memory functions that enable a process to manipulate or determine the status of pages in its virtual address space. Many applications are able to satisfy their memory needs by using the standard allocation functions (GlobalAlloc, LocalAlloc, malloc, and so on). However, virtual memory functions provide some functionality not available in the standard allocation functions. They can perform the following operations:

•	Reserve a range of a process's virtual address space. Reserving address space does not allocate any physical storage, but it prevents other allocation operations from using the specified range. It does not affect the virtual address spaces of other processes. Reserving pages prevents needless consumption of physical storage, while enabling a process to reserve a range of its address space into which a dynamic data structure can grow. The process can allocate physical storage for this space, as needed.

•	Commit a range of reserved pages in a process's virtual address space so that physical storage (either in RAM or on disk) is accessible only to the allocating process.

•	Specify read-write, read-only, or no access for a range of committed pages. This differs from the standard allocation functions that always allocate pages with read-write access.

•	Free a range of reserved pages, making the range of virtual addresses available for subsequent allocation operations by the calling process.

•	Decommit a range of committed pages, releasing their physical storage. Decommitting a range makes their storage available for subsequent allocation by any process.

•	Lock one or more pages of committed memory into physical memory (RAM), so the system cannot swap the pages out to the paging file.

•	Query information about a range of pages in the virtual address space of the calling process or of a specified process.

•	Change the access protection for a specified range of committed pages in the virtual address space of the calling process or a specified process.

The virtual memory functions manipulate pages of memory. The functions use the size of a page on the current computer to round off specified sizes and addresses. For a description of the way these values are rounded for each function, see the Microsoft Win32 Programmer's Reference, Volumes 3 and 4.

To determine the size of a page on the current computer, use the GetSystemInfo function.

The VirtualAlloc function performs one of the following operations:

•	Reserves one or more free pages.

•	Commits one or more reserved pages.

•	Reserves and commits one or more free pages.

You can specify the starting address of the pages to be reserved or committed, or you can allow the system to determine the address. The function rounds the specified address to the appropriate page boundary. Reserved pages are not accessible, but committed pages can be allocated with the PAGE_READWRITE, PAGE_READONLY, or PAGE_NOACCESS flag. When pages are committed, storage is allocated in the paging file, but each page is initialized and loaded into physical memory only at the first attempt to read from or write to that page. You can use normal pointer references to access memory committed by the VirtualAlloc function.

The VirtualFree function performs one of the following operations:

•	Decommits one or more committed pages, changing the state of the pages to reserved. Decommitting pages releases the physical storage associated with the pages, making it available to be allocated by any process. Any block of committed pages can be decommitted.

•	Releases a block of one or more reserved pages, changing the state of the pages to free. Releasing a block of pages makes the range of reserved addresses available to be allocated by the process. Reserved pages can be released only by releasing the entire block that was initially reserved by VirtualAlloc.

•	Decommits and releases a block of one or more committed pages simultaneously, changing the state of the pages to free. The specified block must include the entire block initially reserved by VirtualAlloc, and all of the pages must be currently committed.

The VirtualLock function enables a process to lock one or more pages of committed memory into physical memory, RAM. Locking pages prevents the system from swapping the pages out to the paging file. It can be useful when it is necessary to ensure that critical data is accessible without disk access. Locking pages in memory is dangerous because it restricts the system's ability to manage memory. Excessive use of VirtualLock can degrade system performance by causing executable code to be swapped out to the paging file. The VirtualUnlock function unlocks memory locked by VirtualLock.

The VirtualQuery and VirtualQueryEx functions return information about a region of consecutive pages beginning at any specified address in the address space of a process. VirtualQuery returns information about memory in the calling process. VirtualQueryEx returns information about memory in a specified process and is intended to support debuggers that need information about a process being debugged. The region of pages is bounded by the specified address rounded down to the nearest page boundary. It extends through all subsequent pages with the following attributes in common:

•	The state of all pages is the same: either committed, reserved, or free.

•	If the initial page is not free, all pages in the region are part of the same initial allocation of pages that were reserved by a call to the VirtualAlloc function.

•	The access protection of all pages is the same (that is, the PAGE_READONLY, PAGE_READWRITE, or PAGE_NOACCESS flag).

The VirtualProtect function enables a process to modify the access protection of any committed page in the address space of a process. For example, a process can allocate read-write pages to store sensitive data, and then it can change the access to read only or no access to protect against accidental overwriting. VirtualProtect is typically used with pages allocated by VirtualAlloc, but it also works with pages committed by any of the other allocation functions. However, VirtualProtect changes the protection of entire pages, and pointers returned by the other functions are not necessarily aligned on page boundaries. The VirtualProtectEx function is similar to VirtualProtect except that it changes the protection of memory in a specified process. Changing the protection is useful to debuggers in accessing the memory of a process being debugged.


  42.1.5  Heap Functions

The heap functions enable a process to create a private heap, a block of one or more pages in the address space of the calling process. The process can then use a separate set of functions to manage the memory in that heap. There is no difference between memory allocated from a private heap and that allocated by using the standard allocation functions (GlobalAlloc, LocalAlloc, malloc, and so on).

The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. HeapCreate specifies both an initial size and a maximum size for the heap. The initial size determines the number of committed, read-write pages initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a contiguous block of the process's virtual address space into which the heap can grow. Additional pages are automatically committed from this reserved space if requests by HeapAlloc exceed the current size of committed pages, assuming that the physical storage for it is available. Once the pages are committed, they are not decommitted until the process is terminated or the heap is destroyed by calling the HeapDestroy function.

The memory of a private heap object is accessible only to the process that created it. If a dynamic-link library (DLL) creates a private heap, it does so in the address space of the process that invoked the DLL. It is accessible only to that process.

The HeapAlloc function allocates a specified number of bytes from a private heap and returns a pointer to the allocated block. The pointer identifies the block for the HeapFree function to release or for the HeapSize function to determine the size.

Memory allocated by HeapAlloc is not movable. Because the system cannot compact a private heap, the heap can become fragmented.

A possible use for the heap functions is to create a private heap when a process starts up, specifying an initial size sufficient to satisfy the memory requirements of the process. If the call to the HeapCreate function fails, the process can terminate or notify the user of the memory shortage; if it succeeds, however, the process is assured of having the memory it needs.


  42.1.6  Shared Memory

In the Win32 API, shared memory is implemented by file mapping. All memory allocated by the other allocation methods (the GlobalAlloc, LocalAlloc, HeapAlloc, or VirtualAlloc function) is accessible only to the calling process. Memory allocated by a DLL, however, is in the address space of the process that invoked the DLL and is not accessible to other processes using the same DLL.

Named file mapping provides an easy way to create a block of shared memory. One process specifies a name when it uses the CreateFileMapping function to create a file-mapping object. Other processes specify the same name to either the CreateFileMapping or OpenFileMapping function to obtain a handle of the mapping object. The names of event objects, semaphore objects, mutex objects, and file-mapping objects share the same name space. If a specified name matches the name of an existing object of a different type, an error occurs. When creating named objects, try to use unique names and check the function return values for duplicate name errors.

Each process specifies its handle of the file-mapping object in the MapViewOfFile function to map a view of the file into its own address space. The views of all processes for a single file-mapping object are mapped into the same sharable pages of physical storage. However, the virtual addresses of the mapped views can vary from one process to another, unless the MapViewOfFileEx function is used to map the view at a specified address. Although sharable, the pages of physical storage used for a mapped file view are not global; they are not accessible to processes that have not mapped a view of the file.

A file-mapping object is associated with a disk file the system uses when the mapped view is swapped out of physical memory and onto the disk. This disk swap file can be the system's paging file or it can be some other file that was specified when the file-mapping object was created. In that case, the memory is initialized along with the contents of the file. Mapping a specified file in the file system is useful for processes that need to share the data in an existing file or that want to use the file to save the data generated by the sharing processes. If you map a specified file, you should open it for exclusive access and keep the handle open until you are finished with the shared memory. This will prevent other processes from opening another handle on the file to use ReadFile or WriteFile or to create additional mapping objects for the same file, any of which actions can lead to unpredictable results.

Any pages committed by mapping a view of a file are released when the last process with a view of the mapping object either terminates or unmaps its view by calling the UnmapViewOfFile function. At this time, the specified file (if any) associated with the mapping object is updated. A specified file can also be forced to update by calling the FlushViewOfFile function.

For more information about file mapping, see Chapter 47, »File Mapping«, For an example of shared memory in a DLL, see Chapter 50, »Dynamic-Link Libraries«.

If multiple processes have write access to shared memory, access to the memory should be synchronized. For more information about interprocess synchronization, see Chapter 44, »Synchronization«.


  42.1.7  Access Validation

The Win32 API provides a set of functions that a process can use to verify whether it has a specified type of access to a given memory address or range of addresses. The following access validation functions are available.

Function	Description
IsBadCodePtr
	Determines whether the calling process has read access to the memory at the specified address.
IsBadReadPtr
	Determines whether the calling process has read access to the memory at a specified range of addresses.
IsBadStringPtr
	Determines whether the calling process has read access to the memory pointed to by a null-terminated string pointer. The function validates access for a specified number of characters or until it encounters the string's terminating null character.
IsBadWritePtr
	Determines whether the calling process has write access to the memory at a specified range of addresses.
The IsBadHugeReadPtr and IsBadHugeWritePtr functions are also available for compatibility with earlier versions of Windows that distinguished between normal memory allocations and huge allocations occupying multiple segments. In the Win32 API, these functions are equivalent to IsBadReadPtr and IsBadWritePtr.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when one of these functions indicates that the process has the desired access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception. For more information about structured exception handling, see Chapter 64, »Structured Exception Handling«.


  42.2  Using the Virtual Memory Functions

This section explains how to use the virtual memory functions for dynamic allocation.

The following example illustrates the use of the VirtualAlloc and VirtualFree functions in reserving and committing memory as needed for a dynamic array. First, VirtualAlloc is called to reserve a block of pages, and NULL is specified as the base address parameter, forcing the kernel to determine the location of the block. Later, VirtualAlloc is called whenever it is necessary to commit a page from this reserved region, and the base address of the next page to be committed is specified.

The example uses the try-except structured exception-handling syntax to commit pages from the reserved region. Whenever a page fault exception occurs during execution of the try block, the filter function in the expression preceding the except block is executed. If the filter function can allocate another page, execution continues in the try block at the point where the exception occurred. Otherwise, the exception handler in the except block is executed. For more information about structured exception handling, see Chapter 64, »Structured Exception Handling«.

As an alternative to this dynamic allocation, the process can simply commit the entire region instead of only reserving it. However, this consumes physical storage that might not be needed, making it unavailable for use by other processes.

The example uses VirtualFree to free the reserved and committed pages when it is finished with them. The function is called twice: first to decommit the committed pages and again to release the entire region of reserved pages.

#define PAGELIMIT 80

#define PAGESIZE 0x1000

INT PageFaultExceptionFilter(DWORD);

VOID MyErrorExit(LPTSTR);

LPTSTR lpNxtPage;

DWORD dwPages = 0;

VOID UseDynamicVirtualAlloc(VOID) {

  LPVOID lpvBase;

  LPTSTR lpPtr;

  BOOL bSuccess;

  DWORD i;

  /* Reserve pages in the process's virtual address space. */

  lpvBase = VirtualAlloc(

         NULL,               /* system selects address   */

         PAGELIMIT*PAGESIZE, /* size of allocation       */

         MEM_RESERVE,        /* allocates reserved pages */

         PAGE_NOACCESS);     /* protection = no access   */

  if (lpvBase == NULL )

      MyErrorExit("VirtualAlloc reserve");

  lpPtr = lpNxtPage = (LPTSTR) lpvBase;

  /*

   * Use try-except structured exception handling when

   * accessing the pages. If a page fault occurs, the

   * exception filter is executed to commit another page

   * from the reserved block of pages.

   */

  for (i=0; i < PAGELIMIT*PAGESIZE; i++) {

      try {

          /* Write to memory. */

          lpPtr[i] = 'a';

      }

      /*

       * If there is a page fault, commit another page

       * and try again.

       */

      except ( PageFaultExceptionFilter(

                   GetExceptionCode() ) ) {

          /*

           * This is executed only if the filter function is

           * unsuccessful in committing the next page.

           */

          ExitProcess( GetLastError() );

      }

  }

  /* Release the block of pages when you are finished using them. */

  /* First, decommit the committed pages. */

  bSuccess = VirtualFree(

            lpvBase,          /* base address of block    */

            dwPages*PAGESIZE, /* bytes of committed pages */

            MEM_DECOMMIT);    /* decommit the pages       */

  /* Release the entire block. */

  if (bSuccess)

      bSuccess = VirtualFree(

            lpvBase,        /* base address of block     */

            0,              /* releases the entire block */

            MEM_RELEASE);   /* releases the pages        */

}

INT PageFaultExceptionFilter(DWORD dwCode) {

LPVOID lpvResult;

  /* If the exception is not a page fault, exit. */

  if (dwCode != EXCEPTION_ACCESS_VIOLATION) {

      printf("exception code = %d\n", dwCode);

      return EXCEPTION_EXECUTE_HANDLER;

  }

  printf("page fault\n");

  /* If the reserved pages are used up, exit. */

  if (dwPages >= PAGELIMIT) {

      printf("out of pages\n");

      return EXCEPTION_EXECUTE_HANDLER;

  }

  /* Otherwise, commit another page. */

  lpvResult = VirtualAlloc(

      (LPVOID) lpNxtPage, /* next page to commit  */

      PAGESIZE,           /* page size, in bytes  */

      MEM_COMMIT,         /* alloc committed page */

      PAGE_READWRITE);    /* read-write access    */

  if (lpvResult == NULL ) {

      printf("VirtualAlloc failed\n");

      return EXCEPTION_EXECUTE_HANDLER;

  }

  /*

   * Increment the page count, and advance lpNxtPage

   * to the next page.

   */

  dwPages++;

  lpNxtPage += PAGESIZE;

  /* Continue execution where the page fault occurred. */

  return EXCEPTION_CONTINUE_EXECUTION;

}


  42.3  Functions

Following are the Win32 functions used in memory management.

GetProcessHeap
GlobalAlloc
GlobalDiscard
GlobalFlags
GlobalFree
GlobalHandle
GlobalLock
GlobalMemoryStatus
GlobalReAlloc
GlobalSize
GlobalUnlock
HeapAlloc
HeapCreate
HeapDestroy
HeapFree
HeapReAlloc
HeapSize
IsBadCodePtr
IsBadHugeReadPtr
IsBadHugeWritePtr
IsBadReadPtr
IsBadStringPtr
IsBadWritePtr
LocalAlloc
LocalDiscard
LocalFlags
LocalFree
LocalHandle
LocalLock
LocalReAlloc
LocalSize
LocalUnlock
VirtualAlloc
VirtualFree
VirtualLock
VirtualProtect
VirtualProtectEx
VirtualQuery
VirtualQueryEx
VirtualUnlock


Processes and Threads
  Chapter 43    Processes and Threads

43.1  About Processes and Threads

A Microsoft Windows application can consist of more than one process, and a process can consist of more than one thread. The Microsoft Win32 application program interface (API) supports multitasking, which creates the effect of simultaneous execution of multiple processes and threads. This chapter describes processes and threads, and explains how to create and use them.


  43.1.1  Multitasking

A process is a program that is loaded into memory and prepared for execution. Each process has a private virtual address space. A process consists of the code, data, and other system resources — such as files, pipes, and synchronization objects — that are accessible to the threads of the process. Each process is started with a single thread, but additional independently executing threads can be created.

A thread can execute any part of the program's code, including a part executed by another thread. Threads are the basic entity to which the operating system allocates CPU time. Each thread maintains a set of structures for saving its context while waiting to be scheduled for processing time. The context includes the thread's set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread's process. All threads of a process share the virtual address space and can access the global variables and system resources of the process.

A multitasking operating system divides the available CPU time among the threads that need it. In Windows, the Win32 API is designed for preemptive multitasking, which means that the system allocates small slices of CPU time among the competing threads. The currently executing thread is suspended when its timeslice elapses, allowing another thread to run. When the system switches from one thread to another, it saves the context of the suspended thread and restores the saved context of the next thread in the queue.

Because each timeslice is small (on the order of 20 milliseconds), it appears that multiple threads are executing at the same time. This is actually the case on multiprocessor systems, where the executable threads are distributed among the available processors. On a single processor system, however, using multiple threads does not result in more instructions being executed. In fact, the system can slow down if it is forced to keep track of too many threads.

To the user, the advantage of multitasking is the ability to have several applications open and working at the same time. For example, a user can edit a file with one application while another application is printing or recalculating a spreadsheet.

To the application developer, the advantage of multitasking is the ability to create applications that use more than one process, and to create processes that use more than one thread of execution. For example, you can have one thread that handles interactions with the user (keyboard and mouse input), while other threads with lower priority perform the other work of the process. The higher priority of the input thread makes the program nicely responsive to the user, while the other threads ensure that the processor can be used efficiently during the slices of time between keystrokes.


  43.1.1.1  When to Use Multitasking

Any thread of any process can use the CreateThread and CreateProcess functions to create additional threads or processes. An application might use multiple processes for functions that require a private address space and private resources, to protect them from the activities of other threads. Functions that are to be distributed as separate executable modules but that can be integrated to form a single application can benefit from the multi-process approach.

It is useful for a process to have multiple threads in situations where the application has several tasks to run concurrently. For example, an application that opens more than one window can have a separate thread perform the work of the application in each window. Multiple threads can be a convenient way to structure a program that performs several similar or identical tasks. For example, a named pipe server can create a thread to handle communications with each client process that attaches to the pipe. Other examples of using multiple threads are processes that do the following:

•	Handle input for multiple windows.

•	Manage input from several communications devices.

•	Need to distinguish among tasks of varying priority. For example, a high A priority thread handles time-critical tasks and a low-priority thread performs other tasks.

It is typically more efficient for an application to implement multitasking by distributing tasks among the threads of a single process, rather than by creating multiple processes, for the following reasons:

•	The system can create and execute threads more quickly than it can create processes, primarily because the code for threads has already been mapped into the address space of the process, while the code for a new process must be loaded.

•	All threads of a process share the same address space and can access the process's global variables, which can simplify communications between threads.

•	All threads of a process can use open handles to resources such as files and pipes.

For both multiple threads and multiple processes, there are costs and dangers to be considered. The system consumes memory for the structures required by both processes and threads. Keeping track of a large number of threads consumes CPU time. With multiple threads accessing the same resources, you must synchronize the threads to avoid conflicts. This is true for system resources (such as communications ports or disk drives), handles to resources shared by multiple processes (such as file or pipe handles), or the resources of a single process (such as global variables accessed by multiple threads). Failure to synchronize multiple threads properly (in the same or in different processes) can lead to program bugs such as deadlock and race conditions. The Win32 API provides a set of synchronization objects and functions you can use to coordinate multiple threads. For more information about synchronization, see Section 43.1.6, »Synchronizing Execution of Multiple Threads«, and Chapter 44, »Synchronization«.

The Win32 API also provides alternative ways to execute multiple tasks that, in some cases, make multithreaded processes unnecessary. The most significant of these are overlapped I/O and the ability to wait for multiple events.

Overlapped I/O enables a single thread to initiate multiple time consuming I/O requests that can run concurrently. This asynchronous I/O can be performed on files, pipes, serial communications devices, or tape devices. For more information about files, see Chapter 45, »Files«. For more information about pipes, see Chapter 54, »Pipes«. For more information about serial communication devices, see Chapter 68, »Communications«. For more information about tape devices, see Chapter 59, »Tape Backup«.

Waiting for multiple events enables a single thread to block its execution while waiting for any one of several events to occur. This is much more efficient than using multiple threads, each waiting for a single event, or using a single thread that consumes CPU time by continually checking for an event of interest. For more information about waiting for multiple events, see Chapter 44, »Synchronization«.


  43.1.2  Scheduling

The system scheduler controls multitasking by determining which of the competing threads receives the next slice of the processor's time. Each timeslice consists of a fixed number of clock ticks. The Windows scheduler is preemptive, gaining control whenever a clock interrupt occurs, and decrementing the count of clock ticks remaining in the timeslice of the currently executing thread. If the count goes to zero, the scheduler determines which thread runs next. The scheduler maintains a queue of executable threads at each priority level. When the highest priority is shared by more than one executable thread, the next timeslice goes to the thread at the head of the priority queue. The thread that just finished executing is placed at the end of the queue of threads with its priority. Threads that are suspended or blocked (for example, waiting for a semaphore object or waiting for input) are not executable, so until they become unblocked, the scheduler does not allocate any processor time to them, regardless of their priority. When the scheduler awards the next timeslice to a different thread, the context of the currently executing thread is saved, and the machine state is set according to the context of the next executable thread.


  43.1.3  Scheduling Priorities

The scheduling priority of each thread is determined by the following criteria:

•	The priority class of its process (high, normal, or idle)

•	The priority level of the thread within the priority class of its process (lowest, below normal, normal, above normal, highest)

•	The dynamic priority boost, if any, the system applies to the thread's base priority

By default, the priority class of a process is set to normal. The CreateProcess function allows a parent process to specify the priority class of its child processes. Use SetPriorityClass to change the priority class of a process, and GetPriorityClass to determine the current priority class of a process.

There are five priority levels within each priority class. The levels range from lowest (−2) to highest (2). All threads are started with normal (0) priority. The SetThreadPriority function enables you to change the priority level of a thread to any of the five levels. Use the GetThreadPriority function to determine the current priority level of a thread.

The base priority of each thread is the thread's priority level within the priority class of its process. The scheduler uses this base priority to determine a thread's dynamic priority, which it uses to make scheduling decisions. A thread's dynamic priority is never less than its base priority. The scheduler raises and lowers the dynamic priority of a thread to enhance its responsiveness when significant things happen to the thread. For example, whenever a window receives input (such as timer messages, mouse move messages, keyboard input), the scheduler boosts the priorities of all threads within the process that owns the window. In some cases, the dynamic priority of a waiting thread is raised when a wait is satisfied. For example, a wait associated with disk or keyboard I/O results in a dynamic boost when the input occurs.

After raising a thread's dynamic priority, the scheduler reduces that priority by one level each time the thread completes a timeslice, until the thread drops back to its base priority.

In addition to these dynamic priority boosts, the scheduler raises the priority class of the process associated with the foreground window, so it is greater than or equal to the priority class of any background processes. The process's priority class returns to its original setting when it is no longer in the foreground. A user can always make a given window lose the foreground priority boost by clicking on another window or by using the ALT+TAB or CTRL+ESC key combination.

The three priority classes are intended to be used as follows:

Priority	Meaning
IDLE_PRIORITY_CLASS	Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS	Indicates a normal process with no special scheduling needs.
HIGH_PRIORITY_CLASS	Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
REALTIME_PRIORITY_CLASS	Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.
Use the high priority class with extreme care. If a thread runs at the highest priority level for extended periods, other threads in the system will be starved for CPU time. If several threads are set at high priority at the same time, the effect of the high priority is neutralized. The high priority class should be reserved for threads that must respond to time critical events. If your application has a task that requires the high priority class while most of its functions are normal priority, use SetPriorityClass to raise the priority class temporarily; then reduce it once the time critical task has been completed. Another strategy is to create a high priority process that is blocked most of the time, awakening only when the critical task is needed. The important point is that a thread should be high priority and executable only for a brief period, when it has time-critical work to perform.

Having selected a priority class for a multithreaded process, use SetThreadPriority to adjust the relative priority of its threads. A typical strategy is to use a higher priority level for the process's input thread, to ensure responsiveness to the user. Other threads, particularly those that are CPU intensive, can be set to a lower relative priority, to ensure that they can be preempted when necessary. However, if you have a higher priority thread waiting for a lower priority thread to complete some task, be sure to block the execution of the waiting thread (using a wait function, critical section, or Sleep) rather than having it iterate in a loop. Otherwise, the process will deadlock because the lower priority thread will never get scheduled.


  43.1.4  Creating Threads

The CreateThread function creates a new thread for a process. The creating thread must specify the starting address of the code that the new thread is to execute. Typically, the starting address is the name of a function defined in the program's code. A process can have multiple threads simultaneously executing the same function. The function called by the thread takes a single 32-bit parameter and returns a doubleword result.

The following example illustrates the creation of a new thread that executes the ThreadFunc function:

DWORD ThreadFunc(LPDWORD lpdwParam) {

    printf("ThreadFunc:  thread parameter=%d\n", *lpdwParam);

    return 0;

}

DWORD main(VOID) {

    DWORD dwThreadId, dwThrdParam = 1;

    HANDLE hThread;

    hThread = CreateThread(

        NULL,                        /* no security attributes        */

        0,                           /* use default stack size        */

        (LPTHREAD_START_ROUTINE) ThreadFunc, /* thread function       */

        &dwThrdParam,                /* argument to thread function   */

        0,                           /* use default creation flags    */

        &dwThreadId);                /* returns thread the identifier */

    /* Check the return value for success. */

    if (hThread == NULL)

        ErrorExit("CreateThread error\n");

For simplicity, this example passes a pointer to dwThrdParam as an argument to the thread function. This could be a pointer to any type of data or structure, or it could be omitted altogether by passing a NULL pointer and deleting the references to the parameter in ThreadFunc. It is risky to pass the address of the local variable if the creating thread exits before the new thread, because the pointer becomes invalid. Instead, either pass dynamically allocated parameters or make the creating thread wait for the new thread to terminate. Data can also be passed from the creating thread to the new thread using global variables. With global variables, it is usually necessary to synchronize access by multiple threads. For more information about synchronizing, see Section 43.1.6, »Synchronizing Execution of Multiple Threads«.

Using the thread function's argument to pass data to the new thread is particularly useful in processes where the main thread might create multiple threads to execute the same code. In this case, it is inconvenient to use global variables. For example, a process that enables the user to open several files at the same time can create a new thread for each file, with each of the threads executing the same thread function. The creating thread can pass as an argument the unique information (such as the filename) required by each instance of the thread function.

The creating thread can use the arguments to CreateThread to specify the following:

•	The security attributes for the handle of the new thread. These security attributes include an inheritance flag that determines whether the handle can be inherited by child processes. The security attributes also include a security descriptor, which the system uses to perform access checks on all subsequent uses of the thread's handle before access is granted. For more information about security attributes, see Chapter 49, »Security«.

•	The initial stack size of the new thread. The thread's stack is allocated automatically in the memory space of the process; it can grow as needed; and it is freed when the thread terminates.

•	A creation flag that enables you to create the thread in a suspended state. When suspended, the thread does not run until the ResumeThread function is called.

The handle returned by CreateThread has full access rights to the new thread. Subject to security checks, the handle can be used in any of the Win32 API functions that accepts a handle to a thread object. The handle can be duplicated by DuplicateHandle, which enables you to create a thread handle with a subset of the access rights.

A thread can also be created with the CreateRemoteThread function. This is used by debugger processes to create a thread that runs in the address space of another process.


  43.1.5  Suspending Thread Execution

A thread can suspend and resume the execution of another thread using the SuspendThread and ResumeThread functions. While a thread is suspended, it is not scheduled for time on the processor.

SuspendThread is not particularly useful for synchronization, because it does not control the point in the code at which the thread's execution is suspended. However, you might want to suspend a thread in a situation where you are confirming a user's input that would terminate the work of the thread. If confirmed, the thread is terminated; otherwise, it resumes.

If a thread is created in a suspended state, it does not begin to run until ResumeThread is called with a handle to the suspended thread. This can be useful for initializing the thread's state before it begins to run. See Section 43.2.1, »Example: Multithreaded MDI Application«, for an example that uses this method to modify the thread's priority before it can run. Suspending a thread at creation can be useful for one-time synchronization, because ResumeThread ensures that the suspended thread will resume running at the starting point of its code.

A thread can temporarily suspend its own execution for a specified interval by calling the Sleep or SleepEx functions. This is useful particularly in cases where the thread responds to user interaction, as it can delay execution long enough to enable the users to observe the results of their actions. During the sleep interval, the thread is not scheduled for time on the processor.


  43.1.6  Synchronizing Execution of Multiple Threads

To avoid conflicts, it is necessary to synchronize access by multiple threads to shared resources. Synchronization is also necessary to ensure that interdependent code is executed in the proper sequence.

The Win32 API provides a number of objects whose handles can be used to synchronize multiple threads. These objects include:

•	Synchronization objects: mutex, semaphore, and event handles

•	File handles

•	Named pipe handles

•	Console input buffer handles

•	Communication device handles

•	Process handles

•	Thread handles

The state of each of these objects is either signaled or not signaled. When a handle to any of these objects is specified in a call to one of the wait functions — WaitForSingleObject, WaitForMultipleObjects, WaitForSingleObjectEx, or WaitForMultipleObjectsEx — the execution of the calling thread is blocked until the state of the specified object is signaled. As with a suspended thread, a waiting thread consumes very little processor time.

Some of these objects are useful in blocking a thread until some event occurs. For example, a console input buffer handle is signaled when there is unread input, such as a keystroke or mouse button press. Process and thread handles are signaled when the process or thread terminates. This allows a process, for example, to create a child process and then block its own execution until the new process has terminated.

Other objects are useful in protecting shared resources from simultaneous access. For example, multiple threads can each have a handle to a mutex object. Before accessing a shared resource, the threads must call one of the wait functions to wait for the state of the mutex to be signaled. When the mutex becomes signaled, only one waiting thread is released to access the resource. The state of the mutex is immediately reset to not signaled so any other waiting threads remain blocked. When the thread is finished with the resource, it must set the state of the mutex to signaled to free other threads to access the resource.

For the threads of a single process, critical section objects provide another (and slightly more efficient) means of synchronization. A critical section is used like a mutex to enable only one thread at a time to use the protected resource. A thread uses the EnterCriticalSection function to request ownership of a critical section. If it is already owned by another thread, the requesting thread is blocked. After it receives ownership, the thread is free to use the protected resource. The execution of the other threads of the process is not affected unless they attempt to enter the same critical section.

The WaitForInputIdle function makes a thread wait until a specified process is initialized and waiting for user input with no input pending. This can be useful for synchronizing parent and child processes, because CreateProcess returns without waiting for the child process to complete its initialization.

For more about critical sections and synchronization, see Chapter 44, »Synchronization«.


  43.1.7  Thread Local Storage

All threads of a process share the virtual address space and the global variables of that process. Sometimes it is desirable to have static storage that is local to each thread. Of course the local variables of a thread function are local to each thread that runs the function. But when a thread invokes another function, the static or global variables used by that function store the same value for all threads. With thread local storage, one thread allocates an index that can be used by any thread of the process to store and retrieve a different value for each thread.

The following is a typical thread local storage (TLS) scenario:

1.	TlsAlloc is used during process or dynamic-link library (DLL) initialization to allocate a TLS index.

2.	Each thread that needs to use the TLS index allocates dynamic storage, then uses TlsSetValue to associate the index with a pointer to the dynamic storage.

3.	When a thread needs to access its storage, it specifies the TLS index in a call to TlsGetValue to retrieve the pointer.

4.	Each thread frees the dynamic storage that it has associated with a TLS index when it is no longer needed. When all threads have finished using a TLS index, the TlsFree function frees the index.

The constant TLS_MINIMUM_AVAILABLE defines the minimum number of TLS indices available in each process. This minimum is guaranteed to be at least 64 for all systems.

Thread local storage can be useful with DLLs. The DllEntryPoint function performs the initial TLS operations in the context of the process or thread the DLL is attaching to or detaching from. When the DLL attaches to a new process, the entrypoint function calls TlsAlloc to allocate a TLS index for that process. When the DLL attaches to a new thread of that process, the entrypoint function allocates dynamic memory for that thread and uses TlsSetValue to save private data to the index. The DLL stores the TLS index in a global variable that is private to each attached process. The functions of the DLL can use the TLS index in a call to TlsGetValue to access the private data for the calling thread.

For an example illustrating the use of thread local storage, see Section 43.2.4, »Using Thread Local Storage«.


  43.1.8  Terminating a Thread

A thread runs until one of the following events occurs:

•	It calls ExitThread.

•	The thread function returns. This results in an implicit call to ExitProcess for a primary thread, or to ExitThread for other threads.

•	ExitProcess is invoked explicitly or implicitly by any thread of the process.

•	TerminateThread is called with a handle to the thread.

•	TerminateProcess is called with a handle to the thread's process.

When a thread terminates, the state of the thread object changes to signaled, releasing any other threads that had been waiting for the thread to terminate. Then its termination status changes from STILL_ACTIVE to the exit code of the thread.

If a thread is terminated by ExitThread, the entrypoint function of all attached DLLs is invoked with a code indicating that the thread is detaching from the DLL. If a thread is terminated by ExitProcess, the DLL entrypoint functions are invoked once, to indicate that the process is detaching. DLLs are not notified when a thread is terminated by TerminateThread or TerminateProcess. For more information about DLLs, see Chapter 50, »Dynamic-Link Libraries«.

The GetExitCodeThread function returns the termination status of a thread. While a thread is executing, its termination status is STILL_ACTIVE. When a thread terminates, its termination status is the exit code of the thread, which is the value specified in the call to ExitThread, ExitProcess, or TerminateThread, or the value returned by the thread function.

For more information about termination, see Section 43.1.14, »Terminating a Process«.


  43.1.9  Multiple Threads and GDI Objects

To enhance performance, access to graphics device interface (GDI) objects (such as palettes, device contexts, regions, and the like) is not serialized. This creates a potential danger for processes that have multiple threads sharing these objects. For example, if one thread deletes a GDI object while another thread is using it, the results are unpredictable. This danger can be avoided simply by not sharing GDI objects. If sharing is unavoidable (or desirable), the application must provide its own mechanisms for synchronizing access. For more information about synchronizing access, see Section 43.1.6, »Synchronizing Execution of Multiple Threads«.


  43.1.10  Creating Processes

The CreateProcess function creates a new process, which runs independently of the creating process. The function provides two methods for identifying the program to be executed. The most common method is to specify the image file's path and filename. If the lpszImageName argument is NULL, the program is identified in the CommandLine argument.

If CreateProcess succeeds, it returns a PROCESS_INFORMATION structure containing handles and identification numbers for the new process and its primary thread. The thread and process handles are created with full access rights, although access can be restricted if a security descriptor is specified.


  43.1.11  Inheritance

A child process can inherit a number of properties and resources from its parent process. You can also prevent a child process from inheriting anything from its parent process. The following can be inherited:

•	Any inheritable open handle returned by the CreateFile function. This includes handles to files, console input buffers, console screen buffers, named pipes, serial communication devices, and mailslots.

•	Inheritable open handles to process, thread, mutex, event, semaphore, named pipe, anonymous pipe, and file mapping objects.

•	Environment variables.

•	The current directory.

•	The console of parent process, unless the process is detached or a new console is created. A child console process also inherits the parent's standard handles, as well as access to the input buffer and the active screen buffer. For more about console processes, see Chapter 57, »Consoles and Character-Mode Support«.

The fInheritHandles flag of CreateProcess determines whether the inheritable handles of the parent process are inherited by the child process. The inheritability of the handles listed above is specified in the functions used to create, open, or duplicate the handles. This allows a child process to inherit some of its parent's handles, while not inheriting others. For each of these object types there is a creation function (such as CreateProcess or CreateFile) that takes a security attributes argument whose inherit flag determines whether the handle can be inherited. If the security attributes argument is NULL, the handle is not inherited.

Some of these objects have an open function (such as OpenMutex or OpenEvent) with an inherit flag parameter that determines inheritability.

Any of these handles can be duplicated using the DuplicateHandle function by which you can specify whether the handle can be inherited. This can be useful if a process has an inheritable open handle that you do not want to be inherited by the child process. In this case, use DuplicateHandle to open a noninheritable duplicate of the handle; then use CloseHandle to close the inheritable handle. DuplicateHandle can also open an inheritable duplicate of a noninheritable handle.

An inherited handle has the same value and access privileges as the parent process's handle. To use a handle, the child process must retrieve the handle and know the object to which it refers. For most handles, the parent process must communicate this information to the child process. This can be done using the command line or any of the other methods for interprocess communication (such as pipes or shared memory).

An inherited handle refers to the same object as the parent process's handle does. When one process changes the state of the object, the change affects both processes. With file handles, for example, if one process uses a handle to read from a file, the current file position is moved for all processes using the same handle.

A child process inherits the environment variables and current directory of its parent process by default. However, CreateProcess enables the parent process to specify a different current directory or block of environment variables. For more information about environment variables, see Section 43.1.12, »Environment Variables«.

The child process does not inherit the following:

•	Priority class

•	Memory handles

•	Pseudo handles, as in the handles returned by GetCurrentProcess or GetCurrentThread. These handles are valid only for the calling process. For more information about these functions, see Section 43.1.15, »Process and Thread Handles and Identifiers«.

•	DLL module handles returned by LoadLibrary.

•	GDI or User handles, such as HBITMAP or HMENU. Refer to WINDEF.H for a complete list of these handles.


  43.1.12  Environment Variables

Every process has an environment block that contains a set of environment variables and their values. The command processor for Microsoft® Windows NT (™)  (called CMD.EXE) provides the "set" command to display its environment block or to create new environment variables (as in, "set name=value"). Programs started by the command processor inherit the command processor's environment variables.

By default, a child process inherits the environment variables of its parent process. However, you can specify a different environment for the child process by creating a new environment block and passing a pointer to it as a parameter to the CreateProcess function.

The GetEnvironmentStrings function returns a pointer to the environment block of the calling process. This should be treated as a read-only block; do not modify it directly. Instead, use the SetEnvironmentVariable function to change an environment variable. The GetEnvironmentVariable function determines whether a specified variable is defined in the environment of the calling process, and, if so, what its value is. For more information about environments, see the examples in Section 43.2.3, »Changing Environment Variables«.


  43.1.13  Setting Window Properties Using STARTUPINFO

A parent process can specify properties associated with the main window of its child process. A pointer to a STARTUPINFO structure is passed as a parameter to the CreateProcess function. The members of this structure can be used to specify more than a dozen different characteristics of the child's main window. The dwFlags member contains a bit field that determines whether the other members of the structure are used. This allows the creating process to specify values for any subset of the window properties. Default values are used for the properties not specified by dwFlags. The dwFlags member can also force a feedback cursor to be displayed during the initialization of the new process. A process can use the GetStartupInfo function to retrieve the STARTUPINFO structure specified when it was created.

For GUI processes, the STARTUPINFO structure specifies the default values to be used the first time the new process calls CreateWindow and ShowWindow to create and display an overlapped window. The following default values can be specified:

•	The width and height in pixels of the window created by CreateWindow.

•	The location in screen coordinates of the window created by CreateWindow.

•	The nCmdShow parameter of ShowWindow.

For console processes, use the STARTUPINFO specifications only when a new console is created either by CreateProcess with CREATE_NEW_CONSOLE or by AllocConsole. For more about console processes, see Chapter 57, »Consoles and Character-Mode Support«. STARTUPINFO can specify the following console window properties:

•	The size, in character cells, and the location in screen coordinates of the new console window.

•	The size, in character cells, of the new console's screen buffer.

•	The text and background color attributes of the new console's screen buffer.

•	The title of the new console's window.


  43.1.14  Terminating a Process

A process terminates when one of the following occurs:

•	Any thread of the process calls ExitProcess.

•	The primary thread of the process returns. This results in an implicit call to ExitProcess.

•	The last thread of the process terminates.

•	TerminateProcess is called with a handle to the process.

When a process terminates, the following events occur:

•	Open handles to files or other resources are closed automatically. Note that the objects referenced by these handles exist until all open handles are closed. This means that an object remains valid after a process closes, if another process has a handle to it.

•	The state of the process object becomes signaled, satisfying any threads that are waiting for the process to terminate. For more about synchronization, see Section 43.1.6, »Synchronizing Execution of Multiple Threads«.

•	The termination status of the process changes from STILL_ACTIVE to the exit code of the process.

Child processes are not automatically terminated when a parent process terminates.

ExitProcess is the preferred way to terminate a process, because it notifies all attached DLLs of the termination, and it ensures that all threads of the process are terminated. If a process is terminated by ExitProcess, the entrypoint function of all attached DLLs is invoked with a code indicating that the process is detaching from the DLL. DLLs are not notified when a process is terminated by TerminateProcess. For more information about DLLs, see Chapter 50, »Dynamic-Link Libraries«.

When a process is terminated by ExitProcess or TerminateProcess, all threads of the process are terminated immediately with no chance to run additional code (except for the DLL process detach code if ExitProcess is called). This means that the process does not execute code in termination handler blocks such as the "finally" block of the try-finally handler supported by Microsoft compilers. For more information about handlers, see Chapter 64, »Structured Exception Handling«.

The primary thread of a process differs from the other threads of a process in that ExitProcess (rather than ExitThread) is invoked implicitly when a primary thread returns. Alternatively, the primary thread can avoid terminating other threads by explicitly calling ExitThread before it exits. In this case, one of the remaining threads explicitly calls ExitProcess, to ensure that all threads of the process are terminated. For example, it is possible for an attached DLL to create a thread that does not terminates unless ExitProcess is invoked.

ExitProcess can be invoked implicitly by the system. For most unhandled exceptions, the system's default action is to call ExitProcess. For console processes, ExitProcess is called by the default handler function that can be invoked when a CTRL+C or CTRL+BREAK signal is received. For more about console application, see Chapter 57, »Consoles and Character-Mode Support«. Note that this default handling of console interrupt signals can terminate parent and child processes, because all processes attached to a console receive the signal. An interrupt signal received by a console window is propagated only to attached console processes. Detached processes and processes that have created new console windows are not affected. GUI processes are not affected by CTRL+C or CTRL+BREAK signals.

The GetExitCodeProcess function returns the termination status of a process. While a process is running, its termination status is STILL_ACTIVE. When a process terminates, its termination status is the exit code of the process, which is the value specified in the call to ExitProcess or TerminateProcess, or the value returned by the main or WinMain function of the process. If a process is terminated in some other way (for example, by a fatal unhandled exception or a CTRL+C signal) the process's termination code is the exception code that caused the termination. The process's exit code is also used as the exit code of all of the threads that had not previously terminated.


  43.1.15  Process and Thread Handles and Identifiers

When a new thread is created by CreateThread or CreateRemoteThread, a handle of the thread is returned. Similarly, when a new process is created by CreateProcess, handles of the new process and its primary thread are returned. These handles are created with full access rights, and — subject to security access checking — can be used in any of the functions that accepts a thread or process handle. These handles can be inherited by child processes, depending on the inheritance flag specified when they are created. The handles are valid until closed, even after the process or thread they represent is terminated.

The OpenProcess function opens a handle to a process specified by its process identifier. OpenProcess enables you to specify the handle's access rights and inheritability.

A process can use the GetCurrentProcess function to retrieve a pseudohandle of its own process object; a thread can use the GetCurrentThread function to retrieve a pseudo handle to its own thread object. These pseudohandles are valid only for the calling process; they cannot be inherited or duplicated for use by other processes.

The functions that create a process or thread also return an identifier that uniquely identifies the process or thread throughout the system. A process can use the GetCurrentProcessId function to get its own process identifier. Similarly, a thread can use the GetCurrentThreadId function to get its own thread identifier. The identifiers are valid from the time the thread or process is created until the thread or process terminates.


  43.2  Using Processes and Threads

The examples in this section illustrate the following:

•	Creating multiple threads for a process with multiple windows. Each window is associated with a separate thread.

•	Creating a console child process whose standard input and output handles have been redirected.

•	Creating a child process whose environment variables are different from those of the parent process.

•	Using thread local storage.


  43.2.1  Example: Multithreaded MDI Application

The following example shows how to use multiple threads in a multiple document interface (MDI) process. The process has a single main window, but can have any number of child windows. The primary thread of the process performs initialization and also handles messages to all windows through the MainWndProc and ChildWndProc functions.

Each time a child window is created, a new thread is also created. In this example, the new thread only checks continually to see if it is time to terminate. In a real application the new thread could be used to draw the contents of the window or to carry out the functions associated with the window.

The ThreadFunc function is specified in CreateThread as the code for the new thread to execute. The handle of the child window associated with the thread is passed as a parameter to ThreadFunc. The child window's handle is also a parameter to ChildWndProc when a message is dispatched to the child window. A handle is necessary for any communication between a child window and its corresponding thread. Both ThreadFunc and ChildWndProc use the window handle in the SetWindowLong function to access the 32-bit value that is reserved for application use in each window structure. In this example, the 32-bit value is a termination flag. When ChildWndProc gets the WM_CLOSE message, it sets the flag; ThreadFunc checks the flag each time through its loop.

This example shows how to use normal priority for the primary thread and below-normal priority for the other threads. Because the primary thread passes all messages for both the main window and the child windows, its higher relative priority ensures responsiveness to user input. (Even when the child threads are left at normal priority, the scheduler automatically boosts the priority of the input thread when necessary.)

When the user terminates the process by closing the main window, a global boolean parameter is set to terminate the child threads. At this point, the primary thread waits for each child thread to terminate before proceeding. This is necessary only if you want the threads to clean up save changes to a file, detach from DLLs before closing. Without waiting, the primary thread terminates the process by returning before the lower priority threads were able to run any additional code.

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#define MM_NEWWIN       8001

typedef struct _PTHREADLIST {

  HANDLE hThread;

  LPVOID lpvNext;

} THREADLIST, *PTHREADLIST;

/* Globals */

HANDLE hModule;            /* handle to .EXE file for this process */

HWND   hwndMain = NULL;    /* handle to main window                */

BOOL fKillAll = FALSE;     /* sets TRUE to terminate all threads   */

PTHREADLIST pHead = NULL;  /* head of linked list of thread info.  */

/* Forward declarations */

BOOL InitializeApp(VOID);

LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);

DWORD ThreadFunc(HWND);

VOID AddThreadToList(HANDLE);

VOID ErrorExit(LPSTR);

/* Primary thread:  Initialize the application and dispatch messages. */

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,

        LPSTR lpszCmdLn, int nShowCmd) {

    MSG msg;

    hModule = GetModuleHandle(NULL);

    if (! InitializeApp())

        ErrorExit("InitializeApp failure!");

    while (GetMessage(&msg, NULL, 0, 0)) {

      TranslateMessage(&msg);

      DispatchMessage(&msg);

    }

    return 1;

    UNREFERENCED_PARAMETER(hInst);

    UNREFERENCED_PARAMETER(hPrevInst);

    UNREFERENCED_PARAMETER(lpszCmdLn);

    UNREFERENCED_PARAMETER(nShowCmd);

}

/* Register window classes and create the main window. */

BOOL InitializeApp(VOID) {

    HMENU hmenuMain, hmenuPopup;

    WNDCLASS wc;

    /* Register a window class for the main window. */

    wc.style            = CS_OWNDC;

    wc.lpfnWndProc      = MainWndProc;

    wc.cbClsExtra       = 0;

    wc.cbWndExtra       = 0;

    wc.hInstance        = hModule;

    wc.hIcon            = LoadIcon(NULL,IDI_APPLICATION);

    wc.hCursor          = LoadCursor(NULL, IDC_ARROW);

    wc.hbrBackground    = (HBRUSH)(COLOR_BACKGROUND+1);

    wc.lpszMenuName     = NULL;

    wc.lpszClassName    = "MainWindowClass";

    if (! RegisterClass(&wc))

        return FALSE;

    /* Register a window class for child windows. */

    wc.lpfnWndProc      = ChildWndProc;

    wc.lpszClassName    = "ThreadWindowClass";

    if (! RegisterClass(&wc))

        return FALSE;

    /* Create a menu for the main window. */

    hmenuMain = CreateMenu();

    hmenuPopup = CreateMenu();

    if (! AppendMenu(hmenuPopup, MF_STRING, MM_NEWWIN, "&New Window"))

        return FALSE;

    if (! AppendMenu(hmenuMain, MF_POPUP, (UINT) hmenuPopup, "&Threads"))

        return FALSE;

    /* Create the main window. */

    hwndMain = CreateWindow("MainWindowClass", "Primary Window",

        WS_OVERLAPPED | WS_CAPTION | WS_BORDER | WS_THICKFRAME |

        WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CLIPCHILDREN |

        WS_VISIBLE | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,

        CW_USEDEFAULT, CW_USEDEFAULT, NULL, hmenuMain, hModule,

        NULL);

    if (hwndMain == NULL)

        return FALSE;

    /* Set the initial focus. */

    SetFocus(hwndMain);

    return TRUE;

}

/* Main window procedure: Handle messages for the main window. */

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uiMessage,

        WPARAM wParam, LPARAM lParam) {

    static HWND hwndClient;

    static DWORD dwCount = 1;

    CLIENTCREATESTRUCT ccsClientCreate;

    HWND hwndChildWnd;

    DWORD IDThread;

    PTHREADLIST pNode;

    switch (uiMessage) {

       /* Create a client window to receive child window messages. */

       case WM_CREATE:

           ccsClientCreate.hWindowMenu = NULL;

           ccsClientCreate.idFirstChild = 1;

           hwndClient = CreateWindow("MDICLIENT", NULL,

               WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, 0, 0, 0, 0,

               hwnd, NULL, hModule, (LPVOID)&ccsClientCreate);

           return 0L;

       /*

        * Close the main window.  First set fKillAll to TRUE to

        * terminate all threads.  Then wait for the threads to exit

        * before passing a close message to a default handler.  If you

        * don't wait for threads to terminate, process terminates

        * with no chance for thread cleanup.

        */

       case WM_CLOSE:

           fKillAll = TRUE;

           pNode = pHead;

           while (pNode) {

               DWORD dwRes;

               SetThreadPriority(pNode->hThread,

                   THREAD_PRIORITY_HIGHEST);

               dwRes = WaitForSingleObject(pNode->hThread,

                   INFINITE);

               pNode = (PTHREADLIST) pNode->lpvNext;

           }

           return DefFrameProc(hwnd, hwndClient, uiMessage,

               wParam, lParam);

       /* Terminate the process. */

       case WM_DESTROY:

           PostQuitMessage(0);

           return 0L;

       /* Handle the menu commands. */

       case WM_COMMAND:

           switch (LOWORD(wParam)) {

           /* Create a child window and start a thread for it. */

             case MM_NEWWIN: {

               HANDLE hThrd;

               MDICREATESTRUCT mdicCreate;

               TCHAR tchTitleBarText[32];

               LONG lPrev;

               sprintf(tchTitleBarText, "Thread Window %d", dwCount);

               mdicCreate.szClass = "ThreadWindowClass";

               mdicCreate.szTitle = tchTitleBarText;

               mdicCreate.hOwner  = hModule;

               mdicCreate.x = mdicCreate.y =

               mdicCreate.cx = mdicCreate.cy = CW_USEDEFAULT;

               mdicCreate.style = mdicCreate.lParam = 0L;

               /* Send a "create child window" message to the client window. */

               hwndChildWnd = (HWND) SendMessage(hwndClient,

                   WM_MDICREATE, 0L, (LONG)&mdicCreate);

               if (hwndChildWnd == NULL)

                   ErrorExit("Failed in Creating Thread Window!");

               /* Window structure used to pass a quit message to the thread. */

               lPrev = SetWindowLong(hwndChildWnd, GWL_USERDATA, 0);

               /* Create suspended, alter priority before resuming. */

               hThrd = CreateThread(NULL,  /* no security attributes */

                         0,                /* use default stack size */

                         (LPTHREAD_START_ROUTINE) ThreadFunc,

                         (LPVOID)hwndChildWnd, /* parameter to thrd func */

                         CREATE_SUSPENDED, /* creation flag          */

                         &IDThread);       /* returns thread id      */

               if (hThrd == NULL)

                   ErrorExit("CreateThread Failed!");

               AddThreadToList(hThrd);

               dwCount++;

               /*

                * Set the priority lower than the primary (input) thread, so

                * that the process is responsive to user input.  Then resume

                * the thread.

                */

               if (! SetThreadPriority(hThrd,

                       THREAD_PRIORITY_BELOW_NORMAL))

                   ErrorExit("SetThreadPriority failed!");

               if ((ResumeThread(hThrd)) == -1)

                   ErrorExit("ResumeThread failed!");

               return 0L;

             }

             default:

               return DefFrameProc(hwnd, hwndClient, uiMessage,

                              wParam, lParam);

           }

       default:

           return DefFrameProc(hwnd, hwndClient, uiMessage,

                          wParam, lParam);

    }

}

/* Handle messages for the child windows. */

LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam) {

    LONG lPrevLong;

    switch (uiMessage) {

        /* Use a window structure to pass "close" message to the thread. */

        case WM_CLOSE:

            lPrevLong = SetWindowLong(hwnd, GWL_USERDATA, 1);

            return DefMDIChildProc(hwnd, uiMessage, wParam, lParam);

        case WM_DESTROY:

            return 0L;

        default:

            return DefMDIChildProc(hwnd, uiMessage, wParam, lParam);

    }

}

/*

 * Each child window has a thread that can be used to perform tasks

 * associated with that window--for example, drawing its contents.

 */

DWORD ThreadFunc(HWND hwnd) {

    LONG lKillMe = 0L;

    while (TRUE) {

        lKillMe = GetWindowLong(hwnd, GWL_USERDATA);

        if (fKillAll || lKillMe) break;

        /* Perform tasks. */

    }

        /* Perform actions needed before thread termination. */

    return 0;

}

VOID AddThreadToList(HANDLE hThread) {

    PTHREADLIST pNode;

    pNode = (PTHREADLIST) LocalAlloc(LPTR, sizeof(PTHREADLIST));

    if (pNode == NULL)

        ErrorExit("malloc Failed!");

    pNode->hThread = hThread;

    pNode->lpvNext = (LPVOID) pHead;

    pHead = pNode;

}

VOID ErrorExit(LPSTR lpszMessage) {

    MessageBox(hwndMain, lpszMessage, "Error", MB_OK);

    ExitProcess(0);

}


  43.2.2  Example: Child Process with Redirected Input and Output

The following example shows the creation of a child process by a console process and illustrates a technique for using anonymous pipes to redirect the child process's standard input and output. If you have a program that can read its input from STDIN or write its results to STDOUT, redirected I/O enables you to execute the program as a child process while controlling its input and receiving its output.

The example shows how to use a SECURITY_ATTRIBUTES structure to create handles that can be inherited by the child process. The structure is used in the CreatePipe function to create inheritable handles to the read and write ends of two pipes. The read end of one pipe serves as standard input for the child process, and the write end of the other pipe is the child's standard output. These pipe handles are specified in the SetStdHandle function, which makes them the standard handles inherited by the child process. After the child process is created, SetStdHandle is used again to restore the original standard handles for the parent process.

The parent process uses the other ends of the pipes to write to the child's input and read the child's output. The handles to these ends of the pipe are also inheritable. However, the handle must not be inherited. Before creating the child process, the parent process must use DuplicateHandle to create a non-inheritable duplicate of hChildStdinWr. It then uses CloseHandle to close the inheritable handle. This leaves the parent process with a pipe handle it can use, but which the child process does not inherit. For more information about pipes, see Chapter 54, »Pipes«.

Here's the parent process:

#include <stdio.h>

#include <windows.h>

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,

    hChildStdoutRd, hChildStdoutWr,

    hInputFile, hSaveStdin, hSaveStdout;

BOOL CreateChildProcess(VOID);

VOID WriteToPipe(VOID);

VOID ReadFromPipe(VOID);

VOID ErrorExit(LPTSTR);

VOID ErrMsg(LPTSTR, BOOL);

DWORD main(int argc, char *argv[]) {

    SECURITY_ATTRIBUTES saAttr;

    BOOL fSuccess;

    /* Set the bInheritHandle flag so pipe handles are inherited. */

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);

    saAttr.bInheritHandle = TRUE;

    saAttr.lpSecurityDescriptor = NULL;

    /*

     * The steps for redirecting child's STDOUT:

     *     1.  Save current STDOUT, to be restored later.

     *     2.  Create anonymous pipe to be STDOUT for child.

     *     3.  Set STDOUT of parent to be write handle of pipe, so

     *         it is inherited by child.

     */

    /* Save the handle to the current STDOUT. */

    hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    /* Create a pipe for the child's STDOUT. */

    if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))

        ErrorExit("Stdout pipe creation failed\n");

    /* Set a write handle to the pipe to be STDOUT. */

    if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))

        ErrorExit("Redirecting STDOUT failed");

    /*

     * The steps for redirecting child's STDIN:

     *     1.  Save current STDIN, to be restored later.

     *     2.  Create anonymous pipe to be STDIN for child.

     *     3.  Set STDIN of parent to be read handle of pipe, so

     *         it is inherited by child.

     *     4.  Create a noninheritable duplicate of write handle,

     *         and close the inheritable write handle.

     */

    /* Save the handle to the current STDIN. */

    hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

    /* Create a pipe for the child's STDIN. */

    if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))

        ErrorExit("Stdin pipe creation failed\n");

    /* Set a read handle to the pipe to be STDIN. */

    if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))

        ErrorExit("Redirecting Stdin failed");

    /*

     * Duplicate the write handle to the pipe, so it is not

     * inherited.

     */

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,

        GetCurrentProcess(), &hChildStdinWrDup, 0,

        FALSE,       /* not inherited */

        DUPLICATE_SAME_ACCESS);

    if (! fSuccess)

        ErrorExit("DuplicateHandle failed");

    CloseHandle(hChildStdinWr);

    /* Now create the child process. */

    if (! CreateChildProcess())

        ErrorExit("Create process failed");

    /* After process creation, restore the saved STDIN and STDOUT. */

    if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))

        ErrorExit("Re-redirecting Stdin failed\n");

    if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))

        ErrorExit("Re-redirecting Stdout failed\n");

    /* Get a handle to the parent's input file. */

    if (argc > 1)

        hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,

            OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);

    else

        hInputFile = hSaveStdin;

    if (hInputFile == INVALID_HANDLE_VALUE)

        ErrorExit("no input file\n");

    /*

     * Write to the pipe that is the standard input for a child

     * process.

     */

    WriteToPipe();

    /*

     * Read from the pipe that is the standard output for the child

     * process.

     */

    ReadFromPipe();

    return 0;

}

BOOL CreateChildProcess() {

    PROCESS_INFORMATION piProcInfo;

    STARTUPINFO siStartInfo;

    /* Set up members of STARTUPINFO structure. */

    siStartInfo.cb = sizeof(STARTUPINFO);

    siStartInfo.lpReserved = NULL;

    siStartInfo.lpReserved2 = NULL;

    siStartInfo.cbReserved2 = 0;

    siStartInfo.lpDesktop = NULL;

    siStartInfo.dwFlags = 0;

    /* Create the child process. */

    return CreateProcess(NULL,

        "child",       /* command line                       */

        NULL,          /* process security attributes        */

        NULL,          /* primary thread security attributes */

        TRUE,          /* handles are inherited              */

        0,             /* creation flags                     */

        NULL,          /* use parent's environment           */

        NULL,          /* use parent's current directory     */

        &siStartInfo,  /* STARTUPINFO pointer                */

        &piProcInfo);  /* receives PROCESS_INFORMATION       */

VOID WriteToPipe(VOID) {

    DWORD dwRead, dwWritten;

    CHAR chBuf[BUFSIZE];

    /* Read from a file and write its contents to a pipe. */

    for (;;) {

        if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||

            dwRead == 0) break;

        if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,

            &dwWritten, NULL)) break;

    }

    /* Close the pipe handle so the child stops reading. */

    if (! CloseHandle(hChildStdinWrDup))

        ErrorExit("Close pipe failed\n");

}

VOID ReadFromPipe(VOID) {

    DWORD dwRead, dwWritten;

    CHAR chBuf[BUFSIZE];

    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    /*

     * Close the write end of the pipe before reading from the read end

     * of the pipe.

     */

    if (! CloseHandle(hChildStdoutWr))

        ErrorExit("Closing handle failed");

    /*

     * Read output from the child, and write it to the parent's STDOUT.

     */

    for (;;) {

        if (! ReadFile(hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) ||

            dwRead == 0) break;

        if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))

            break;

    }

}

VOID ErrorExit (LPTSTR lpszMessage) {

    fprintf(stderr, "%s\n", lpszMessage);

    ExitProcess(0);

}

Here's the child process:

#include <windows.h>

#define BUFSIZE 4096

VOID main(VOID) {

    CHAR chBuf[BUFSIZE];

    DWORD dwRead, dwWritten;

    HANDLE hStdin, hStdout;

    BOOL fSuccess;

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    hStdin = GetStdHandle(STD_INPUT_HANDLE);

    if ((hStdout == INVALID_HANDLE_VALUE) ||

        (hStdin == INVALID_HANDLE_VALUE))

        ExitProcess(1);

    for (;;) {

      /* Read from standard input. */

      fSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);

      if (! fSuccess || dwRead == 0)

          break;

      /* Write to standard output. */

      fSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);

      if (! fSuccess)

          break;

    }

}


  43.2.3  Changing Environment Variables

The environment block consists of a null-terminated block of null-terminated strings (that is, two null bytes at the end of the block), where each string is in the form: NAME=value. Because the equal sign is a separator, it must not be used in the name of an environment variable. The following example creates a new environment block to pass to a child process:

TCHAR tchNewEnv[BUFSIZE];

LPTSTR lpszCurrentVariable;

BOOL fSuccess;

/*

 * Copy name=value environment variable pairs into the environment

 * block.

 */

lpszCurrentVariable = tchNewEnv;

if (lstrcpy(lpszCurrentVariable, "OperatingSystem=Windows NT") == NULL)

    ErrorExit("lstrcpy failed");

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;

if (lstrcpy(lpszCurrentVariable, "API=Win32") == NULL)

    ErrorExit("lstrcpy failed");

/* Terminate the block with a NULL byte. */

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;

*lpszCurrentVariable = '\0';

/* Create the child process, specifying a new environment block. */

fSuccess = CreateProcess(NULL, "childenv", NULL, NULL, TRUE, 0,

    (LPVOID) tchNewEnv,     /* new environment block */

    NULL, &siStartInfo, &piProcInfo);

if (! fSuccess)

    ErrorExit("CreateProcess failed");

If you want the child process to inherit most of the parent's environment with only a few changes, save the current values, make changes for the child to inherit, and then restore the saved values for example:

LPTSTR lpszOldValue;

TCHAR tchBuf[BUFSIZE];

BOOL fSuccess;

/*

 * lpszOldValue gets current value of "varname", or NULL if "varname"

 * environment variable does not exist. Set "varname" to new value,

 * create child process, then use SetEnvironmentVariable to restore

 * original value of "varname". If lpszOldValue is NULL, the "varname"

 * variable will be deleted.

 */

lpszOldValue = ((GetEnvironmentVariable("varname", tchBuf, BUFSIZE) > 0) ?

    tchBuf : NULL);

/* Set a value for the child to inherit. */

if (! SetEnvironmentVariable("varname", "newvalue"))

    ErrorExit("SetEnvironmentVariable failed");

/* Create a child process. */

fSuccess = CreateProcess(NULL, "childenv", NULL, NULL, TRUE, 0,

    NULL,     /* inherit parent's environment */

    NULL, &siStartInfo, &piProcInfo);

if (! fSuccess)

    ErrorExit("CreateProcess failed");

/* Restore the parent's environment. */

if (! SetEnvironmentVariable("varname", lpszOldValue))

    ErrorExit("SetEnvironmentVariable failed");

The following example, taken from a console process, prints the contents of the process's environment block.

LPTSTR lpszVariable;

LPVOID lpvEnv;

/* Get a pointer to the environment block. */

lpvEnv = GetEnvironmentStrings();

/*

 * Variable strings are separated by NULL byte, and the block is

 * terminated by a NULL byte.

 */

for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++) {

    while (*lpszVariable)

        putchar(*lpszVariable++);

    putchar('\n');

}


  43.2.4  Using Thread Local Storage

Thread local storage (TLS) enables multiple threads of the same process to use an index allocated by TlsAlloc to store and retrieve a value that is local to the thread. In this example, an index is allocated when the process starts. When each thread starts, it allocates a block of dynamic memory and stores a pointer to this memory by using the TLS index. The TLS index is used by the CommonFunc function to access the data local to the calling thread. Before each thread terminates, it releases its dynamic memory.

#include <stdio.h>

#include <windows.h>

#define THREADCOUNT 4

DWORD dwTlsIndex;

VOID ErrorExit(LPTSTR);

VOID CommonFunc(VOID) {

  LPVOID lpvData;

    /* Retrieve a data pointer for the current thread. */

    lpvData = TlsGetValue(dwTlsIndex);

    if ((lpvData == 0) && (GetLastError() != 0))

        ErrorExit("TlsGetValue error");

    /* Use the data stored for the current thread. */

    printf("common: thread %d: lpvData=%lx\n",

        GetCurrentThreadId(), lpvData);

    Sleep(5000);

}

DWORD ThreadFunc(VOID) {

    LPVOID lpvData;

    /* Initialize the TLS index for this thread. */

    lpvData = (LPVOID) LocalAlloc(LPTR, 256);

    if (! TlsSetValue(dwTlsIndex, lpvData))

        ErrorExit("TlsSetValue error");

    printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData);

    CommonFunc();

    /* Release the dynamic memory before the thread returns. */

    lpvData = TlsGetValue(dwTlsIndex);

    if (lpvData != 0)

        LocalFree((HLOCAL) lpvData);

    return 0;

}

DWORD main(VOID) {

    DWORD IDThread;

    HANDLE hThread[THREADCOUNT];

    int i;

    /* Allocate a TLS index. */

    if ((dwTlsIndex = TlsAlloc()) == 0xFFFFFFFF)

        ErrorExit("TlsAlloc failed");

    /* Create multiple threads. */

    for (i = 0; i < THREADCOUNT; i++) {

        hThread[i] = CreateThread(NULL,/* no security attributes    */

            0,                       /* use default stack size      */

            (LPTHREAD_START_ROUTINE) ThreadFunc, /* thread function */

            NULL,                    /* no thread function argument */

            0,                       /* use default creation flags  */

            &IDThread);              /* returns thread identifier   */

        /* Check the return value for success. */

        if (hThread[i] == NULL)

            ErrorExit("CreateThread error\n");

    }

    for (i = 0; i < THREADCOUNT; i++)

        WaitForSingleObject(hThread[i], INFINITE);

    return 0;

}

VOID ErrorExit (LPTSTR lpszMessage) {

    fprintf(stderr, "%s\n", lpszMessage);

    ExitProcess(0);

}


  43.3  Functions

Following are the functions used with processes.

AttachThreadInput
CreateProcess
CreateRemoteThread
CreateThread
DuplicateHandle
ExitProcess
ExitThread
GetCommandLine
GetCurrentProcess
GetCurrentProcessId
GetCurrentThread
GetCurrentThreadId
GetEnvironmentStrings
GetEnvironmentVariable
GetExitCodeProcess
GetExitCodeThread
GetPriorityClass
GetProcessShutdownParameters
GetProcessTimes
GetStartupInfo
GetThreadPriority
GetThreadTimes
LoadModule (obsolete)
OpenProcess
ResumeThread
SetEnvironmentVariable
SetPriorityClass
SetProcessShutdownParameters
SetThreadPriority
Sleep
SleepEx
SuspendThread
TerminateProcess
TerminateThread
TlsAlloc
TlsFree
TlsGetValue
TlsSetValue
WaitForInputIdle
WinExec (obsolete)
Yield (obsolete)


Synchronization
  Chapter 44    Synchronization

44.1  About Synchronization

The Microsoft Win32 application programming interface (API) provides a variety of ways to coordinate multiple threads of execution. This chapter describes the use of the following synchronization mechanisms:

•	Wait functions and synchronization objects

•	Overlapped input and output (I/O) operations

•	Critical section objects

•	Interlocked variable access


  44.1.1  Wait Functions

The Win32 API provides a set of wait functions that enable a thread to block its own execution. These functions do not return until a set of conditions specified by the wait function's parameters have been satisfied. These parameters include a time-out interval and handles of one or more synchronization objects. For more information about synchronization objects, see Section 44.1.2, »Synchronization Objects«.

When a wait function is called, it checks the state of the specified synchronization object or objects and any other conditions that could cause it to return. If this initial state does not satisfy the specified conditions and the time-out interval has not elapsed, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the conditions to be satisfied. The time-out interval can be set to INFINITE to cause an indefinite wait.

The WaitForSingleObject and WaitForSingleObjectEx functions require a handle of one synchronization object. These functions return when the state of the object is signaled, or when the time-out interval elapses. (The state of a synchronization object is either signaled or nonsignaled.)

The WaitForMultipleObjects, WaitForMultipleObjectsEx, and MsgWaitForMultipleObjects functions enable the calling thread to specify an array containing one or more synchronization object handles. These functions can be set to return when the state of any one of the specified objects is signaled, in which case the return value indicates the array index of the object that caused the function to return. Alternatively, the functions can be set to return only when the state of all objects is signaled at the same time, in which case the return value simply indicates that the specified conditions were satisfied.

When waiting for all objects to be signaled, these multiple-object functions do not modify the state of the specified objects until all objects are signaled simultaneously. For example, a mutex can be signaled, but the calling thread does not get ownership of it until the other objects are also signaled. In the meantime, some other thread may get ownership of the mutex, thereby delaying satisfaction of all specified conditions.

The WaitForSingleObjectEx and WaitForMultipleObjectsEx functions differ from the other wait functions in that they can optionally perform an alertable wait. In an alertable wait, the function can return when the specified conditions are satisfied, but it can also return if the system queues a completion routine for execution by the waiting thread. For more information about alertable waits and input and output (I/O) completion routines, see Section 44.1.5, »Synchronization and Overlapped Input and Output«.

The MsgWaitForMultipleObjects function is identical to WaitForMultipleObjects, except that it can also return when a specified type of input is available in the calling thread's input queue. For example, a thread could use MsgWaitForMultipleObjects to block its execution until either the state of a specified object is signaled, or there is mouse input available in the thread's input queue. When input is available, the thread can use the GetMessage or PeekMessage function to retrieve it.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. A wait function can modify the state of synchronization objects as follows:

•	The count of a semaphore object decreases by one, with the semaphore's state changing to nonsignaled if its count is zero.

•	The state of mutex, auto-reset event, and change notification objects changes to nonsignaled.

•	The state of manual-reset event, process, thread, and console input objects is not affected by a wait function.


  44.1.2  Synchronization Objects

A synchronization object is an object whose handle can be specified in one of the wait functions to coordinate the execution of multiple threads. The state of a synchronization object is either signaled, which can allow the wait function to return, or nonsignaled, which can prevent the function from returning. More than one process can have a handle of the same synchronization object, making interprocess synchronization possible.

The Win32 API provides the following three object types intended exclusively for synchronization.

Type	Description
event	Notifies one or more waiting threads that an event has occurred.
mutex	Can be owned by only one thread at a time, enabling threads to coordinate mutually exclusive access to a shared resource.
semaphore	Maintains a count between zero and some maximum value, limiting the number of threads that are simultaneously accessing a shared resource.
Though available for other uses, the following objects can also be used for synchronization.

Object	Description
change notification	Created by the FindFirstChangeNotification function, its state is signaled when a specified type of change occurs within a specified directory or directory tree. For more information, see Chapter 45, »Files«.
console input	Created when a console is created, when a handle to console input is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. Its state is signaled when there is unread input in the console's input buffer, and nonsignaled when the input buffer is empty. For more information, see Chapter 57, »Consoles and Character-Mode Support«.
process	Created when a new process is created by calling the CreateProcess function, its state is nonsignaled while the process is running, and signaled when the process terminates. For more information, see Chapter 43, »Processes and Threads«.
thread	Created when a new thread is created by calling the CreateProcess, CreateThread, or CreateRemoteThread function, its state is nonsignaled while the thread is running, and signaled when the thread terminates. For more information, see Chapter 43, »Processes and Threads«.
In some circumstances you can also use a file, named pipe, or communications device as a synchronization object; however, their use for this purpose is discouraged. For additional information, see Section 44.1.5, »Synchronization and Overlapped Input and Output«.


  44.1.3  Mutex Objects

A mutex object is a synchronization object whose state is signaled when it is not owned by any thread, and nonsignaled when it is owned. Only one thread at a time can own a mutex, whose name comes from the fact that it is useful in coordinating mutually exclusive access to a shared resource. For example, to prevent two threads from writing to shared memory at the same time, each thread waits for ownership of a mutex before executing the code that accesses the memory. After writing to the shared memory, the thread releases the mutex.

A thread uses the CreateMutex function to create a mutex object. The creating thread can request immediate ownership of the mutex and can also specify a name for the mutex object. Threads in other processes can open a handle of an existing mutex object by specifying its name in a call to the OpenMutex function. For additional information about names for mutex, event, and semaphore objects, see Section 44.1.4, »Interprocess Synchronization«.

Any thread with a handle of a mutex object can use one of the wait functions to request ownership of the mutex. If the mutex is owned by another thread, the wait function blocks the execution of the requesting thread until the owning thread releases the mutex using the ReleaseMutex function. The return value of the wait function indicates whether the function returned for some reason other than the state of the mutex being signaled.

Once a thread owns a mutex, it can specify the same mutex in repeated wait-function calls without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. To release its ownership under such circumstances, the thread must call ReleaseMutex once for each time that the mutex satisfied the conditions of a wait function.

If a thread terminates without releasing its ownership of a mutex object, the mutex is considered to be abandoned. A waiting thread can acquire ownership of an abandoned mutex, but the wait function's return value indicates that the mutex is abandoned. It is best to assume that an abandoned mutex indicates that an error has occurred and that any shared resource being protected by the mutex is in an undefined state. If the thread proceeds normally, as though the mutex had not been abandoned, the mutex's abandoned flag is cleared when the thread releases its ownership. This restores normal mutex behavior if the mutex is subsequently specified in a wait function.


  44.1.3.1  Semaphore Objects

A semaphore object is a synchronization object that maintains a count between zero and a specified maximum value. A semaphore's state is signaled when its count is greater than zero, and nonsignaled when its count is zero.

The semaphore object is useful in controlling a shared resource that can support a limited number of users. It acts like a gate that counts the threads as they enter and exit a controlled area and limits the number of threads sharing the resource to a specified maximum number. For example, an application might want to place a limit on the number of windows that it creates. It uses a semaphore with a maximum count equal to the window limit, decrementing the count whenever a window is created and incrementing it whenever a window is closed. The application specifies the semaphore object in a wait function before each window is created. When the count is zero — indicating that the window limit has been reached — the wait function blocks execution of the window-creation code.

A thread uses the CreateSemaphore function to create a semaphore object. The creating thread specifies the initial count and the maximum count of the object. The initial count must be neither less than zero nor greater than the maximum count. The creating thread can also specify a name for the semaphore object. Threads in other processes can open a handle of an existing semaphore object by specifying its name in a call to the OpenSemaphore function. For additional information about names for mutex, event, and semaphore objects, see Section 44.1.4, »Interprocess Synchronization«.

Each time that a wait function returns because of a semaphore's signaled state, the count of the semaphore is decreased by one. The ReleaseSemaphore function increases a semaphore's count by a specified amount. The count can never be less than zero or greater than the maximum count.

The initial count of a semaphore is typically set to the maximum value. The count is then decremented from that level as the protected resource is consumed. Alternatively, a semaphore can be created with an initial count of zero to block access to the protected resource while the application is being initialized. After initialization, you would use ReleaseSemaphore to increment the count to the maximum.

Threads do not acquire ownership of semaphore objects as they do with mutex objects. A thread that owns a mutex can wait repeatedly for the same mutex object without its execution becoming blocked. A thread that waits repeatedly for the same semaphore object, however, decrements the semaphore's count each time a wait is satisfied; its execution is blocked when the count gets to zero. Similarly, only the thread that owns a mutex can successfully call the ReleaseMutex function, though any thread can use ReleaseSemaphore to increase the count of a semaphore object, even if the thread never used a wait function to decrement the count.

A thread can decrement a semaphore's count more than once by repeatedly specifying the same semaphore object in calls to any of the wait functions. However, calling the WaitForMultipleObjects function with an array that contains multiple handles of the same semaphore does not perform multiple decrements.


  44.1.3.2  Event Objects

An event object is a synchronization object whose state can be set to signaled explicitly by use of the SetEvent or PulseEvent function. Following are the two types of event object.

Object	Description
manual-reset event	An event object whose state remains signaled until it is explicitly reset to nonsignaled by the ResetEvent function. While it is signaled, any number of waiting threads, or threads that subsequently specify the same event object in one of the wait functions, can be released.
auto-reset event	An event object whose state remains signaled until a single waiting thread is released, at which time the system automatically sets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.
The event object is useful in signaling a thread that a particular event has occurred. For example, in overlapped input and output, the system sets a specified event object to the signaled state when the overlapped operation has been completed. A single thread can specify different event objects in several simultaneous overlapped operations, then use the WaitForMultipleObjects function to wait for the state of any one of the event objects to be signaled.

A thread uses the CreateEvent function to create an event object. The creating thread specifies the initial state of the object and whether it is a manual-reset or auto-reset event object. The creating thread can also specify a name for the event object. Threads in other processes can open a handle of an existing event object by specifying its name in a call to the OpenEvent function. For additional information about names for mutex, event, and semaphore objects, see Section 44.1.4, »Interprocess Synchronization«.

A thread can use the PulseEvent function to set an event object's state to signaled and then reset it to nonsignaled after releasing the appropriate number of waiting threads. For a manual-reset event object, all waiting threads that can be released immediately are released. For an auto-reset event object, the function releases only a single waiting thread, even if multiple threads are waiting. If no threads are waiting, or if no thread can be released immediately, PulseEvent simply sets the event object's state to nonsignaled and returns.


  44.1.4  Interprocess Synchronization

Multiple processes can have handles of the same mutex, semaphore, or event object, so these objects can be used to accomplish interprocess synchronization. The process that creates an object can use the handle returned by the creation function (CreateEvent, CreateMutex, or CreateSemaphore). Other processes can open a handle of the object by using its name, or through inheritance or duplication.


  44.1.4.1  Object Names

Named objects provide an easy way for processes to share object handles. The name specified by the creating process is limited to MAX_PATH characters, and can include any character except the backslash path-separator character (\). Once a process has created a named event, mutex, or semaphore object, other processes can use the name to call the appropriate function (OpenEvent, OpenMutex, or OpenSemaphore) to open a handle of the object. Name comparison is case sensitive. The names of event, semaphore, mutex, and file-mapping objects share the same name space, so an error occurs if a specified name matches the name of an existing object of a different type. When creating named objects, therefore, use unique names and be sure to check function return values for duplicate-name errors.

If the name specified in a call to the CreateMutex function matches the name of an existing mutex object, the function returns a handle of the existing object. In this case, the call to CreateMutex is equivalent to a call to the OpenMutex function. (The CreateEvent and CreateSemaphore functions work the same way with existing named event and semaphore objects, respectively.) Having multiple processes use CreateMutex for the same mutex is therefore equivalent to having one process that calls CreateMutex while the other processes call OpenMutex, except that it eliminates the need to ensure that the creating process is started first. When using this technique for mutex objects, however, none of the calling processes should request immediate ownership of the mutex. If multiple processes do request immediate ownership, it can be difficult to predict which process actually gets the initial ownership.


  44.1.4.2  Object Inheritance

A child process created by the CreateProcess function can inherit a handle of a mutex, event, or semaphore if the SECURITY_ATTRIBUTES structure — specified when the object was created — enabled inheritance. The handle inherited by the child process has the same access to the object as the parent's handle. The inherited handle appears in the handle table of the child process, but for the child process to be able to use the handle, the parent process must communicate the handle's value to the child process. The parent can do this by specifying the value as a command-line argument when it calls the CreateProcess function. The child process can then use the GetCommandLine function to retrieve the command-line string and convert the handle argument into a usable handle. For more information about object inheritance, see Chapter 43, »Processes and Threads«.


  44.1.4.3  Object Duplication

The DuplicateHandle function creates a duplicate handle that can be used by another specified process. This method of sharing object handles is more complex than using named objects or inheritance. It requires communication between the creating process and the process into which the handle is duplicated. The necessary information (the handle value and process identifier) can be communicated by any of the interprocess communication methods (for example, named pipe, shared file, shared memory). For more information about object duplication, see Chapter 43, »Processes and Threads«.


  44.1.5  Synchronization and Overlapped Input and Output

The Win32 API supports both synchronous and asynchronous (or overlapped) I/O operations on files, named pipes, and serial communications devices. The WriteFile, ReadFile, DeviceIoControl, WaitCommEvent, ConnectNamedPipe, and TransactNamedPipe functions can be performed either synchronously or asynchronously. The ReadFileEx and WriteFileEx functions can be performed asynchronously only.

When a function is executed synchronously, it does not return until the operation has been completed. This means that the execution of the calling thread can be blocked for an indefinite period while it waits for a time-consuming operation to finish. Functions called for overlapped operation can return immediately, even though the operation has not been completed. This enables a time-consuming I/O operation to be executed in the background while the calling thread is free to perform other tasks. For example, a single thread can perform simultaneous I/O operations on different handles, or even simultaneous read and write operations on the same handle. To synchronize its execution with the completion of the overlapped operation, the calling thread uses the GetOverlappedResult function or one of the wait functions to determine when the operation has been completed.

Overlapped operations require a file, named pipe, or communications device that was created with the FILE_FLAG_OVERLAPPED flag. To call a function as an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure. If this pointer is NULL, the operation is performed synchronously, even though the handle was created with FILE_FLAG_OVERLAPPED enabled. The OVERLAPPED structure must contain a handle to a manual-reset — not an auto-reset — event object. The system sets the state of the event object to nonsignaled when a call to the I/O function returns before the operation has been completed. The system sets the state of the event object to signaled when the operation has been completed.

When a function is called as an overlapped operation, the operation may have been completed before the function returns. When this happens, the results are handled as if the operation had been performed synchronously. If the operation has not yet been completed, however, the function's return value is FALSE, and the GetLastError function returns ERROR_IO_PENDING.

A thread can manage overlapped operations by either of two methods. It can use the GetOverlappedResult function to wait for the overlapped operation to be completed. Alternatively, it can specify a handle of the OVERLAPPED structure's manual-reset event object in one of the wait functions and then call GetOverlappedResult after the wait function returns. GetOverlappedResult returns the results of the completed overlapped operation, and for functions in which such information is appropriate, it reports the actual number of bytes that were transferred.

When performing multiple simultaneous overlapped operations, the calling thread must specify a separate OVERLAPPED structure with its own manual-reset event object for each operation. The thread can then specify handles of the different event objects in the handle-array parameter of the WaitForMultipleObjects function (or one of the other multiple-object wait functions) to wait for any one of the overlapped operations to be completed. The return value of the multiple-object wait function indicates which event object was signaled, so the thread can determine which operation was completed.

If no event object is specified in the OVERLAPPED structure, the system signals the state of the file, named pipe, or communications device when the overlapped operation has been completed. Thus, you can specify these handles as synchronization objects in a wait function, though their use for this purpose can be difficult to manage. When performing simultaneous overlapped operations on the same file, named pipe, or communications device, there is no way to know which operation caused the object's state to be signaled. It is safer to use a separate event object for each overlapped operation.

For examples that illustrate the use of overlapped operations, completion routines, and the GetOverlappedResult function, see Chapter 54, »Pipes«.


  44.1.6  Critical Section Objects

Critical section objects provide synchronization similar to that provided by mutex objects, except that critical section objects can be used only by the threads of a single process. Event, mutex, and semaphore objects can also be used in a single-process application, but critical section objects provide a slightly faster, more efficient mechanism for mutual-exclusion synchronization. Like a mutex object, a critical section object can be owned by only one thread at a time, which makes it useful for protecting a shared resource from simultaneous access. For example, a process could use a critical section object to prevent more than one thread at a time from modifying a global data structure.

The process is responsible for allocating the memory used by a critical section object. Typically, this is done by simply declaring a variable of type CRITICAL_SECTION. Before the threads of the process can use it, the critical section object must be initialized by using the InitializeCriticalSection function.

A thread uses the EnterCriticalSection function to request ownership and the LeaveCriticalSection function to release its ownership. If the critical section object is currently owned by another thread, EnterCriticalSection waits indefinitely for ownership. This differs from the use of a mutex object for mutual exclusion, where the wait functions accept a specified time-out interval.

Once a thread owns a critical section object, it can make additional calls to EnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section object that it already owns. To release its ownership, the thread must call LeaveCriticalSection once for each time that it entered the critical section.

Any thread of the process can use the DeleteCriticalSection function to release the system resources that were allocated when the critical section object was initialized. After this function has been called, the critical section object can no longer be used for synchronization.

When a critical section object is owned, the only other threads affected are those that are waiting for ownership in a call to EnterCriticalSection. Threads that are not waiting are free to continue their normal execution.


  44.1.7  Interlocked Variable Access

The InterlockedIncrement and InterlockedDecrement functions provide a simple mechanism for synchronizing access to a specified 32-bit variable that is shared by multiple threads in the same or in different processes. These functions combine the operations of incrementing or decrementing the variable and checking the resulting value. This is useful in a multitasking operating system, in which the system can interrupt one thread's execution to grant a slice of processor time to another thread. Without such synchronization, one thread could increment a variable but be interrupted by the system before it can check the resulting value of the variable. A second thread could then increment the same variable. When the first thread receives its next timeslice, it will check the value of the variable, which has now been incremented not once but twice. The interlocked variable-access functions protect against this kind of error.

The threads of different processes can use this mechanism if the variable is in shared memory.


  44.2  Using Synchronization

The examples in this section illustrate the following techniques:

•	Using named objects for interprocess object sharing

•	Waiting for multiple objects

•	Using mutex objects

•	Using semaphore objects

•	Using event objects

•	Using critical section objects


  44.2.1  Using Named Objects

This example illustrates the use of an object name to let two processes open handles of the same mutex object.

The first process uses the CreateMutex function to create the mutex object. Note that the function succeeds even if there is an existing object with the same name.

/* One process creates the mutex object. */

HANDLE hMutex;

DWORD dwErr;

hMutex = CreateMutex(

    NULL,                  /* no security descriptor */

    FALSE,                 /* mutex not owned        */

    "NameOfMutexObject");  /* object name            */

if (hMutex == NULL)

    printf("CreateMutex error: %d\n", GetLastError() );

else

    if ( GetLastError() == ERROR_ALREADY_EXISTS )

        printf("CreateMutex opened existing mutex\n");

    else

        printf("CreateMutex created new mutex\n");

The second process uses the OpenMutex function to open a handle of the existing mutex. This function fails if a mutex object with the specified name does not exist. The access parameter requests full access to the mutex object, which is necessary for the handle to be used in any of the wait functions.

/* Another process opens a handle of the existing mutex. */

HANDLE hMutex;

hMutex = OpenMutex(

    MUTEX_ALL_ACCESS,      /* request full access    */

    FALSE,                 /* handle not inheritable */

    "NameOfMutexObject");  /* object name            */

if (hMutex == NULL)

    printf("OpenMutex error: %d\n", GetLastError() );

The following example uses the CreateSemaphore function to illustrate a named-object creation operation that fails if the object already exists.

HANDLE CreateNewSemaphore(LPSECURITY_ATTRIBUTES lpsa,

    LONG cInitial, LONG cMax, LPTSTR lpszName) {

HANDLE hSem;

/* Create or open a named semaphore. */

hSem = CreateSemaphore(

    lpsa,         /* security attributes */

    cInitial,     /* initial count       */

    cMax,         /* maximum count       */

    lpszName);    /* semaphore name      */

/* Close handle, and return NULL if existing semaphore opened. */

if (hSem != NULL &&

        GetLastError() == ERROR_ALREADY_EXISTS) {

    CloseHandle(hSem);

    return NULL;

}

/* If new semaphore was created, return the handle. */

return hSem;

}


  44.2.2  Waiting for Multiple Objects

This example uses the CreateEvent function to create two event objects. It then uses the WaitForMultipleObjects function to wait for one of them to be signaled.

HANDLE hEvents[2];

DWORD i, dwEvent;

/* Create two event objects. */

for (i = 0; i < 2; i++) {

    hEvents[i] = CreateEvent(

        NULL,   /* no security attributes        */

        FALSE,  /* auto-reset event object       */

        FALSE,  /* initial state is nonsignaled  */

        NULL);  /* unnamed object                */

    if (hEvents[i] == NULL) {

        printf("CreateEvent error: %d\n", GetLastError() );

        ExitProcess(0);

    }

}

/*

 * The creating thread waits for other threads or processes

 * to signal the event objects.

 */

dwEvent = WaitForMultipleObjects(

    2,           /* number of objects in array */

    hEvents,     /* array of objects           */

    FALSE,       /* wait for any               */

    INFINITE);   /* indefinite wait            */

/* Return value indicates which event is signaled. */

switch (dwEvent) {

    /* hEvent[0] was signaled. */

    case WAIT_OBJECT_0 + 0:

        /* Perform tasks required by this event. */

        break;

    /* hEvent[1] was signaled. */

    case WAIT_OBJECT_0 + 1:

        /* Perform tasks required by this event. */

        break;

    /* Return value is invalid. */

    default:

        printf("Wait error: %d\n", GetLastError());

        ExitProcess(0);

}


  44.2.3  Using Mutex Objects

You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes. Each thread must wait for ownership of the mutex before it can execute the code that accesses the shared resource. For example, if several threads share access to a database, the threads can use a mutex object to permit only one thread at a time to write to the database.

In the following example, a process uses the CreateMutex function to create a named mutex object or open a handle of an existing mutex object.

HANDLE hMutex;

/* Create a mutex with no initial owner. */

hMutex = CreateMutex(

    NULL,                       /* no security attributes */

    FALSE,                      /* initially not owned      */

    "MutexToProtectDatabase");  /* name of mutex          */

if (hMutex == NULL) {

    /* check for error */

}

When a thread of this process writes to the database, as in the next example, it first requests ownership of the mutex. If it gets ownership, the thread writes to the database and then releases its ownership.

The example uses the try-finally structured exception handling syntax to ensure that the thread properly releases the mutex. The finally block of code is executed no matter how the try block terminates (unless the try block includes a call to the TerminateThread function). This prevents the mutex from being abandoned inadvertently.

BOOL FunctionToWriteToDatabase(HANDLE hMutex) {

DWORD dwWaitResult;

/* Request ownership of mutex. */

dwWaitResult = WaitForSingleObject(

        hMutex,   /* handle of mutex           */

        5000L);   /* five-second time-out interval */

switch (dwWaitResult) {

    /* The thread got mutex ownership. */

    case WAIT_OBJECT_0:

        try {

            .

            . /* Write to the database. */

            .

        }

        finally {

            /* Release ownership of the mutex object. */

            if (! ReleaseMutex(hMutex)) {

                /* Deal with error. */

            }

            break;

        }

    /* Cannot get mutex ownership due to time-out. */

    case WAIT_TIMEOUT:

        return FALSE;

    /* Got ownership of the abandoned mutex object. */

    case WAIT_ABANDONED:

        return FALSE;

}

return TRUE;

}


  44.2.4  Using Semaphore Objects

In the following example, a process uses a semaphore object to limit the number of windows it creates. First, it uses the CreateSemaphore function to create the semaphore and to specify initial and maximum counts.

HANDLE hSemaphore;

LONG cMax = 10;

LONG cPreviousCount;

/* Create a semaphore with initial and max. counts of 10. */

hSemaphore = CreateSemaphore(

    NULL,   /* no security attributes */

    cMax,   /* initial count          */

    cMax,   /* maximum count          */

    NULL);  /* unnamed semaphore      */

if (hSemaphore == NULL) {

    /* Check for error. */

}

Before any thread of the process creates a new window, it uses the WaitForSingleObject function to determine whether the semaphore's current count permits the creation of additional windows. The wait function's time-out parameter is set to zero, so the function returns immediately if the semaphore is nonsignaled.

DWORD dwWaitResult;

/* Try to enter the semaphore gate. */

dwWaitResult = WaitForSingleObject(

        hSemaphore,   /* handle of semaphore          */

        0L);          /* zero-second time-out interval */

switch (dwWaitResult) {

    /* The semaphore object was signaled. */

    case WAIT_OBJECT_0:

        .

        . /* OK to open another window. */

        .

        break;

    /* Semaphore was nonsignaled, so a time-out occurred. */

    case WAIT_TIMEOUT:

        .

        . /* Cannot open another window. */

        .

        break;

}

When a thread closes a window, it uses the ReleaseSemaphore function to increment the semaphore's count.

/* Increment the count of the semaphore. */

if (! ReleaseSemaphore(

        hSemaphore,  /* handle of semaphore              */

        1,           /* increase count by one            */

        NULL) ) {    /* not interested in previous count */

    /* Deal with the error. */

}


  44.2.5  Using Event Objects

The Win32 API uses event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped input and output (I/O) operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Section 44.1.5, »Synchronization and Overlapped Input and Output«.

In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer.

#define NUMTHREADS 4

HANDLE hGlobalWriteEvent;

void CreateEventsAndThreads(void) {

HANDLE hReadEvents[NUMTHREADS], hThread;

DWORD i, IDThread;

/*

 * Create a manual-reset event object. The master thread sets

 * this to nonsignaled when it writes to the shared buffer.

 */

hGlobalWriteEvent = CreateEvent(

    NULL,        /* no security attributes    */

    TRUE,        /* manual-reset event        */

    TRUE,        /* initial state is signaled */

    "WriteEvent" /* object name               */

    );

if (hGlobalWriteEvent == NULL) {

    /* error exit */

}

/*

 * Create multiple threads and an auto-reset event object

 * for each thread. Each thread sets its event object to

 * signaled when it is not reading from the shared buffer.

 */

for(i = 1; i <= NUMTHREADS; i++) {

    /* Create the auto-reset event. */

    hReadEvents[i] = CreateEvent(

        NULL,     /* no security attributes    */

        FALSE,    /* auto-reset event          */

        TRUE,     /* initial state is signaled */

        NULL);    /* object not named          */

    if (hReadEvents[i] == NULL) {

        /* error exit */

    }

    hThread = CreateThread(NULL, 0,

            (LPTHREAD_START_ROUTINE) ThreadFunction,

            &hReadEvents[i], /* pass event handle  */

            0, &IDThread);

    if (hThread == NULL) {

        /* error exit */

    }

}

}

Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent and all the reader-thread events to signaled, enabling the reader threads to resume their read operations.

VOID WriteToBuffer(VOID) {

DWORD dwWaitResult, i;

/* Reset hGlobalWriteEvent to nonsignaled, to block readers. */

if (! ResetEvent(hGlobalWriteEvent) ) {

        /* error exit */

}

/* Wait for all reading threads to finish reading. */

dwWaitResult = WaitForMultipleObjects(

        NUMTHREADS,   /* number of handles in array   */

        hReadEvents,  /* array of read-event handles  */

        TRUE,         /* wait until all are signaled  */

        INFINITE);    /* indefinite wait              */

switch (dwWaitResult) {

    /* All read-event objects were signaled. */

    case WAIT_OBJECT_0:

        .

        . /* Write to the shared buffer. */

        .

        break;

    /* An error occurred. */

    default:

        printf("Wait error: %d\n", GetLastError());

        ExitProcess(0);

}

/* Set hGlobalWriteEvent to signaled. */

if (! SetEvent(hGlobalWriteEvent) ) {

        /* error exit */

}

/* Set all read events to signaled. */

for(i = 1; i <= NUMTHREADS; i++)

    if (! SetEvent(hReadEvents[i]) ) {

            /* error exit */

    }

}

Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for hGlobalWriteEvent and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled.

VOID ThreadFunction(LPVOID lpParam) {

DWORD dwWaitResult, i;

HANDLE hEvents[2];

hEvents[0] = (HANDLE) *lpParam;  /* thread's read event */

hEvents[1] = hGlobalWriteEvent;

dwWaitResult = WaitForMultipleObjects(

        2,            /* number of handles in array   */

        hEvents,      /* array of event handles       */

        TRUE,         /* wait till all are signaled   */

        INFINITE);    /* indefinite wait              */

switch (dwWaitResult) {

    /* Both event objects were signaled. */

    case WAIT_OBJECT_0:

        .

        . /* Read from the shared buffer. */

        .

        break;

    /* An error occurred. */

    default:

        printf("Wait error: %d\n", GetLastError());

        ExitThread(0);

}

/* Set the read event to signaled. */

if (! SetEvent(hEvents[0]) ) {

        /* error exit */

}

}


  44.2.6  Using Critical Section Objects

The following example shows how a thread initializes, enters, and leaves a critical section. As with the mutex example (see Section 44.2.3, »Using Mutex Objects«), this example uses the try-finally structured exception handling syntax to ensure that the thread calls the LeaveCriticalSection function to release its ownership of the critical section object.

CRITICAL_SECTION GlobalCriticalSection;

/* Initialize the critical section. */

InitializeCriticalSection(&GlobalCriticalSection);

/* Request ownership of the critical section. */

try {

    EnterCriticalSection(&GlobalCriticalSection);

        .

        . /* Access the shared resource. */

        .

}

finally {

    /* Release ownership of the critical section. */

    LeaveCriticalSection(&GlobalCriticalSection);

}


  44.3  Functions

Following are the functions used in synchronization.

CreateEvent
CreateMutex
CreateSemaphore
DeleteCriticalSection
EnterCriticalSection
GetOverlappedResult
InitializeCriticalSection
InterlockedDecrement
InterlockedIncrement
LeaveCriticalSection
MsgWaitForMultipleObjects
OpenEvent
OpenMutex
OpenSemaphore
PulseEvent
ReleaseMutex
ReleaseSemaphore
ResetEvent
SetEvent
WaitForMultipleObjects
WaitForMultipleObjectsEx
WaitForSingleObject
WaitForSingleObjectEx


Files
  Chapter 45    Files

45.1  About Files

In Microsoft Windows, a file is a named, ordered collection of information, such as a program, a set of data used by a program, or a user-created document. Files are stored on storage media, such as disks or tapes, and can be organized into groups called directories. The Windows file input/output functions enable applications to create, open, modify, and delete files and directories. They also enable applications to obtain system information, such as what disk drives are present.


  45.1.1  System Organization

A volume is a storage device, such as a fixed disk or floppy disk, formatted to store directories and files. Each volume has a root directory. Directories and files on the volume are organized in a tree structure that starts at the root directory. Each directory entry identifies the name, attributes, location, and size of a file or subdirectory.

A large volume can be divided into more than one logical volume, also called a partition. Each partition appears to the user, and to the operating system, as a separate volume.

A file system is operating system software that manages the low-level organization of files on a volume. Windows supports the following file systems:

•	file allocation table (FAT)

•	high-performance file system (HPFS)

•	New Technology file system (NTFS)

The type of file system defines the filename conventions on a volume and may also provide specific file system features, such as security, recoverability, and high input and output (I/O) performance. Each volume can use a different file system.

For more information on the FAT, HPFS, and NTFS file systems, see Chapter 46, »File Systems«.

The first time a file function accesses a volume and whenever a volume is placed in a floppy-disk drive, Windows examines the volume to determine the appropriate file system. Thereafter, Windows manages all I/O to that volume through the device driver supporting the file system. If an error occurs, the driver returns it to Windows, which then passes it back to the application.

The Windows file functions enable applications to access files regardless of the underlying file system. However, their functionality may vary depending on the file system and/or operating system in use. For example, the CreateFile function includes a security parameter that provides no security benefits for an application written for Windows running with current versions of MS-DOS.

The Windows file functions that create, open, and delete files and directories identify them by their names. These functions store or search for the file or directory in the current directory on the current disk drive unless the name explicitly specifies a path to a different directory, disk drive, or both.


  45.1.1.1  Filename Conventions

Although each file system can have specific rules about the formation of individual components in a directory or filename, all file systems follow the same general conventions for combining components. For example, the FAT file system requires file and directory names to have the 8.3-character filename format; HPFS and NTFS allow names to be up to 255 characters. All three file systems use the backslash (\) character to separate directory names and the filename when forming a path.

General rules for applications creating names for directories and files or processing names supplied by the user include the following:

•	Use any character in the current code page for a name, but do not use a path separator, a character in the range 0 through 31, or any character explicitly disallowed by the file system. A name can contain characters in the extended character set (128−255).

•	Use the backslash (\), the forward slash (/), or both to separate components in a path. No other character is acceptable as a path separator.

•	Use a period (.) as a directory component in a path to represent the current directory.

•	Use two consecutive periods (..) as a directory component in a path to represent the parent of the current directory.

•	Use a period (.) to separate components in a directory name or filename.

•	Do not use the following characters in directory names or filenames, because they are reserved for Windows:

< > : " / \ |

•	Do not use reserved words, such as aux, con, and prn, as filenames or directory names.

•	Process a path as a null-terminated string. The maximum length for a path is given by MAX_PATH.

•	Do not assume case sensitivity. Consider names such as OSCAR, Oscar, and oscar to be the same.

By following the rules listed in this section, an application can create valid names for files and directories regardless of the file system in use.


  45.1.2  File Operations

This section describes the file I/O operations and operating system information provided by the file functions in the Win32 API.


  45.1.2.1  Creating and Opening Files

The CreateFile function can create a new file or open an existing file. When an application uses this function, it must specify whether it will read from the file, write to the file, or both. The application must also specify what action to take whether or not the file exists. For example, an application can specify that CreateFile always be used to create the file. As a result, the function creates the file if it does not exist and overwrites the file if it does exist.

CreateFile also enables an application to specify whether it wants to share the file for reading, writing, both, or neither. A file that is not shared cannot be opened more than once by the first application nor by another application until the first application has closed.

Windows assigns a unique identifier, called a file handle, to each file that is opened or created. An application can use the file handle in functions that read from, write to, and describe the file. It is valid until the file is closed. When an application starts, it inherits all open file handles from the process that started it, if the handles are inheritable. For more information about processes, see Chapter 43, »Processes and Threads«.

For information about the standard input, standard output, and standard error file handles, see Chapter 57, »Consoles and Character-Mode Support«.

An application should check the return value of CreateFile before attempting to use the handle to access the file. If an error occurs, the application can use the GetLastError function to get extended error information.


  45.1.2.2  Closing and Deleting Files

To use operating system resources efficiently, an application should close files when they are no longer needed by using the CloseHandle function. If a file is open when an application terminates, Windows closes it automatically.

The DeleteFile function can be used to delete a file. The file must, however, be closed before any attempt to delete it.


  45.1.2.3  Copying and Moving Files

Before a file can be copied, it must be closed or opened only for reading. No thread can have the file opened for writing. To copy an existing file to a new one, use the CopyFile function. Applications can specify whether CopyFile fails if the new file already exists.

A file must also be closed before an application can move it. The MoveFile function copies an existing file to a new location and deletes the original. Applications frequently use this function to rename files.


  45.1.2.4  Reading from and Writing to a File

Every open file has a file pointer that specifies the next byte to be read or the location to receive the next byte written. When a file is opened for the first time, Windows places the file pointer at the beginning of the file. As each byte is read or written, Windows advances the file pointer. An application can also move the file pointer by using the SetFilePointer function.

An application reads from and writes to a file by using the ReadFile and WriteFile functions. These functions require a handle of a file to be opened for reading and writing, respectively. ReadFile and WriteFile read and write a specified number of bytes at the location indicated by the file pointer. The data is read and written exactly as given; the functions do not format the data.

When the file pointer reaches the end of a file and the application attempts to read from the file, no error occurs, but no bytes are read. Therefore, reading zero bytes without an error means the program has reached the end of the file.

An application can truncate or extend a file by using the SetEndOfFile function. This function sets end-of-file to the current position of the file pointer. A WriteFile of zero bytes does nothing.

When an application writes to a file, Windows usually collects the data being written in an internal buffer and writes the data to the disk on a regular basis.

An application can force the operating system to write the contents of the buffer to the disk by using the FlushFileBuffers function. Alternatively, an application can specify that write operations are to bypass the internal buffer and write directly to the disk by setting a flag when the file is created or opened by using the CreateFile function.

If there is data in the internal buffer when the file is closed, Windows does not automatically write the contents of the buffer to the disk before closing the file. If the application does not force the operating system to write the buffer to disk before closing the file, the caching algorithm determines when the buffer is written.


  Locking and Unlocking Files

Although Windows allows more than one application to open a file and write to it, applications must not write over each other's work. An application can prevent this problem by temporarily locking a region in a file. The LockFile function locks a specified range of bytes in a file. The range may extend beyond the current end of the file. Locking part of a file prevents all other processes from reading or writing anywhere in the specified area. Attempts to read from or write to a region locked by another process always fail. The application unlocks the region by using the UnlockFile function. An application should unlock all locked areas before closing a file.


  Synchronizing Input and Output

Asynchronous input and output is a type of I/O in which some I/O functions return immediately, even though an I/O request is still pending. This enables an application to continue with other processing and wait for the I/O to be completed at a later time. Asynchronous I/O is also called overlapped I/O.

The ReadFile and WriteFile functions enable an application to specify an OVERLAPPED structure that indicates where to position the file pointer before the read or write operation. The handle of the file being read from or written to must have been opened with the FILE_FLAG_OVERLAPPED flag. The OVERLAPPED structure can also contain an event handle on which the WaitForSingleObject or WaitForMultipleObjects function can wait.

An application can also wait on the file handle to synchronize the completion of an I/O operation, but this requires extreme caution. Each time an I/O operation is started, the operating system sets the file handle to the nonsignaled state. Each time an I/O operation is completed, the operating system sets the file handle to the signaled state. Therefore, if an application starts two I/O operations and waits on the file handle, there is no way to determine which operation is finished when the handle is set to the signaled state. If an application must perform multiple asynchronous I/O operations on a single file, make it wait on the event handle in the OVERLAPPED structure for each I/O operation, rather than on the file handle.

The ReadFileEx and WriteFileEx functions enable an application to specify a routine to execute when the asynchronous I/O request is completed.

For more information about synchronization, see Chapter 44, »Synchronization«.


  45.1.2.5  Searching for Files

An application can search the current directory for all filenames that match a given pattern by using the FindFirstFile, FindNextFile, and FindClose functions. The pattern must be a valid filename and can include wildcard characters.

FindFirstFile creates a handle that FindNextFile uses to search for other files with the same pattern. Both functions also return information about the file that was found in a WIN32_FIND_DATA structure. This information includes the filename, size, attributes, and time. The FindClose function destroys the handle created by FindFirstFile. For more information about the WIN32_FIND_DATA structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

An application can search for a single file on a specific path by using the SearchPath function.


  45.1.2.6  Creating Temporary Files

Applications can create temporary filenames with the GetTempFileName function. The GetTempPath function retrieves the path to the directory where temporary files are to be created.


  45.1.2.7  Getting Information About Files

Ten characteristics called attributes may be associated with a file, as described in the following table.

Attribute	Meaning
FILE_ATTRIBUTE_ARCHIVE	The file is an archive file. Applications use this flag to mark files for backup or removal.
FILE_ATTRIBUTE_DIRECTORY	The file is a directory.
FILE_ATTRIBUTE_HIDDEN	The file is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL	The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_READONLY	The file is read only. Applications can read from the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM	The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY	The file is a temporary file. Applications can write to the file only if absolutely necessary. Most of the file's data remains in memory without being flushed to the media, because the file will soon be deleted.
FILE_ATTRIBUTE_ATOMIC_WRITE	The file is an atomic write file. Applications write to the file using atomic write semantics. If any write operation flushes data to the media, all write operations up to that point are also flushed, as well as any file system structures. This ensures that the data is retrievable at a later time.
FILE_ATTRIBUTE_XACTION_WRITE	The file is a transaction write file. Applications can write to the file using transaction write semantics. Either all of the write operations for a transaction are written to the media, or none are written.
An application can retrieve and set a file's attributes by using the GetFileAttributes and SetFileAttributes functions. Applications cannot, however, use SetFileAttributes to set the directory attribute.

The GetFileType function returns the type of a file: disk, character (such as a console), pipe, or unknown. The GetFileSize function returns the size of a file. Applications can retrieve the full path of a file by using the GetFullPathName function.

Applications can retrieve and set the date and time a file was created, last modified, or last accessed by using the GetFileTime and SetFileTime functions. For more information about file times, see Chapter 60, »Time«.


  45.1.2.8  Directory Operations

When an application creates a new file, the operating system adds it to the specified directory. Each directory can have any number of files, up to the physical limit of the disk. An application can create new directories and delete existing directories by using the CreateDirectory and RemoveDirectory functions. An application cannot delete a directory unless it is empty.

The directory at the end of the active path is called the current directory. This is the directory in which the active application started, unless explicitly changed. An application can determine which directory is current by using the GetCurrentDirectory function. An application can change the current directory by using the SetCurrentDirectory function.

An application can monitor the contents of a directory and its subdirectories by using the FindFirstChangeNotification, FindNextChangeNotification, and FindCloseChangeNotification functions. Waiting for a change notification is similar to having a read operation pending against a directory and, if necessary, its subdirectories. When something changes within the directory being watched, the read operation is completed. For example, an application can use these functions to update a directory listing whenever a filename within the monitored directory changes.

An application can specify a set of conditions that trigger a change notification by using the FindFirstChangeNotification function. The conditions include changes to filenames, directory names, attributes, file size, time of last write, and security. This function also returns a handle that can be waited on by using the WaitForSingleObject or WaitForMultipleObjects function. If the wait condition is satisfied, FindNextChangeNotification can be used to provide a notification handle to wait on subsequent changes.

The FindCloseChangeNotification function closes the notification handle.


  45.1.2.9  Getting System Information

Windows provides several functions that applications can use to obtain information about the file system, operating system, and hardware.

The GetVolumeInformation function retrieves information about the file system on a given volume. This information includes the volume name, volume serial number, file system name, file system flags, maximum length of a filename, and so on.

The GetSystemDirectory and GetWindowsDirectory functions retrieve the paths to the Windows system directory and the Windows directory, respectively.

The GetDiskFreeSpace function retrieves organizational information about a disk, including the number of bytes per sector, the number of sectors per cluster, the number of free clusters, and the total number of clusters.

The GetDriveType function indicates whether the disk referenced by the specified disk drive is removable, fixed, CD-ROM, RAM, or a network drive.

The GetLogicalDrives function identifies the drives currently present on the operating system. The GetLogicalDriveStrings function retrieves a null-terminated string for each drive present on the operating system. Use these strings whenever a root directory is required.


  45.2  Using Files

The Windows file functions enable applications to access files regardless of the underlying file system. However, their functionality may vary depending on the operating system in use. If you have questions about a specific function, consult the reference information on that function.

For functions that manipulate files, the filenames may be relative to the current directory. A filename is relative to the current directory if it does not begin with a disk designator or directory name separator, such as a backslash (\). If the filename begins with a disk designator, it is a fully qualified path.

The examples in this section illustrate how to perform the following tasks:

•	Create, open, close, and delete a file

•	Read from and write to a file

•	Lock and unlock a file

•	Set the file pointer

•	Get a unique temporary filename

•	Move a file

•	Search for a file

•	Create a directory

•	Copy a file

•	Get and set a file's attributes

•	Monitor changes in a directory or directory tree


  45.2.1  Creating and Opening Files

You can use the CreateFile function to create a new file or open an existing file. You must specify the filename, preferred access, share mode, creation instructions, and attributes.

The following example returns a handle of the current console input buffer.

HANDLE hReadWriteInput;

hReadWriteInput = CreateFile("CONIN$",

    GENERIC_READ | GENERIC_WRITE,

    FILE_SHARE_READ | FILE_SHARE_WRITE, /* share with cmd.      */

    NULL,

    OPEN_EXISTING,              /* open already created console */

    0,                          /* normal file open             */

    NULL

    );

For more information about consoles, see Chapter 57, »Consoles and Character-Mode Support«.

In the following example, CreateFile opens an existing file for reading.

HANDLE hFile;

hFile = CreateFile("MYFILE.TXT",           /* open MYFILE.TXT    */

                GENERIC_READ,              /* open for reading   */

                FILE_SHARE_READ,           /* share for reading  */

                (LPSECURITY_ATTRIBUTES) NULL, /* no security     */

                OPEN_EXISTING,             /* existing file only */

                FILE_ATTRIBUTE_NORMAL,     /* normal file        */

                (HANDLE) NULL);            /* no attr. template  */

if (hFile == INVALID_HANDLE_VALUE) {

        ErrorHandler("Could not open file.");   /* process error */

}

In this example, CreateFile succeeds only if a file named MYFILE.TXT already exists in the current directory. Your application should check the return value of CreateFile before attempting to use the handle to access the file. If an error occurs, use the GetLastError function to obtain extended error information and respond accordingly.

You must close a file before the file can be deleted. The following lines close and delete the file MYFILE.TXT.

CloseHandle(hFile);

DeleteFile("MYFILE.TXT");

In the following example, CreateFile creates a new file and opens it for writing.

HANDLE hFile;

hFile = CreateFile("MYFILE.TXT",           /* create MYFILE.TXT  */

             GENERIC_WRITE,                /* open for writing   */

             0,                            /* do not share       */

             (LPSECURITY_ATTRIBUTES) NULL, /* no security        */

             CREATE_ALWAYS,                /* overwrite existing */

             FILE_ATTRIBUTE_NORMAL |       /* normal file        */

             FILE_FLAG_OVERLAPPED,         /* asynchronous I/O   */

             (HANDLE) NULL);               /* no attr. template  */

if (hFile == INVALID_HANDLE_VALUE) {

    ErrorHandler("Could not open file.");  /* process error      */

}

In addition to the standard attributes (read only, hidden, system, and so on), you can also specify security attributes by including a pointer to a SECURITY_ATTRIBUTES structure as the fourth parameter. However, the underlying operating system must support security for these attributes for them to have any effect. For more information about security, see Chapter 49, »Security«.


  45.2.2  Reading, Writing, and Locking Files

The ReadFile function requires a file handle that is open for reading, or reading and writing. ReadFile copies a specified number of bytes, up to the end of the file, to a specified buffer. It returns the actual number of bytes read in a variable specified by its fourth parameter.

The WriteFile function requires a file handle that is open for writing, or writing and reading. WriteFile copies a specified number of bytes, up to the end of the buffer, to a specified file. It returns the actual number of bytes written in a variable specified by its fourth parameter.

The following example illustrates a possible flow for using callback completion asynchronous I/O.

Completion Routine:

VOID IoCompletionRoutine(DWORD dwErrorCode,

        DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)

{

    /* If an I/O error occurred, display the error and then exit. */

    if (dwErrorCode) {

        printf("FATAL I/O Error %ld I/O Context %lx.%lx\n",

            dwErrorCode, lpOverlapped, lpOverlapped->hEvent);

        ExitProcess(dwErrorCode);

    }

    LocalFree(lpOverlapped);

}

Main Thread:

VOID IoWorkerThread(VOID)

{

    HANDLE HandleVector[2];

    DWORD CompletionStatus;

    PIOREQUEST IoRequestPacket;

    LPOVERLAPPED Overlapped;

    BOOL IoOperationStatus;

    HandleVector[0] = IoWorkerListLock;

    HandleVector[1] = IoWorkerListSemaphore;

    for(;;) {

        /*

         * Do an alertable wait on the handle vector. Both objects

         * being signaled at the same time means there is an

         * I/O request in the queue, and the caller has exclusive

         * access to the queue.

         */

        CompletionStatus = WaitForMultipleObjectsEx(2, HandleVector,

                TRUE, INFINITE, TRUE);

        /* If the wait failed, error out. */

        if (CompletionStatus == 0xFFFFFFFF) {

            printf("FATAL WAIT ERROR %ld\n", GetLastError());

            ExitProcess(1);

        }

        /* If an I/O completion occurred, wait for another         */

        /* I/O request or I/O completion.                          */

        if (CompletionStatus != WAIT_IO_COMPLETION) {

        /* Wait was satisfied. We now have exclusive ownership of  */

        /* the I/O request queue, and there is something in the    */

        /* queue. To insert something in the queue, the            */

        /* inserter gets the list lock (mutex), inserts an entry,  */

        /* signals the list semaphore, and finally releases the    */

        /* list lock.                                              */

            IoRequestPacket = RemoveHeadList(&IoRequestList);

            ReleaseMutex(IoWorkerListLock);

            /* Allocate an overlapped structure. */

            Overlapped = LocalAlloc(LMEM_ZEROINIT,

                    sizeof(OVERLAPPED));

            if (!Overlapped) {

                printf("FATAL allocation error\n");

                ExitProcess(1);

            }

            Overlapped->Offset = IoRequestPacket->Offset;

            Overlapped->OffsetHigh = IoRequestPacket->OffsetHigh;

            Overlapped->hEvent =

                    IoRequestPacket->dwAdditionalIoContext;

            if (IoRequestPacket->bRead) {

                IoOperationStatus =

                            ReadFileEx(IoRequestPacket->hFile,

                    IoRequestPacket->lpBuffer,

                    IoRequestPacket->dwTransferCount,

                    Overlapped, IoCompletionRoutine);

            }

            else {

                IoOperationStatus =

                    WriteFileEx(IoRequestPacket->hFile,

                        IoRequestPacket->lpBuffer,

                        IoRequestPacket->dwTransferCount,

                        Overlapped,

                        IoCompletionRoutine);

            }

            /* Test to see if I/O was queued successfully. */

            if (!IoOperationStatus) {

                printf("FATAL I/O Error %ld I/O Context %lx.%lx\n",

                    GetLastError(), Overlapped, Overlapped->hEvent);

                ExitProcess(1);

            }

            /* The I/O queued successfully. Go back into the */

            /* alertable wait for I/O completion or for      */

            /* more I/O requests.                            */

        }

    }

}

The SetFilePointer function moves the file pointer a specified number of bytes, relative to the beginning or end of the file, or the file pointer's current position. If you specify a positive number of bytes, SetFilePointer moves the file pointer toward the beginning of the file; a negative value moves the pointer toward the end of the file.

The following example appends one file to the end of another file. The application opens two files by using CreateFile: ONE.TXT is opened for reading, and TWO.TXT is opened for writing. Then, the application appends the contents of ONE.TXT to the end of TWO.TXT by reading and writing 4K blocks by using ReadFile and WriteFile. Before writing to the second file, the application sets the second file's pointer to the end of the file by using SetFilePointer and locks the area to be written by using LockFile. This prevents another process from accessing the area while the write is in progress. After each write operation, UnlockFile unlocks the locked area.

HANDLE hFile;

HANDLE hAppend;

DWORD  dwBytesRead, dwBytesWritten, dwPos;

char   buff[4096];

/* Open the existing file. */

hFile = CreateFile("ONE.TXT",     /* open ONE.TXT       */

    GENERIC_READ,                 /* open for reading   */

    0,                            /* do not share       */

    (LPSECURITY_ATTRIBUTES) NULL, /* no security        */

    OPEN_EXISTING,                /* existing file only */

    FILE_ATTRIBUTE_NORMAL,        /* normal file        */

    (HANDLE) NULL);               /* no attr. template  */

if (hFile == INVALID_HANDLE_VALUE) {

    ErrorHandler("Could not open ONE.");  /* process error */

}

/*

 * Open the existing file or, if the file doesn't exist,

 * create new file.

 */

hAppend = CreateFile("TWO.TXT",   /* open TWO.TXT       */

    GENERIC_WRITE,                /* open for writing   */

    0,                            /* do not share       */

    (LPSECURITY_ATTRIBUTES) NULL, /* no security        */

    OPEN_ALWAYS,                  /* open or create     */

    FILE_ATTRIBUTE_NORMAL,        /* normal file        */

    (HANDLE) NULL);               /* no attr. template  */

if (hAppend == INVALID_HANDLE_VALUE) {

    ErrorHandler("Could not open TWO.");    /* process error */

}

/*

 * Append the first file to the end of the second file.

 * Lock the second file to prevent another process from

 * accessing it while writing to it. Unlock the

 * file when writing is finished.

 */

do {

  if (ReadFile(hFile, (LPSTR) buff, 4096, &dwBytesRead, NULL)) {

      dwPos = SetFilePointer(hAppend, 0, (LPLONG) NULL, FILE_END);

      LockFile(hAppend, dwPos, 0, dwPos + dwBytesRead, 0);

      WriteFile(hAppend, (LPSTR) buff, dwBytesRead,

          &dwBytesWritten, NULL);

      UnlockFile(hAppend, dwPos, 0, dwPos + dwBytesRead, 0);

  }

} while (dwBytesRead == 4096);

/* Close both files. */

CloseHandle(hFile);

CloseHandle(hAppend);


  45.2.3  Creating and Using a Temporary File

The following example copies one file to another. The second file is an uppercase version of the first file.

The application opens the file ORIGINAL.TXT by using CreateFile. The application then obtains a temporary filename with the GetTempFileName function and uses CreateFile to create the temporary file. The application reads 4K blocks into a buffer, converts the buffer contents to uppercase, and writes the converted buffer to the temporary file. When all of ORIGINAL.TXT has been written to the temporary file, the application closes both files and renames the temporary file to ALLCAPS.TXT by using the MoveFile function.

HANDLE hFile;

HANDLE hTempFile;

DWORD  dwBytesRead, dwBytesWritten, dwPos;

char szTempName[MAX_PATH];

char buffer[4096];

/* Open the existing file. */

hFile = CreateFile("ORIGINAL.TXT",        /* filename   */

    GENERIC_READ,                 /* open for reading   */

    0,                            /* do not share       */

    (LPSECURITY_ATTRIBUTES) NULL, /* no security        */

    OPEN_EXISTING,                /* existing file only */

    FILE_ATTRIBUTE_NORMAL,        /* normal file        */

    (HANDLE) NULL);               /* no attr. template  */

if (hFile == INVALID_HANDLE_VALUE) {

    ErrorHandler("Could not open file."); /* process err. on fail*/

}

/* Create a temporary file. */

GetTempFileName("\\TEMP", /* dir. for temp. files            */

    "NEW",                /* temp. filename prefix           */

    0,                    /* create unique name w/ sys. time */

    (LPTSTR) szTempName); /* buffer for name                 */

hTempFile = CreateFile((LPTSTR) szTempName,  /* filename     */

    GENERIC_READ | GENERIC_WRITE, /* open for read-write     */

    0,                            /* do not share            */

    (LPSECURITY_ATTRIBUTES) NULL, /* no security             */

    CREATE_ALWAYS,                /* overwrite existing      */

    FILE_ATTRIBUTE_NORMAL,        /* normal file             */

    (HANDLE) NULL);               /* no attr. template       */

if (hTempFile == INVALID_HANDLE_VALUE) {

    ErrorHandler("Could not create temporary file.");

}

/*

 * Read 4K blocks to the buffer.

 * Change all characters in the buffer to uppercase.

 * Write the buffer to the temporary file.

 */

do {

    if (ReadFile(hFile, (LPSTR) buffer, 4096,

        &dwBytesRead, NULL)) {

        CharUpperBuff((LPTSTR) buffer, dwBytesRead);

        WriteFile(hTempFile, (LPSTR) buffer, dwBytesRead,

            &dwBytesWritten, NULL);

    }

} while (dwBytesRead == 4096);

/* Close both files. */

CloseHandle(hFile);

CloseHandle(hTempFile);

/* Move the temporary file to the new text file. */

if (!MoveFile(szTempName, "ALLCAPS.TXT")) {

    ErrorHandler("Could not move temp. file.");

}


  45.2.4  Searching for Files and Changing File Attributes

The following example copies all text files in the current directory to a new directory of read-only files named \TEXTRO. Files in the new directory are changed to read only, if necessary.

The application uses the GetCurrentDirectory function to retrieve the current directory path. This is also used to return to the current directory after changing to the \TEXTRO directory.

The application then creates the \TEXTRO directory by using the CreateDirectory function.

The application searches the current directory for all .TXT files by using the FindFirstFile and FindNextFile functions. Each .TXT file is copied to the \TEXTRO directory. After a file is copied, the GetFileAttributes function determines whether the file is read only. If the file is not read only, the application changes directories to \TEXTRO and converts the copied file to read only by using the SetFileAttributes function.

After all .TXT files in the current directory have been copied, the application closes the search handle by using the FindClose function.

WIN32_FIND_DATA FileData;

HANDLE hSearch;

DWORD dwAttrs;

char szDirPath[] = "c:\\TEXTRO\\";

char szNewPath[MAX_PATH];

char szHome[MAX_PATH];

BOOL fFinished = FALSE;

/* Create a new directory. */

if (!CreateDirectory(szDirPath, NULL)) {

    ErrorHandler("Couldn't create new directory.");

}

/* Start searching for .TXT files in the current directory. */

hSearch = FindFirstFile("*.txt", &FileData);

if (hSearch == INVALID_HANDLE_VALUE) {

    ErrorHandler("No .TXT files found.");

}

/*

 * Copy each .TXT file to the new directory

 * and change to read only, if not already.

 */

while (!fFinished) {

    lstrcpy(szNewPath, szDirPath);

    lstrcat(szNewPath, FileData.cFileName);

    if (CopyFile(FileData.cFileName, szNewPath, FALSE)) {

        dwAttrs = GetFileAttributes(FileData.cFileName);

        if (!(dwAttrs & FILE_ATTRIBUTE_READONLY)) {

                SetFileAttributes(szNewPath,

                    dwAttrs | FILE_ATTRIBUTE_READONLY);

            }

    }

    else {

        ErrorHandler("Couldn't copy file.");

    }

    if (!FindNextFile(hSearch, &FileData))

        if (GetLastError() == ERROR_NO_MORE_FILES) {

            MessageBox(hwnd, "No more .TXT files.",

                "Search completed.", MB_OK);

            fFinished = TRUE;

        }

        else {

            ErrorHandler("Couldn't find next file.");

        }

}

/* Close the search handle. */

if (!FindClose(hSearch)) {

    ErrorHandler("Couldn't close search handle.");

}


  45.2.5  Monitoring Changes in a Directory or Directory Tree

The following example monitors the directory tree starting at C:\ for directory name changes. It also monitors the C:\WINDOWS directory for filename changes.

The example uses the FindFirstChangeNotification function to create two notification handles and the WaitForMultipleObjects function to wait on the handles. Whenever a directory is created or deleted in the tree starting at C:\, the example updates the entire directory tree. Whenever a file is created or deleted in the C:\WINDOWS directory, the example refreshes the WINDOWS directory. The FindNextChangeNotification function restarts the change notification each time the example processes a change.

DWORD dwWaitStatus;

HANDLE dwChangeHandles[2];

/*

 * Watch the C:\WINDOWS directory for file creation and

 * deletion.

 */

dwChangeHandles[0] = FindFirstChangeNotification(

    "C:\\WINDOWS",                 /* directory to watch       */

    FALSE,                         /* do not watch the subtree */

    FILE_NOTIFY_CHANGE_FILE_NAME); /* watch filename changes   */

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)

    ExitProcess(GetLastError());

/*

 * Watch the C:\ subtree for directory creation and

 * deletion.

 */

dwChangeHandles[1] = FindFirstChangeNotification(

    "C:\\",                        /* directory to watch      */

    TRUE,                          /* watch the subtree       */

    FILE_NOTIFY_CHANGE_DIR_NAME);  /* watch dir. name changes */

if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)

    ExitProcess(GetLastError());

/*

 * Change notification is set. Now wait on both notification

 * handles and refresh accordingly.

 */

while (TRUE) {

  /* Wait for notification. */

  dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,

      FALSE, INFINITE);

  switch (dwWaitStatus) {

    case WAIT_OBJECT_0:

      /*

       * A file was created or deleted in C:\WINDOWS.

       * Refresh this directory and restart the

       * change notification. RefreshDirectory is an

       * application-defined function.

       */

      RefreshDirectory("C:\\WINDOWS")

      if (FindNextChangeNotification(dwChangeHandles[0]) == FALSE)

          ExitProcess(GetLastError());

      break;

    case WAIT_OBJECT_0 + 1:

      /*

       * A directory was created or deleted in C:\.

       * Refresh the directory tree and restart the

       * change notification. RefreshTree is an

       * application-defined function.

       */

      RefreshTree("C:\\");

      if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE)

          ExitProcess(GetLastError());

      break;

       default:

            ExitProcess(GetLastError());

  }

}


  45.2.6  Retrieving a File Pointer

The following example retrieves the current position of the file pointer in the file specified by the hFile value.

HANDLE hFile;

DWORD dwCurrentFilePosition;

dwCurrentFilePosition = SetFilePointer(

    hFile, /* must have GENERIC_READ and/or GENERIC_WRITE    */

    0,     /* do not move pointer                            */

    NULL,  /* hFile is not large enough to need this pointer */

    FILE_CURRENT);  /* provides offset from current position */


  45.3  Functions

Following are the functions used with files.

CloseHandle
CopyFile
CreateDirectory
CreateFile
DefineDosDevice
DeleteFile
FileIOCompletionRoutine
FindClose
FindCloseChangeNotification
FindFirstChangeNotification
FindFirstFile
FindNextChangeNotification
FindNextFile
FlushFileBuffers
GetCurrentDirectory
GetDiskFreeSpace
GetDriveType
GetFileAttributes
GetFileInformationByHandle
GetFileSize
GetFileType
GetFullPathName
GetLogicalDrives
GetLogicalDriveStrings
GetTempFileName
GetTempPath
GetVolumeInformation
_hread
_hwrite
_lclose
_lcreat
_llseek
LockFile
LockFileEx
_lopen
_lread
_lwrite
MoveFile
MoveFileEx
OpenFile
QueryDosDevice
ReadFile
ReadFileEx
RemoveDirectory
SearchPath
SetCurrentDirectory
SetEndOfFile
SetFileAttributes
SetFilePointer
SetHandleCount
SetVolumeLabel
UnlockFile
UnlockFileEx
WriteFile
WriteFileEx


File Systems
  Chapter 46    File Systems

46.1  About File Systems for Microsoft Windows NT

Windows NT supports three file systems: New Technology file system (NTFS), file allocation table (FAT) file system, and high-performance file system (HPFS).

A file system defines how information is organized on a volume. This includes mandating the filename conventions on a volume and providing specific features of a file system, such as security, recoverability, and high input and output (I/O) performance. Each volume can use a different file system. All three file systems in Windows NT use one or more tables that specify the location and size of the data files on the volume, as well as other information specific to the file system.

With Windows NT, you can install a file system by specifying the desired file-system device drivers and dynamic-link libraries during setup. Device drivers access volumes; the driver's .INF file describes the driver to the setup procedure. Dynamic-link libraries control the format of information on a volume and manage the flow of data to and from the volume.

The FAT file system is the default file system for Windows NT; it does not need to be installed. HPFS and NTFS are installable file systems; their software can be installed when the operating system starts.

Although Windows NT may be booted from all three file systems, FAT and NTFS are strongly recommended. Note that on a MIPS-based ARC-compliant machine, the system partition (that is, the one that contains the program OSLOADER.EXE) must be a FAT file system. The Windows NT system root may be on FAT or NTFS.


  46.2  The New Technology File System

The New Technology file system (NTFS) organizes data on fixed disks. This file system supports object-oriented applications by treating all files as objects with user- and system-defined attributes. NTFS provides all the capabilities of the FAT and HPFS file systems without many of their limitations. Accessing files under NTFS is often faster than accessing similar files under the FAT or HPFS file systems.

NTFS is a fully recoverable file system. It is designed to restore consistency to a disk after a CPU failure, system crash, or I/O error. NTFS allows the operating system to recover without your having to use the autochk or chkdsk utilities. However, NTFS provides these utilities in case recovery fails or corruption occurs outside the control of the file system. NTFS also includes features not present in HPFS or FAT, such as security, Unicode filenames, automatic creation of MS-DOS® aliases, multiple data streams, and unique functionality specific to the POSIX subsystem. For more information on security, see Chapter 49, »Security«. For more information on Unicode, see Chapter 53, »String Manipulation and Unicode«.

NTFS follows the filename conventions described in the HPFS section, but it also supports Unicode filenames.

NTFS cannot manipulate a file's extended attributes if the file was created on HPFS.


  46.3  The File Allocation Table File System

The FAT file system organizes data on fixed disks and floppy disks. The distinguishing feature of the FAT file system is its filename convention. The filename convention consists of a filename (up to eight characters), a separating period (.), and a filename extension (up to three characters).

The main advantage of FAT volumes is that they are accessible by MS-DOS, Microsoft Windows, and OS/2 systems. FAT is also the only file system currently supported on floppy disks and other removable media.

Valid Windows NT FAT filenames have the following form:

[[drive:]][[directory\]]filename[[.extension]]

The drive parameter must name an existing drive and can be any letter from A through Z. The drive letter must be followed by a colon (:).

The directory parameter specifies the directory that contains the file's directory entry. This value must be followed by a backslash (\) to separate it from the filename. If the specified directory is not in the current directory, directory must include the names of all directories in the file's path, separated by backslashes. The root directory is specified by using a backslash at the beginning of the name. For example, if the directory ABC is in the directory SAMPLE and SAMPLE is in the root directory, the correct directory specification is \SAMPLE\ABC. A directory name consists of any combination of up to eight letters, digits, or the following special characters:

$ % ' − _ @ { } ~ ` ! # ( )

A directory name can also have an extension that is any combination of up to three letters, digits, or special characters, preceded by a period (.).

The filename and extension parameters specify the file. Filename can be any combination of up to eight letters, digits, or the special characters previously listed; extension can be any combination of up to three letters, digits, or special characters, all preceded by a period. Filename can also include embedded (preceded and followed by one or more letters, digits, or special characters just noted) spaces. For example, the string "disk 1" is a legal value for filename.

FAT volumes do not distinguish between uppercase and lowercase letters.


  46.4  The High-Performance File System

HPFS organizes data on fixed disks. Filenames under HPFS can be any practical length (up to 254 characters) and can contain characters that are not valid for the FAT file system, such as spaces and periods. In many cases, accessing files under HPFS is faster than accessing similar files under the FAT file system. Although HPFS is provided for data exchange with OS/2, in Windows NT, HPFS offers no performance advantages over FAT.

Blank spaces can be used anywhere in an HPFS filename or directory name, but blank spaces and periods at the end of a filename are ignored. There is no requirement that HPFS filenames have extensions; however, many applications still create and use them.

The following special characters can also be used in HPFS filenames:

, + = [ ] ; _

An HPFS filename can be all uppercase, all lowercase, or mixed case. The case is preserved for directory listings but is ignored in file searches and all other system operations. Therefore, in a given directory, there cannot be more than one file with the same name when the only difference is case.


File Mapping
  Chapter 47    File Mapping

47.1  About File Mapping

File mapping is the copying of a file's contents to a process's virtual address space. The copy of the file's contents is called the file view, and the internal structure the operating system uses to maintain the copy is called the file-mapping object.

Another process can create an identical file view in its own virtual address space by using the first process's file-mapping object to create the view. This enables the processes to share data. Any process that has the name or a handle of a file-mapping object can create a file view.

Microsoft Windows NT file-mapping functions create file-mapping objects and file views necessary for this method of data sharing.


  47.1.1  Sharing a File

If two (or more) processes need to share a file, one process should open the file for exclusive access by using the CreateFile function. The CreateFileMapping function uses the handle returned by CreateFile to create a file-mapping object. Processes that have the name or a handle of the file-mapping object can share the file's data. The file handle should remain open until the processes are no longer sharing the file; this prevents nonsharing processes from reading from or writing to the file.

CreateFileMapping enables you to specify an object name, the number of bytes to be mapped from the file, and the read-and-write access to the mapped memory. CreateFileMapping fails if the access flags conflict with those specified when the file was opened by using CreateFile. CreateFileMapping returns a handle of the file-mapping object. This handle is used to create a "view of the file," or "file view," in the process's virtual address space. A file view is a copy of the entire file or a portion of the file, depending on the number of bytes requested.

The process that created the file-mapping object uses the MapViewOfFile function with the file-mapping object handle to create a file view, or copy of the file, in the process's virtual address space. MapViewOfFile returns a pointer to the file view. This function fails if the access flags conflict with those specified when the mapping object was created with CreateFileMapping.

To share the data in the file view, another process must create an identical file view in its own virtual address space. To do this, the process must first obtain a handle of the same file-mapping object and then create its own file view by using MapViewOfFile. The easiest way to obtain a handle of the file-mapping object is to use the OpenFileMapping function and specify the object's name. If the file-mapping object does not have a name, the process must obtain a handle of it through inheritance or duplication. For more information on inheritance and duplication, see Chapter 43, »Processes and Threads«, and Chapter 48, »Handles and Objects«.

MapViewOfFile returns a pointer to the file view. To ensure that multiple processes are sharing the same data through their own pointers, all views of a file must be derived from the same file-mapping object. If this is the case, the file views are said to be coherent, or identical. Typically, file views are not coherent if they are derived from different file-mapping objects, even if the mapping objects refer to the same file.

Because the file view is a block of memory and not a file, processes must read from and write to the file view by using the ReadProcessMemory and WriteProcessMemory functions, not the ReadFile and WriteFile functions.

If one or more of the processes has write access to the shared data, processes must synchronize their access to the shared data by using a semaphore. This ensures that the file views remain coherent in all processes. For more information on synchronization, see Chapter 44, »Synchronization«.

Some applications require that a file be mapped to the same address in multiple processes. To place the file view at a specific location within the process's address space, you should use the MapViewOfFileEx function and specify the desired address. If there is not enough space at the specified address, the function fails.

Although CreateFileMapping works with remote files, it does not keep them coherent. For example, if two machines both map a file as writable, and both change the same page, each machine will only see its own writes to the page. When the data gets updated on the disk, it is not merged.


  47.1.2  Sharing a Memory Block

If two (or more) processes need to share a memory block not associated with a file, one process must use the CreateFileMapping function and specify (HANDLE)0xFFFFFFFF instead of an existing file handle. The corresponding file-mapping object accesses memory from the operating-system paging file. Processes sharing the operating-system paging file must create file views by using the MapViewOfFile or MapViewOfFileEx function just as when sharing a named file.


  47.1.3  Closing a File View

When a process has finished using the shared memory, it should destroy the file view in its address space by using the UnmapViewOfFile function. This invalidates the pointer to the shared memory. If any of the pages of the file view changed since the view was mapped, this function copies the changed pages to the physical file.

To copy a specified number of bytes from the file view to the physical file, you should use the FlushViewOfFile function. FlushViewOfFile does not destroy the file view.

For information on other ways to share data among applications, see Chapter 77, »Dynamic Data Exchange Management Library«.


  47.2  Using File Mapping

The code samples in this section illustrate how two processes might access an existing file as named shared memory.

As discussed earlier, if one or both processes write to the shared memory, the processes must use a semaphore to synchronize their access to the memory. For more information on synchronization, see Chapter 44, »Synchronization«.

In the following code, the CreateFileMapping function creates a file-mapping object. When a corresponding file view is created, the process has read-and-write access to the memory.

hMapFile = CreateFileMapping(hFile,    /* current file handle */

    (LPSECURITY_ATTRIBUTES) NULL,      /* no security         */

    PAGE_READWRITE,                    /* read-write access   */

    0,                                 /* max. object size is */

    0,                                 /* size of hFile       */

    "MyFileMappingObject");            /* name of map. object */

if (hMapFile == NULL) {

    ErrorHandler("Could not create file-mapping object.");

}

The following code uses the file-mapping object handle returned by CreateFileMapping to create a view of the file in the process's address space.

lpMapAddress = MapViewOfFile(hMapFile, /* handle to map. object */

    FILE_MAP_ALL_ACCESS,               /* read-write access     */

    0,                                 /* max. object size is   */

    0,                                 /* size of hFile         */

    0);                                /* map entire file       */

if (lpMapAddress == NULL) {

    ErrorHandler("Could not map view of file.");

}

The MapViewOfFile function returns a pointer to the file view. The process can use the pointer to access the memory for whatever it needs to do.

In the next example, a second process uses the OpenFileMapping function to share the same memory. As in the original process, the MapViewOfFile function returns a pointer to the file view.

hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, /* r-w access  */

    FALSE,                             /* do not inherit       */

    "MyFileMappingObject");            /* name of mapping obj. */

if (hMapFile == NULL) {

    ErrorHandler("Could not open file-mapping object.");

}

lpMapAddress = MapViewOfFile(hMapFile, /* hndl. to map. obj.  */

    FILE_MAP_ALL_ACCESS,               /* read-write access   */

    0,                                 /* max. object size is */

    0,                                 /* size of hFile       */

    0);                                /* map entire file     */

if (lpMapAddress == NULL) {

    ErrorHandler("Could not map view of file.");

}

Note that MapViewOfFile returns different addresses in different processes. To specify the location of the file view within a process's address space, use the MapViewOfFileEx function, rather than MapViewOfFile.

The following example uses the UnmapViewOfFile function to invalidate the pointer to the mapped memory. This destroys the file view in the process's address space. If any pages of the file view changed since the view was mapped, UnmapViewOfFile also copies the changed pages to the physical file.

if (!UnmapViewOfFile(lpMapAddress)) {

    ErrorHandler("Could not unmap view of file.");

}

The FlushViewOfFile function copies the specified number of bytes of the file view to the physical file but does not destroy the file view:

if (!FlushViewOfFile(lpMapAddress, dwBytesToFlush)) {

    ErrorHandler("Could not flush memory to disk.");

}


  47.3  Functions

The following functions are used with file mapping.

CreateFileMapping
FlushViewOfFile
MapViewOfFile
MapViewOfFileEx
OpenFileMapping
UnmapViewOfFile


Handles and Objects
  Chapter 48    Handles and Objects

48.1  About Handles and Objects

An object is an internal structure that represents a system resource, such as a file, a thread, or a graphic image. An application cannot directly access the internal structure of an object or the system resource that an object represents. Instead, an application must obtain an object handle and use this handle to examine or modify the system resource (or both). In the Microsoft Windows NT operating system, handles are usually implemented as indirect pointers, but this is not always the case.

Windows NT uses objects and handles to regulate access to system resources for two main reasons. First, the use of objects ensures that developers are not writing code specifically to low-level, internal structures. This enables Microsoft to add or change functionality in future versions of the operating system, as long as the original calling conventions are maintained. When subsequent versions of the operating system are released, applications will gain this new functionality with little or no additional development.

Second, the use of objects enables developers to take advantage of Windows NT security. Each object has its own access-control list (ACL) that specifies the types of actions processes can perform on the object. The operating system examines an object's ACL each time an application attempts to create a handle to the object. For more information about security, see Chapter 49, »Security«.

For most objects, the Win32 API provides functions that create the object, create an object handle, close the object handle, and destroy the object. These tasks may be combined or unnecessary, depending on the type of object and the situation. For example, an application could create an event object. Other applications could open the event and each would have a unique handle to the same event object. In this scenario, as the applications finish using the object, each closes its handle. When there are no open handles to the event object, the operating system removes the object from memory.

In contrast, an application could obtain the existing window-object handle. In this instance, when the window object is no longer needed, the application must remove the object from memory, which invalidates the window handle.

When a process terminates, the operating system automatically closes handles and deletes objects created by the process. However, when a thread terminates, the operating system usually does not close handles or delete objects. The only exceptions are window, hook, window position, and dynamic data exchange (DDE) conversation objects that are deleted when the creating thread terminates.

Handles and objects consume memory. Therefore, to preserve operating-system performance, applications should close handles and delete objects as soon as the handles and objects are no longer needed. Applications that do not do this can slow the operating system, due to excessive use of the paging file.

Windows NT provides three categories of objects: user, graphics device interface (GDI), and kernel, as shown in the following tables. The operating system uses user objects to support window management, GDI objects to support graphics, and kernel objects to support memory management, process execution, and interprocess communications (IPC). For information about creating and using a specific object, refer to the associated overview chapter.

Windows NT User Objects

User object	Overview
Accelerator table	Chapter 17, "Keyboard Accelerators" in Microsoft Win32 Programmer's Reference, Volume 1.
Caret	Chapter 22, "Carets" in Microsoft Win32 Programmer's Reference, Volume 1
Cursor	Chapter 21, "Cursors" in Microsoft Win32 Programmer's Reference, Volume 1
Dynamic data exchange conversation	Chapter 77, »Dynamic Data Exchange Management Library«
Desktop	Chapter 49, »Security«
Hook	Chapter 8, "Hooks" in Microsoft Win32 Programmer's Reference, Volume 1
Icon	Chapter 23, "Icons" in Microsoft Win32 Programmer's Reference, Volume 1
Menu	Chapter 16, "Menus" in Microsoft Win32 Programmer's Reference, Volume 1
Window	Chapter 1, "Windows" in Microsoft Win32 Programmer's Reference, Volume 1
Window position	Chapter 1, "Windows" in Microsoft Win32 Programmer's Reference, Volume 1
Window station	Chapter 1, "Windows" in Microsoft Win32 Programmer's Reference, Volume 1
Windows NT GDI Objects

GDI object	Overview
Bitmap	Chapter 29, "Bitmaps" in Microsoft Win32 Programmer's Reference, Volume 1
Brush	Chapter 30, "Brushes" in Microsoft Win32 Programmer's Reference, Volume 1
Font	Chapter 35, "Fonts and Text" in Microsoft Win32 Programmer's Reference, Volume 1
Palette	Chapter 36, "Colors" in Microsoft Win32 Programmer's Reference, Volume 1
Pen	Chapter 31, "Pens" in Microsoft Win32 Programmer's Reference, Volume 1
Extended pen	Chapter 31, "Pens" in Microsoft Win32 Programmer's Reference, Volume 1
Region	Chapter 32, "Regions" in Microsoft Win32 Programmer's Reference, Volume 1
Device context	Chapter 28, "Device Contexts" in Microsoft Win32 Programmer's Reference, Volume 1
Memory device context	Chapter 28, "Device Contexts" in Microsoft Win32 Programmer's Reference, Volume 1
Metafile	Chapter 40, "Metafiles" in Microsoft Win32 Programmer's Reference, Volume 1
Metafile device context	Chapter 40, "Metafiles" in Microsoft Win32 Programmer's Reference, Volume 1
Enhanced metafile	Chapter 40, "Metafiles" in Microsoft Win32 Programmer's Reference, Volume 1
Enhanced-metafile device context	Chapter 40, "Metafiles" in Microsoft Win32 Programmer's Reference, Volume 1
Windows NT Kernel Objects

Kernel object	Overview
Process	Chapter 43, »Processes and Threads«
Thread	Chapter 43, »Processes and Threads«
File	Chapter 45, »Files«
File mapping	Chapter 47, »File Mapping«
Event	Chapter 44, »Synchronization«
Semaphore	Chapter 44, »Synchronization«
Mutex	Chapter 44, »Synchronization«
Pipe (named and anonymous)	Chapter 54, »Pipes«
Mailslot	Chapter 55, »Mailslots«
Communications device	Chapter 68, »Communications«
Heap	Chapter 42, »Memory Management«
Module	Chapter 50, »Dynamic-Link Libraries«
Update resource	Chapter 51, »Resources«
Find file	Chapter 45, »Files«
Event log	Chapter 65, »Event Logging«
Change notification	Chapter 45, »Files«
Token	Chapter 49, »Security«
Service object	Chapter 41, Printing and Print Spooler in Microsoft Win32 Programmer's Reference, Volume 1.
LZ file	Chapter 81, »Data Decompression Library«


  48.1.1  Handle Limitations

Some objects, such as user and GDI objects, support only one handle at a time. The operating system provides the handle when an application creates the object and invalidates the handle when the application destroys the object. Other objects, such as some kernel objects, support multiple handles to a single object. The operating system automatically removes the object from memory after the last handle to the object is closed.

The total number of open handles in the operating system is limited only by the amount of memory available to the operating system. However, a single process may have no more than 65,536 open GDI object handles. The per-process limit on user handles is 2 (32) ; the per-process limit on kernel handles is 2 (30) .


  48.2  User and Graphics Device Interface Objects

User and GDI objects support only one handle per object. Processes cannot inherit or duplicate handles to user or GDI objects.

Handles to user objects are public to all processes. That is, any process can use the user object handle, provided that the process has access to the object as defined by user security. For more information about security, see Chapter 49, »Security«.

Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle.

The following illustrations show the creation and destruction of a user object, although the concepts apply equally to GDI objects.

In »this illustration«, an application creates a window object. The CreateWindow function creates the window object and returns an object handle.

After the window object has been created, the application can use the window handle to display or change the window. The handle remains valid until the window object is destroyed.

In »this illustration«, the application destroys the window object. The DestroyWindow function removes the window object from memory, which invalidates the window handle.

The following table lists the Windows NT user objects and each object's creator and destructor functions. The creator functions either create the object and an object handle or simply return the existing object handle. The destructor functions remove the object from memory, which invalidates the object handle.

Note that the window station and desktop objects are created and maintained by the system; applications cannot delete these objects.

User Objects

Object	Creator function	Destructor function
Accelerator table	CreateAcceleratorTable	DestroyAcceleratorTable
Cursor	CreateCursor, LoadCursor, GetCursor, SetCursor	DestroyCursor
Dynamic data exchange conversation	DdeConnect, DdeConnectList, DdeQueryNextServer, DdeReconnect	DdeDisconnect, DdeDisconnectList
Desktop	GetThreadDesktop	−
Hook	SetWindowsHook, SetWindowsHookEx	UnhookWindowsHook
Menu	CreateMenu, CreatePopupMenu, GetMenu, GetSubMenu, GetSystemMenu,LoadMenu, LoadMenuIndirect	DestroyMenu
Window	CreateWindow, CreateWindowEx, CreateDialogParam, CreateDialogIndirectParam,CreateMDIWindow, FindWindow, GetWindow, GetClipboardOwner, GetDesktopWindow, GetDlgItem, GetForegroundWindow, GetLastActivePopup, GetOpenClipboardWindow, GetTopWindow, WindowFromDC, WindowFromPoint, and others	DestroyWindow
Window position	BeginDeferWindowPos	EndDeferWindowPos
Window station	GetProcessWindowStation	−
The following table lists the Windows NT GDI objects and each object's creator and destructor functions. The creator functions either create the object and an object handle or simply return the existing object handle. The destructor functions remove the object from memory, which invalidates the object handle.

GDI Objects

Object	Creator function	Destructor function
Bitmap	CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDIBitmap,CreateDIBSection, CreateDiscardableBitmap	DeleteObject
Brush	CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt,CreateHatchBrush, CreatePatternBrush, CreateSolidBrush	DeleteObject
Font	CreateFont, CreateFontIndirect, ExtCreateFontIndirect	DeleteObject
Palette	CreatePalette	DeleteObject
Pen	CreatePen, CreatePenIndirect	DeleteObject
Extended pen	ExtCreatePen	DeleteObject
Region	CreateRegion, CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect,CreatePolygonRgn, CreatePolyPolygonRgn, CreateRectRgn, CreateRectRgnIndirect, CreateRoundRectRgn, ExtCreateRegion, PathToRegion	DeleteObject
Device context	CreateDC, GetDC	DeleteDC, ReleaseDC
Memory device context	CreateCompatibleDC	DeleteDC
Metafile	CloseMetaFile, CopyMetaFile, GetMetaFile, SetMetaFileBitsEx	DeleteMetaFile
Metafile device context	CreateMetafile	CloseMetaFile
Enhanced metafile	CloseEnhMetaFile, CopyEnhMetaFile, GetEnhMetaFile, SetEnhMetaFileBits	DeleteEnhMetaFile
Enhanced-metafile device context	CreateEnhMetaFile	CloseEnhMetaFile


  48.3  Kernel Objects

Kernel object handles are process specific. That is, a process must either create a kernel object or open an existing object to obtain an object handle. Any process can create a new handle to an existing kernel object (even one created by another process), provided that the process knows the name of the object and has access to the object as defined by user security. For more information about security, see Chapter 49, »Security«.

Processes can inherit or duplicate handles to the following types of kernel objects:

•	Processes

•	Threads

•	Files (including file-mapping objects)

•	Events

•	Semaphores

•	Mutexes

•	Pipes (named and anonymous)

•	Mailslots

•	Communications devices

All other kernel objects are private to the process that created them; object handles cannot be duplicated or inherited.

A child process inherits an open handle from its parent process if inheritance was specified when the original handle was created and if the child process was created with the "inherit handles" flag set. An inherited handle is valid only in the context of the child process.

The DuplicateHandle function duplicates a handle into the current process or into another process. If an application duplicates one of its handles into another process, the duplicated handle is valid only in the context of the other process.

A duplicated or inherited handle is a unique value, but it refers to the same object as the original handle.

Kernel object handles include access rights that indicate the actions the application wants to perform on the object. An application specifies access rights when it creates an object or obtains an existing object handle. Each type of kernel object supports its own set of access rights. For example, event handles can have "set" or "wait" access (or both), file handles can have "read" or "write" access (or both), and so on. For more information on access rights, see Chapter 49, »Security«, and the chapters that describe individual objects.

In »this illustration«, an application creates an event object. The CreateEvent function creates the event object and returns an object handle.

After the event object has been created, the application can use the event handle to set or wait on the event. The handle remains valid until the application closes the handle or terminates.

Most kernel objects support multiple handles to a single object. For example, the application in the preceding illustration could obtain additional event object handles by using the OpenEvent function, as shown in »this illustration«.

This enables an application to have handles with different access rights. For example, Handle 1 might have "set" and "wait" access to the event, and Handle 2 might have only "wait" access.

If another process knows the event name and has security access to the object, it can create its own event object handle by using OpenEvent, as shown in »this illustration«.

The original application could also duplicate one of its handles into the same process or into another process by using the DuplicateHandle function, as shown in »this illustration«.

»This illustration« shows how a child process inherits a handle created by its parent process.

A child process of an application automatically inherits handles created by its parent process if inheritance was specified when the handles were created and if the child process is created with the "inherit handles" flag set. Note that in the preceding illustration, Handle 2 is not equivalent to Handle 1 but does refer to the same event object.

For more information on inheritance, see Chapter 43, »Processes and Threads«, and Chapter 45, »Files«.

An object remains in memory as long as at least one object handle exists. In the following illustration, the applications use the CloseHandle function to close their event object handles. When there are no event handles, the operating system removes the object from memory, as shown in »this illustration«.

Occasionally, an object remains in memory after all object handles have been closed. For example, a thread could create an event object and wait on the event handle. While the thread is waiting, another thread could close the same event object handle. The event object remains in memory, without any event object handles, until the event object is set to the signaled state and the wait operation is completed. At this time, the operating system removes the object from memory.

Windows NT manages file objects somewhat differently from other kernel objects. File objects contain the file pointer — the pointer to the next byte to be read or written in a file. Whenever an application creates a new file handle, the operating system creates a new file object. Therefore, more than one file object can refer to a single file on disk, as shown in »this illustration«.

Only through duplication or inheritance can more than one file handle refer to the same file object, as shown in »this illustration«.

The following table lists each of the Windows NT kernel objects and each object's creator and destructor functions. The creator functions either create the object and an object handle or create a new existing object handle. The destructor functions close the object handle. When an application closes the last handle to a kernel object, the operating system removes the object from memory.

Kernel Objects

Object	Creator function	Destructor function
Process	CreateProcess, OpenProcess, GetCurrentProcess	CloseHandle, TerminateProcess
Thread	CreateThread, CreateRemoteThread, GetCurrentThread	CloseHandle, TerminateThread
File	CreateFile	CloseHandle, DeleteFile
File mapping	CreateFileMapping, OpenFileMapping	CloseHandle
Event	CreateEvent, OpenEvent	CloseHandle
Semaphore	CreateSemaphore, OpenSemaphore	CloseHandle
Mutex	CreateMutex, OpenMutex	CloseHandle
Pipe	CreatePipe	CloseHandle
Named pipe	CreateNamedPipe	CloseHandle, DisconnectNamedPipe
Mailslot	CreateMailslot	CloseHandle
Communications device	GetStdHandle	CloseHandle
Heap	HeapCreate	HeapDestroy
Module	LoadLibrary,  GetModuleHandle	FreeLibrary
Update resource	BeginUpdateResource	EndUpdateResource
Find file	FindFirstFile	FindCloseFile
Event log	OpenEventLog, RegisterEventSource, OpenBackupEventLog	CloseEventLog
Change notification	FindFirstChangeNotification	FindCloseChangeNotification


Security
  Chapter 49    Security

49.1  About Security

The security provisions of Microsoft Windows NT are available to Windows-based applications automatically. Every application running on the system is subject to the security imposed by the particular configuration of the local implementation of Windows NT.

The security functions in the Win32 application programming interface (API) allow an application to selectively grant and deny access to an object. An application can specify many different kinds of access for particular users and groups of users. The operating system grants or denies access to an object based on a comparison of the security provisions stored with an object with the access rights specified in a token associated with the process or thread requesting the access. These security functions allow an application to query and manipulate the security features of both an object and a process or thread.

The impact of Windows security on most Windows functions is minimal, and a Windows-based application not requiring security functionality usually does not need to incorporate any special code. However, a developer can use the security features of Windows NT to provide a number of services in a Windows-based application. Generally, any application that manipulates a system-wide resource such as the system time, must use the security system to gain access to that resource. A security-aware application might allow the user to query the security attributes of a file, provide specialized feedback when access to a secure file is denied, or customize the security attributes of a file or group of files so that only a subset of other users on a network has access to the information.

The first release of Windows NT is designed to support C2-level security as defined by the US Department of Defense. Some of the most important requirements of C2-level security are shown in the following list.

•	It must be possible to control access to a resource. This access control must include or exclude individual users or named groups of users.

•	Memory must be protected so its contents cannot be read after it is freed by a process.

•	Users must identify themselves in a unique manner when they log on. All auditable actions must identify the user performing the action.

•	System administrators must be able to audit security-related events. Access to this audit data must be limited to authorized administrators.

•	The system must protect itself from external interference or tampering, such as modification of the running system or of system files stored on disk.


  49.2  Security Model

All named objects in Windows NT, and some unnamed objects, can be secured. The security attributes of each securable object in Windows are described by a security descriptor, that contains information about the owner of the object and by an access-control list (ACL), identifying the users and groups allowed or denied access to the object. An ACL contains an entry for each user, global group, or local group (alias) being allowed or denied access to the object. Each of these entries is an access-control entry (ACE).

At logon, a user is assigned an access token containing identifiers that represent the user and any groups to which the user belongs. Every process run on behalf of this user will have a copy of this particular access token. When a process attempts to use an object, the system compares the security attributes listed in the access token with the ACEs in the object's ACL. The system compares the access token with each ACE until access is either granted or denied or until there are no more ACEs to check. Conceivably, several ACEs could apply to a token. And, if this occurs, the access rights granted by each ACE accumulate. For example, if one ACE grants read access to a group in an access token and another ACE grants write access to the user, who is also a member of the group, the user will have both read and write access to the object when the access check is complete.

»This illustration« shows the relationship between these blocks of security information:

Typically, the application protecting an object is a server in that it defines the users and groups with access to the object. The application interacts with clients when they attempt to gain access to the object. Users and groups are identified by security identifiers (SIDs). An SID is a structure of variable length that uniquely identifies a user or group. SIDs are stored in a security database that an application can query by calling Win32 functions. With one exception, an SID is used to identify a user or group is never reassigned to another user or group. For a given account, the only SID that will not be the same from logon to logon is the logon-identifier SID. In the model represented by the preceding illustration, SIDs would be used to identify the following:

•	The owner and group in the security descriptor

•	The recipient of the access being granted by each ACE

•	The user and groups in the access token

Security descriptors, SIDs, and ACLs are treated by applications as opaque structures and are intended to be manipulated only by using Win32 functions. This helps ensure that these structures remain syntactically accurate and prevents future enhancements to the security system from breaking existing code.

Pointers to doubleword values or structures must be aligned on doubleword boundaries. However, the exception is strings, for which alignment is not critical. All Win32 memory-allocation functions return handles of doubleword-aligned memory objects.


  49.2.1  Access Tokens

When a user logs on, the system verifies the user's password by comparing it with information stored in a security database. If the password is authenticated, the system produces an access token and attaches it to the user's process. This access token identifies the user in all subsequent interactions with securable objects and contains the following information about a process:

•	The user's SID

•	Group SIDs

•	Privileges

•	An owner SID

•	The SID for the primary group

•	The default discretionary access-control list (ACL)

•	The source of the access token

•	Whether the token is a primary or impersonation token

•	Current impersonation levels

•	Other statistics

Every process must have an access token, but even a thread can have one assigned to it. When a thread has an access token, it supersedes the token of the process that owns the thread. This allows individual threads of a server process to impersonate clients by associating a client's access token with the thread. The only exception to this is any action requiring the SE_TCB_NAME privilege. This privilege is always checked against the process token, even if the current thread has an impersonation token.

For more information about privileges, see Section 49.2.7, »Privileges«. For more information about security identifiers (SIDs), see Section 49.2.6, »Security Identifiers (SIDs)«. For more information about discretionary ACLs, see Section 49.2.3, »Access-control Lists (ACLs)«. For more information about the components of an access token, see the following token structures and enumerated types in Microsoft Win32 Programmer's Reference, Volume 5.

Structure or type	Specifies
TOKEN_CONTROL	Information useful in identifying an access token.
TOKEN_DEFAULT_DACL	The default discretionary ACL for an access token.
TOKEN_GROUPS	Specifies the SIDs of the access token's groups and whether any privileges are enabled.
TOKEN_INFORMATION_CLASS	Information being set in or retrieved from an access token.
TOKEN_OWNER	The SID of an access token's owner.
TOKEN_PRIMARY_GROUP	The SID of the access token's primary group.
TOKEN_PRIVILEGES	The privileges associated with an access token and whether the privileges are enabled.
TOKEN_SOURCE	The source of an access token.
TOKEN_STATISTICS	Statistics associated with an access token.
TOKEN_TYPE	Whether an access token is being used as an impersonation token.
TOKEN_USER	The SID of an access token's user.
Following are the functions an application can use to manipulate access tokens.

Function	Description
AdjustTokenGroups	Changes the group information in an access token.
AdjustTokenPrivileges	Changes the privileges in an access token.
GetTokenInformation	Retrieves information about a token.
OpenProcessToken	Retrieves the handle of the access token for a process.
OpenThreadToken	Retrieves the handle of the access token for a thread.
SetTokenInformation	Changes a token's owner, primary group, or default discretionary ACL.


  49.2.2  Security Descriptors

A security descriptor contains the security information associated with an object. This information can include an owner, a primary group, a discretionary access-control list, and a system access-control list. This information is stored in the form of security identifiers (SIDs) and access-control lists (ACLs). For more information about access-control lists, see Section 49.2.3, »Access-control Lists (ACLs)«.

There are five groups of Windows functions that manipulate security descriptors, corresponding to five different kinds of objects:

•	Files

•	User Objects (also called window-management objects)

•	Kernel objects

•	Registry objects

•	Private objects

To manipulate security descriptors for files and directories, an application can use the GetFileSecurity and SetFileSecurity functions. These functions identify files and directories by using character strings, instead of using the handles required by other security functions.

Kernel objects and user objects are manipulated by two pairs of functions: GetKernelObjectSecurity and SetKernelObjectSecurity, and GetUserObjectSecurity and SetUserObjectSecurity. Kernel and user objects are separated in this way because it is possible for a file handle and a window handle to have the same value. An application can use these functions to ensure that the correct object referenced.

An application can use the RegGetKeySecurity and RegSetKeySecurity functions to retrieve and set security descriptors for keys in the registry.

The functions that manipulate private objects allow an application, usually a server, to associate a security descriptor with its own object type. The functions provide the ability to retrieve default information from an access token, support inheritance, and manipulate specific parts of the security descriptor. These functions are CreatePrivateObjectSecurity, GetPrivateObjectSecurity, SetPrivateObjectSecurity, and DestroyPrivateObjectSecurity.

The Windows functions in the following table enable an application to query a security descriptor or set specific information in it.

Function	Description
GetSecurityDescriptorControl	Retrieves revision and control information.
GetSecurityDescriptorDacl	Retrieves the discretionary ACL.
GetSecurityDescriptorGroup	Retrieves primary group information.
GetSecurityDescriptorLength	Returns the length of a security descriptor.
GetSecurityDescriptorOwner	Retrieves the owner of a security descriptor.
GetSecurityDescriptorSacl	Retrieves the system ACL.
SetSecurityDescriptorDacl	Sets discretionary ACL information.
SetSecurityDescriptorGroup	Sets primary group information.
SetSecurityDescriptorOwner	Sets the owner of the security descriptor.
SetSecurityDescriptorSacl	Sets system ACL information.
To check the revision level and structural integrity of a security descriptor, an application can call the IsValidSecurityDescriptor function.

A security descriptor can be in either an absolute or self-relative format. In absolute format, a security descriptor contains pointers to its information, not the information itself. This format is useful when default settings for the owner, group, and discretionary ACL are available, because an application can simply call the InitializeSecurityDescriptor function to initialize a SECURITY_DESCRIPTOR structure and then point to preexisting components, such as SIDs and ACLs.

A security descriptor in self-relative format contains information in a contiguous block of memory. In this format, a SECURITY_DESCRIPTOR structure always starts the information, but the other components of the security descriptor can follow the structure in any order. Instead of using memory addresses, the security descriptor's components are identified by offsets from the beginning of the descriptor. This format is useful when a security descriptor must be stored on disk, transmitted by means of a communications protocol, or copied in memory.

All security descriptors provided by the operating system as the result of calls to Win32 API functions are in self-relative format. Security descriptors passed back to the operating system can be in either form, depending on the situation.

A server that copies secured objects to various media can use the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor. The MakeAbsoluteSD function can create an absolute security descriptor from a self-relative security descriptor.


  49.2.3  Access-control Lists (ACLs)

Part of the security descriptor for each securable object is a list specifying users and groups, and the access to the object each is granted or denied. This list is an access-control list (ACL). An ACL consists of two parts. The first is a header in the form of an ACL structure. This structure contains information pertaining to the entire ACL, such as its revision level and size. The second part is an ordered list of access-control entries (ACEs). Each ACE identifies a user, group, or local group, and the access each of them is allowed.

There are two types of ACLs: discretionary and system.

A discretionary ACL is controlled by the owner of an object and specifies the access particular users or groups can have to an object. For example, the owner of a file can use a discretionary ACL to control who can and cannot have access to the file.

When an object's discretionary ACL contains no access-control entries, no access rights have been explicitly granted. Therefore, access to the object is implicitly denied. However, when an object has no discretionary ACL, no protection is assigned to the object and any access request is granted. For information about setting no ACL for an object, see Section 49.4.2, »Allowing Access«.

An object may also have system-level security information associated with it, in the form of a system ACL. System ACLs are controlled by system administrators. A system ACL can enable the system administrator to audit any attempts to gain access to an object. In future releases, a system ACL will also be able to raise an alarm when an unauthorized user attempts to gain access to an object.

An application can use Win32 functions to retrieve, initialize, query, and modify ACLs.

Function	Description
GetAclInformation	Retrieves revision or size information about an ACL.
GetSecurityDescriptorDacl	Retrieves a discretionary ACL from a specified security descriptor.
GetSecurityDescriptorSacl	Retrieves a system ACL from a specified security descriptor.
InitializeAcl	Initializes an ACL by creating an empty ACL structure.
IsValidAcl	Determines whether an ACL's revision level and structure are valid.
SetAclInformation	Changes the revision information in an ACL.
SetSecurityDescriptorDacl	Puts a discretionary ACL into a specified security descriptor, superseding any preexisting discretionary ACL.
SetSecurityDescriptorSacl	Puts a system access-control list into a specified security descriptor, superseding any preexisting system ACL.
To change a security descriptor's ACL, an application generally initializes a new ACL, adds ACEs to it, then uses either the SetSecurityDescriptorDacl or SetSecurityDescriptorSacl function to add the new ACL to the security descriptor. GetSecurityDescriptorDacl and GetSecurityDescriptorSacl retrieve a pointer to a preexisting ACL in a security descriptor so an application can copy information from the previous ACL as it creates a new one.


  49.2.4  Access-control Entries (ACEs)

Each of the entries in an access-control list (ACL) is an access-control entry (ACE). Each ACE consists of three parts:

•	A header in the form of an ACE_HEADER structure

•	An access mask for the specified ACE type

•	A security identifier (SID)

The ACE_HEADER structure gives information such as the type of the ACE and its size. The access mask is a 32-bit value that specifies the rights being granted, denied, or monitored. The security identifier is in the form of an SID structure and it specifies the user or group to which the ACE applies.

Discretionary ACLs have two types of ACE defined in the AceType member of the ACE_HEADER structure. They are shown in the following table.

Type	Description
ACCESS_ALLOWED_ACE_TYPE	This ACE grants the specified rights to the user or group identified by the security identifier. It is defined by an ACCESS_ALLOWED_ACE structure.
ACCESS_DENIED_ACE_TYPE	This ACE denies the specified rights to the user or group identified by the security identifier. It is defined by an ACCESS_DENIED_ACE structure.
Only one type of ACE, SYSTEM-AUDIT-ACE-TYPE, is currently supported for system ACLs. It specifies what types of access cause system-level audits. This ACE is defined by a SYSTEM_AUDIT_ACE structure.

The SYSTEM_ALARM_ACE_TYPE is not supported in the current version of Windows NT.

Security auditing is used to keep a log of security-significant events, such as which users access a secured file. The SYSTEM_AUDIT_ACE_TYPE ACE is used to generate security audit messages and causes them to be entered into a system audit log for later processing. An administrator can view this log by using Event Viewer (EVENTVWR.EXE) and can manipulate the log by using the event-logging functions. For more information about event logging, see Chapter 65, »Event Logging«.

The order of ACEs in an ACL is important. An access token is checked against the ACEs in an ACL until it either accumulates the access rights it needs, it is explicitly denied access in an access-denied ACE, or it reaches the end of the ACL and is implicitly denied access. If a user is a member of several groups represented by ACEs in the ACL, the rights granted to each group apply to the user. For example, a user may request read and write access to an object protected by an ACE that grants one group read access only. Another ACE may provide protection that grants write access. If the user belongs to both groups, the request will succeed. An ACL typically denies access to specific users or groups of users and allows access to more general categories of users. Although the ACEs in an ACL can be in any order, the security menu items in File Manager and Registry Editor (RGEDT32.EXE) only work with ACLs in which access-denied ACEs precede access-allowed ACEs.

To change a security descriptor's ACL, an application usually initializes a new ACL, adds ACEs to it, and then adds the ACL to the security descriptor. The AddAccessAllowedAce and AddAccessDeniedAce functions add an ACE at the end of a discretionary ACL. The AddAuditAccessAce function adds an ACE at the end of a system ACL. The AddAce function allows an application to specify the position of a new ACE in an ACL, and the DeleteAce function allows an application to remove an ACE from a specified position in one. The GetAce and FindFirstFreeAce functions are especially useful when copying information from a preexisting ACL to a new one.


  49.2.5  Access Masks and Access Rights

An access right defines a particular set of abilities that can be granted or denied to a process when it attempts to use an object. For example, if an application attempts to create a subkey in the registry but does not have the KEY_CREATE_SUB_KEY access right, the system does not carry out the operation. An application usually requests a set of access rights when it opens an object, and in the case of registry keys, it makes that request when it calls the RegOpenKeyEx function.

An access mask is the component of an access-control entry (ACE) that contains the specific rights, standard rights, and generic rights defining the access a user or group has to an object. Access masks are also used to request access rights when an object is opened. For example, an application that needs to set values, create subkeys, and query values in the registry can open a key using an access mask that combines the KEY_WRITE and KEY_QUERY_VALUE access rights.

An access mask is a single 32-bit value. The first 16 bits are the specific rights and apply only to the object type associated with the access mask. Bits 16 through 23 are the standard rights applying to all objects. Bits 28 through 31 are the generic rights mapped to specific and standard rights when access to an object is requested.

Generic access rights are broad types of access whose exact implementation is determined by the application defining an object. These rights are used when protecting an object. For example, an application that defines a voice-annotation object might define specific access rights by using VOICE_PLAY and VOICE_EDIT for playing and editing the object. It might set up a GENERIC_MAPPING structure in which GENERIC_EXECUTE maps to VOICE_PLAY and GENERIC_WRITE maps to both VOICE_PLAY and VOICE_EDIT.

The following are the generic rights that have been defined.

Constant	Meaning
GENERIC_ALL	Read, write, and execute access
GENERIC_EXECUTE	Execute access
GENERIC_READ	Read access
GENERIC_WRITE	Write access
If an application receives GENERIC_WRITE access to a file, for example, it has specific rights allowing it to write and append data to the file, write file attributes, and write extended attributes. In addition, the application has the STANDARD_RIGHTS_WRITE and SYNCHRONIZE standard access rights.

The following constants are masks for the standard access rights.

Constant	Meaning
DELETE	Delete access.
READ_CONTROL	Read access to the security descriptor not including the system ACL.
STANDARD_RIGHTS_ALL	Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and SYNCHRONIZE access.
STANDARD_RIGHTS_EXECUTE	Currently defined to equal READ_CONTROL.
STANDARD_RIGHTS_READ	Currently defined to equal READ_CONTROL.
STANDARD_RIGHTS_REQUIRED	Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access.
STANDARD_RIGHTS_WRITE	Currently defined to equal READ_CONTROL.
SYNCHRONIZE	Synchronize access. Allows a thread to wait for the object. This access type is not supported by all object types.
WRITE_DAC	Write access to the discretionary ACL.
WRITE_OWNER	Write access to the owner.
The SPECIFIC_RIGHTS_ALL constant denotes all of the specific rights, even those not be defined for an object.

The system validates each requested access against the process's access token, so requests for broad access can require a great deal of validation time. Therefore, it is generally better for applications to avoid requesting the broadest possible access to an object except when such access is actually required. Certain rights are commonly used in an ACL to deny access to an object, but they are rarely used in requests to open an object. In particular, requesting any of the access rights in the following list has a negative impact on system performance:

EVENT_ALL_ACCESS	SECTION_ALL_ACCESS
FILE_MAP_ALL_ACCESS	SEMAPHORE_ALL_ACCESS
GENERIC_ALL	SERVICE_ALL_ACCESS
KEY_ALL_ACCESS	SPECIFIC_RIGHTS_ALL
MUTEX_ALL_ACCESS	STANDARD_RIGHTS_ALL
PROCESS_ALL_ACCESS	THREAD_ALL_ACCESS
SC_MANAGER_ALL_ACCESS	TOKEN_ALL_ACCESS
The MAXIMUM_ALLOWED constant specifies that an object is to be opened by using all the access rights that are valid for the given user. An additional access type, ACCESS_SYSTEM_SECURITY, is needed to manipulate an object's system ACL. Neither MAXIMUM_ALLOWED nor ACCESS_SYSTEM_SECURITY can be used in an ACL.

The MapGenericMask function maps a series of generic rights specified in a GENERIC_MAPPING structure to specific and standard rights in an access mask. An application can use the GENERIC_MAPPING structure to specify the access rights for an object when it is created. When a client process requests access to the object, the server can use MapGenericMask to translate the client's requested access into the standard and specific rights for that object.

To discover whether a client process has the proper access rights to an object, a server can call the AccessCheck or AccessCheckAndAuditAlarm function. The AreAllAccessesGranted and AreAnyAccessesGranted functions compare a requested access mask with a granted access mask.


  49.2.6  Security Identifiers (SIDs)

A security identifier (SID) is a unique value of variable length used to identify a user or group. The SID assigned to a user when he or she logs on becomes part of the access token that accompanies any process begun by that user. Except for the logon SID, an SID is always unique. When it has been used to identify a user or group, it cannot be used again, at any time, to identify another user or group.

SIDs identify several separate elements. These include the owner and group in security descriptors, the recipient of the access being granted by access-control entries (ACEs), and the user, as well as groups of which the user is a member in access tokens.

An SID also contains the following information.

•	A 48-bit identifier authority value

•	A revision level

•	A variable number of subauthority values (relative identifiers)

The identifier authority value actually contains two values and is the most important piece of information in an SID. It contains a value identifying the agency that issued the SID, usually representing a Microsoft® Advanced Server (™)  domain, and a 32-bit relative identifier (RID) value, to uniquely identify the user or group in that agency. Joining these values ensures that no two SIDs will be the same, even if two different SID-issuing authorities issue the same RID. Each SID-issuing authority issues a given RID only once.

A standardized shorthand notation for SIDs makes it simpler to visualize their components:

S-R-I-S-S...

In the notation shown above, S identifies the series of digits as an SID, R is the revision level, I is the identifier-authority value, and S is the subauthority value. An SID could be written in this notation as follows:

S-1−4138−86

In this example, the SID has a revision level of 1, an identifier-authority value of 4138, and one subauthority value of 86.

An application is never required to manipulate an SID directly. The following Win32 functions provide all the functionality required to work with SIDs.

Function	Description
AllocateAndInitializeSid	Allocates and initializes an SID with the specified number of subauthorities.
CopySid	Copies a source SID to a buffer.
EqualPrefixSid	Tests two SID prefix values for equality. An SID prefix is the entire SID except for the last subauthority value.
EqualSid	Tests two SIDs for equality. They must match exactly to be considered equal.
FreeSid	Frees an SID previously allocated by using the AllocateAndInitializeSid function.
GetLengthSid	Retrieves the length of an SID.
GetSidIdentifierAuthority	Retrieves a pointer to an SID's identifier authority.
GetSidLengthRequired	Retrieves the size of the buffer required to store an SID with a specified number of subauthorities.
GetSidSubAuthority	Retrieves a pointer to a specified subauthority in an SID.
GetSidSubAuthorityCount	Retrieves the number of subauthorities in an SID.
InitializeSid	Initializes an SID structure.
IsValidSid	Tests the validity of an SID by verifying that the revision number is within a known range and that the number of subauthorities is less than the maximum.
LookupAccountName	Retrieves the SID corresponding to a specified account name. Use the GetUserName function to retrieve the user name for the current thread.
LookupAccountSid	Retrieves the account name corresponding to a specified SID.
Some identifier authorities are predefined, as shown in the following table.

Identifier authority	SID Value
SECURITY_NULL_SID_AUTHORITY	0
SECURITY_WORLD_SID_AUTHORITY	1
SECURITY_LOCAL_SID_AUTHORITY	2
SECURITY_CREATOR_SID_AUTHORITY	3
SECURITY_NT_AUTHORITY	5
The following RID values are also defined.

Relative identifier authority	Value	Superior authority
SECURITY_NULL_RID	0	S-1−0
SECURITY_WORLD_RID	0	S-1−1
SECURITY_LOCAL_RID	0	S-1−2
SECURITY_CREATOR_OWNER_RID	0	S-1−3
SECURITY_CREATOR_GROUP_RID	1	S-1−3
An application can combine an identifier authority and one of these RID values to create an SID that is meaningful on all installations. For example, S-1−1−0 (SECURITY_WORLD_SID_AUTHORITY and SECURITY_WORLD_RID) always identifies the special group representing all users. These security identifiers are universal well-known SIDs. A universal well-known SID is meaningful on all secure systems using this security model, including systems not running Windows NT. The AllocateAndInitializeSid function provides a simple method of combining an identifier authority and an RID.

The following are some universal well-known SIDs.

Universal well-known SID	Value	Identifies
Null SID	(S-1−0−0)	A group with no members. This is often used when an SID value is not known.
World	(S-1−1−0)	A group that includes all users.
Local	(S-1−2−0)	Users who log on to terminals locally (physically) connected to the system.
Creator Owner ID	(S-1−3−0)	A security identifier to be replaced by the security identifier of the user who created a new object. This SID is used in inheritable ACLs.
Creator Group ID	(S-1−3−1)	Identifies a security identifier to be replaced by the primary-group SID of the user who created a new object. Use this SID in inheritable ACLs.
Another predefined identifier authority is SECURITY_NT_AUTHORITY (S-1−5). This identifier authority produces SIDs that are not universal but are meaningful only on Windows NT installations. An application can use the following RID values with SECURITY_NT_AUTHORITY to create well-known SIDs.

Constant	Identifies
SECURITY_DIALUP_RID (S-1−5−1)
	Users who log on to terminals using a dialup modem. This is a group identifier.
SECURITY_NETWORK_RID (S-1−5−2)
	Users who log on across a network. This is a group identifier.
SECURITY_BATCH_RID (S-1−5−3)
	Users who log on using a batch queue facility. This is a group identifier.
SECURITY_INTERACTIVE_RID (S-1−5−4)
	Users who log on for interactive operation. This is a group identifier.
SECURITY_LOGON_IDS_RID (S-1−5−5-X-Y)
	A logon session. This is used to ensure that only processes in a given logon session can gain access to the window-station objects for that session. The X and Y values for these SIDs are different for each logon session. The value SECURITY_LOGON_IDS_RID_COUNT is the number of RIDs in this identifier (5-X-Y).
SECURITY_SERVICE_RID (S-1−5−6)
	An account authorized to perform security services.
SECURITY_LOCAL_SYSTEM_RID
	(S-1−5−0x12) The user account used by the operating system.
SECURITY_BUILTIN_DOMAIN_RID (S-1−5−0x20)
	The built-in system domain.
The following RIDs are relative to each domain.

RID	Identifies
DOMAIN_USER_RID_ADMIN	The administrative user account in a domain.
DOMAIN_USER_RID_GUEST	The guest-user account in a domain. This account can be logged onto automatically by users who do not have an account.
DOMAIN_GROUP_RID_ADMINS	The domain administrator's group. This account exists only on systems running Microsoft Windows NT Advanced Server, not Windows NT systems.
DOMAIN_GROUP_RID_USERS	A group containing all user accounts in a domain. All users are automatically added to this group.
An alias is a local group and is similar to a global group, but it can contain members from other domains. Its members can be users or other groups. Some domain-relative RIDs, such as the following, can be used to form well-known SIDs used as local groups.

RID	Identifies
DOMAIN_ALIAS_RID_ADMINS
	A local group used for administration of the domain.
DOMAIN_ALIAS_RID_USERS
	A local group representing all users in the domain.
DOMAIN_ALIAS_RID_GUESTS
	A local group representing guests of the domain.
DOMAIN_ALIAS_RID_POWER_USERS
	A local group used to represent a user or set of users that expect to treat a system as if it were their personal computer rather than a multiuser workstation.
DOMAIN_ALIAS_RID_ACCOUNT_OPS
	A local group existing only on systems running Microsoft Windows NT Advanced Server. This local group permits control over non-administrator accounts.
DOMAIN_ALIAS_RID_SYSTEM_OPS
	A local group existing only on systems running Microsoft Windows NT Advanced Server. This local group performs system administrative functions, not including security functions. It establishes network shares, controls printers, unlocks workstations, and performs other operations.
DOMAIN_ALIAS_RID_PRINT_OPS
	A local group existing only on systems running Microsoft Windows NT Advanced Server. This local group controls printers and print queues.
DOMAIN_ALIAS_RID_BACKUP_OPS
	A local group used for controlling assignment of file backup-and-restore privileges.
DOMAIN_ALIAS_RID_REPLICATOR
	A local group responsible for copying security databases from the primary domain controller to the backup domain controllers.


  49.2.7  Privileges

A privilege is used to control access to an object or service more strictly than is normal with discretionary access control. A system manager uses privileges to control which users are able to manipulate system resources. An application uses privileges when it changes a system resource, such as when it changes the system time or shuts down the system.

A privilege is a locally unique identifier (LUID) identified by a character string. This 64-bit value is guaranteed to be unique on the operating system that generated it until the system is restarted. For example, SE_SYSTEMTIME_NAME is a string identifying an LUID. A privilege has three representations, as shown below.

•	A string name, meaningful across systems, called a global program name (for example, SE_SYSTEMTIME_NAME).

•	A readable name that can be displayed to the user when necessary. For example, "Change the system time."

•	A local representation that differs from computer to computer.

Privileges provide access to services rarely needed by most users. An account usually has privileges that are disabled, and they must be enabled to be used. For example, to set the time on the local computer, an application has to set the SE_PRIVILEGE_ENABLED attribute for the SE_SYSTEMTIME_NAME privilege. For security reasons, disable an enabled privilege when it is no longer needed.

The following privileges are defined by Windows NT.

Privilege	Description
SE_ASSIGNPRIMARYTOKEN_NAME	Required to assign the primary token of a process.
SE_AUDIT_NAME	Required to generate audit-log entries. Give this privilege to secure servers.
SE_BACKUP_NAME	Required to perform backup operations.
SE_CHANGE_NOTIFY_NAME	Required to receive notifications of changes to files or directories. This privilege also causes the system to skip all traversal access checks. It is enabled by default for all users.
SE_CREATE_PAGEFILE_NAME	Required to create a paging file.
SE_CREATE_PERMANENT_NAME	Required to create a permanent object.
SE_CREATE_TOKEN_NAME	Required to create a primary token.
SE_DEBUG_NAME	Required to debug a process.
SE_INC_BASE_PRIORITY_NAME	Required to increase the base priority of a process.
SE_INCREASE_QUOTA_NAME	Required to increase the quota assigned to a process.
SE_LOAD_DRIVER_NAME	Required to load or unload a device driver.
SE_LOCK_MEMORY_NAME	Required to lock physical pages in memory.
SE_PROF_SINGLE_PROCESS_NAME	Required to gather profiling information for a single process.
SE_REMOTE_SHUTDOWN_NAME	Required to shut down a system using a network request.
SE_RESTORE_NAME	Required to perform restore operations.
SE_SECURITY_NAME	Required to perform a number of security-related functions, such as controlling and viewing audit messages. This privilege identifies its holder as a security operator.
SE_SHUTDOWN_NAME	Required to shut down a local system.
SE_SYSTEM_ENVIRONMENT_NAME	Required to modify the non-volatile RAM of systems that use this type of memory to store configuration information.
SE_SYSTEM_PROFILE_NAME	Required to gather profiling information for the entire system.
SE_SYSTEMTIME_NAME	Required to modify the system time.
SE_TAKE_OWNERSHIP_NAME	Required to take ownership of an object without being granted discretionary access. This privilege allows the owner value to be set only to those values that the holder may legitimately assign as the owner of an object.
SE_TCB_NAME	This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege.
SE_UNSOLICITED_INPUT_NAME	Required to read unsolicited input from a terminal device.
The following functions are provided for working with privileges.

Function	Description
LookupPrivilegeValue	Allows an application to retrieve the LUID corresponding to a privilege on the local system. This is the local representation of that privilege and an application can set it in the TOKEN_PRIVILEGES and LUID_AND_ATTRIBUTES structures.
LookupPrivilegeDisplayName	Retrieves a displayable privilege name. For example, "Force shutdown from a remote system."
LookupPrivilegeName	Retrieves a programmatic privilege name.
PrivilegeCheck	Determines whether a client application has the privileges required to gain access to an object, such as, SE_REMOTE_SHUTDOWN_NAME.


  49.2.8  Impersonation

Impersonation is the ability of a process to take on the security attributes of another process. Typically, a server thread impersonates a client thread to act on behalf of that client to access objects or validate access to its own objects. For example, when a client in a DDE conversation requests information from a DDE server, the server can impersonate the client so the system can verify that the client is allowed access to the information.

Currently, there are three impersonation levels:

Impersonation Level	Meaning
SecurityAnonymous	Indicates the client does not want the server to obtain identification information about the client.
SecurityIdentification	Allows the server to obtain information about the client, such as security identifiers and privileges, without being able to impersonate the client. This is useful for servers who export their own objects, such as tables and views exported by a database product. Using the retrieved client security information, the server is able to make access-validation decisions for itself even though it is unable to use other services as the client.
SecurityImpersonation	Allows the server to impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.
A fourth level, SecurityDelegation, is not supported in this release of Windows NT.

A DDE server application can impersonate a client by calling the DdeImpersonateClient function. When it has finished the task requiring the impersonation, the DDE server application can revert to its own security information by calling the RevertToSelf function. Similarly, a named-pipe server can use the ImpersonateNamedPipeClient and RevertToSelf functions. The DuplicateToken function creates an impersonation token that duplicates an existing token.

The ImpersonateSelf function enables a thread to generate a copy of its own access token. This is useful when an application needs to change the security attributes of a single thread. For example, sometimes only one thread of a process requires a special privilege.


  49.2.9  Security in New Objects

When an application creates an object, any values explicitly provided in a security descriptor are assigned to the object. If a security descriptor is not explicitly provided, the system searches for security information in different places, depending on the information required.

This section describes the algorithms for security attribute assignments to newly created objects.


  49.2.9.1  Assignment of Owner

To assign an owner to a new object when a security descriptor is not provided, the system checks the creator's access token for a default value. If no default value is found, the creator's user identifier (from the access token) is assigned as the object's owner. Even when an owner is provided in a security descriptor, the system checks these values in the access token to make sure the specified owner can be assigned ownership of the object.


  49.2.9.2  Assignment of Group

To assign a primary group to a new object when a security descriptor is not provided, the system uses the primary group in the creator's access token.


  49.2.9.3  Assignment of Discretionary ACL

To assign a discretionary access-control list (ACL) to a new object when a security descriptor is not provided, the system checks the parent's discretionary ACL for inheritable access-control entries (ACEs) and creates an ACL from any it finds. If there are no inheritable ACEs, the system checks the creator's security descriptor for a default discretionary ACL. If none is found in the security descriptor, the system looks in the creator's access token. If none of these sources provides a discretionary ACL, the object is created without one, and universal unconditional access to the object is granted.


  49.2.9.4  Assignment of System ACL

To assign a system ACL to a new object when a security descriptor is not provided, the system checks the parent's system ACL for inheritable ACEs and creates an ACL from any it finds. If there are no inheritable ACEs, the system checks the creator's security descriptor for a default system ACL. When a system ACL is provided explicitly or by default in a security descriptor, the creator of the object must have the SE_SECURITY_NAME privilege, although this privilege is not required if the system ACL is acquired by inheritance. If none of these sources provides a system ACL, the object is created without one.


  49.2.10  Inheritance

The security attributes of an object can be passed from process to process through the mechanism of handle inheritance. In addition, individual ACEs in an ACL can be inherited by new objects. This section discusses these two inheritance mechanisms.


  49.2.10.1  Handle Inheritance

If a new process inherits a handle, it also inherits the security attributes associated with that handle. A pointer to a SECURITY_ATTRIBUTES structure is used as a parameter in most Win32 kernel and window-management functions that return object handles. The bInheritHandle member of this structure specifies whether the returned handle is inherited when a new process is created. The security attributes of the inherited handle are identical to those of the original handle.


  49.2.10.2  ACE Inheritance

Each ACE in an ACL begins with an ACE_HEADER structure specifying how that ACE is inherited. Among other things, the flags in an ACE_HEADER structure specify whether the ACE is inherited by container objects (directories or registry keys) or by non-container objects, such as files.


  ACE Inheritance in Container Objects

This section outlines the rules governing the inheritance of ACEs by container objects.

If the CONTAINER_INHERIT_ACE flag is set in the ACE_HEADER structure of the parent ACE, a copy of the ACE is added to the end of the inherited ACL and the following actions are performed on the inherited ACE:

•	All inheritance flags in the inherited ACE are cleared.

•	If the ACE contains an access mask and any generic access flags are set, the generic rights are mapped to the standard and specific rights for the child object type.

If neither the CONTAINER_INHERIT_ACE flag nor the NO_PROPAGATE_INHERIT_ACE flag is set, the OBJECT_INHERIT_ACE and INHERIT_ONLY_ACE flags are set. If both the CONTAINER_INHERIT_ACE and the NO_PROPAGATE_INHERIT_ACE are set, the ACE is added to the end of the inherited ACL.

If neither the NO_PROPAGATE_INHERIT_ACE nor the CONTAINER_INHERIT_ACE flag is set in the ACE_HEADER structure of the parent ACE, a copy of the ACE is added to the end of the inherited ACL and its INHERIT_ONLY_ACE flag is set.

Otherwise, the ACE is not inherited.


  ACE Inheritance in Non-container Objects

The following rules govern the inheritance of ACEs in objects other than containers.

If the OBJECT_INHERIT_ACE flag is set in the ACE_HEADER structure of the parent ACE, the ACE is copied to the end of the inherited ACL and:

•	The INHERIT_ONLY_ACE flag in the inherited ACE is cleared.

•	The NO_PROPAGATE_INHERIT_ACE, OBJECT_INHERIT_ACE, and CONTAINER_INHERIT_ACE flags in the inherited ACE are cleared.

•	If the ACE contains an access mask and, if any generic access flags are set, the generic rights are mapped to the standard and specific rights for the child object type.

Otherwise, the ACE is not inherited.


  49.2.10.3  Duplicating Handles

Among cooperating processes, any one process is only as restricted as the least restricted process. For example, a process can call the DuplicateHandle function to duplicate an object handle belonging to a second (source) process into a third (target) process. If the access rights requested for the target process are greater than the rights held by the source process, the system checks the requested access rights against the security context of the process calling DuplicateHandle. If the calling process has the required access rights, the handle is duplicated, and the target process has greater access to the object than the source process.


  49.2.11  Audit Generation

C2-level security requirements specify that system administrators must be able to audit security-related events and that access to this audit data must be limited to authorized administrators. The Win32 API provides functions enabling an administrator to monitor security-related events.

The system access-control list (ACL) contains audit access-control entries (ACEs) for an object. An application can use the GetSecurityDescriptorSacl and SetSecurityDescriptorSacl functions to retrieve an existing system ACL or to set a new one. The AddAuditAccessAce function adds an ACE to a system ACL that causes the system to record specified access attempts in a security log. This security log can be read by using the Microsoft Windows Event Viewer (EVENTVWR.EXE), and can be manipulated by using the event-logging functions discussed in Chapter 65, .»Event Logging«. For more information about system ACLs, see Section 49.2.3, »Access-control Lists (ACLs)«.

An application can use the ObjectPrivilegeAuditAlarm function to generate audit and alarm messages whenever a process attempts to complete a privileged operation. The PrivilegedServiceAuditAlarm generates audit and alarm messages whenever a process attempts to perform a privileged system-service operation.

The ObjectCloseAuditAlarm generates audit messages when an object is deleted. The ObjectOpenAuditAlarm function generates audit messages when a process attempts to open or gain access to an object.


  49.3  Securable Objects

The kernel and window-management systems contain securable objects. This term refers to an object that has a security descriptor.

All named objects are securable. Some unnamed objects, such as unnamed process and thread objects, have security descriptors also.

You can use Win32 functions to query and set the security attributes of securable objects. The following are types of securable objects and the functions an application can use to manipulate their security attributes.

Object type	Functions
Files and directories	GetFileSecurity, SetFileSecurity
Mailslots	GetFileSecurity, SetFileSecurity
Pipes	GetFileSecurity, SetFileSecurity
Kernel objects (processes, threads, access tokens, and file-mapping objects)	SetKernelObjectSecurity, GetKernelObjectSecurity
Window-management objects (window stations, desktops, windows, and menus)	GetUserObjectSecurity, SetUserObjectSecurity
Registry objects	RegGetKeySecurity, RegSetKeySecurity
Service objects	QueryServiceObjectSecurity, SetServiceObjectSecurity
Synchronization objects	SetKernelObjectSecurity, GetKernelObjectSecurity
Private objects (objects private to the creating application)	CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GetPrivateObjectSecurity, SetPrivateObjectSecurity
The following sections discuss the security attributes of these types of securable objects.


  49.3.1  File and Directory Objects

File and directory objects can be secured only when the New Technology file system (NTFS) is in use.

The access rights for files and directories must be manipulated by using the generic access rights.

For file objects, the handle returned by the CreateFile function has SYNCHRONIZE access and the right to read file attributes, in addition to the access rights specified in the call (GENERIC_READ, GENERIC_WRITE, or both).

GENERIC_READ access for file objects combines STANDARD_RIGHTS_READ and SYNCHRONIZE with rights that allow the process to read data from the file, read file attributes, and read extended attributes.

GENERIC_WRITE access for file objects combines STANDARD_RIGHTS_WRITE and SYNCHRONIZE with rights that allow the process to write data to the file, append data to it, write file attributes, and write extended attributes.

An application cannot use an access-denied ACE to deny only GENERIC_READ or GENERIC_WRITE access to a file. If an application denies GENERIC_WRITE access to a file, SYNCHRONIZE access is implicitly denied. When the CreateFile function is used in an attempt to open the file for read access, the function requests SYNCHRONIZE access and the operation fails. Instead of denying read or write access to a file, an application can explicitly allow the permitted access rights.

For directory objects, the handle returned by the CreateDirectory function has SYNCHRONIZE access and the right to list the contents of the directory.

For more information about files and directories, see Chapter 45, »Files«.


  49.3.2  Mailslot Objects

The handle returned by the CreateMailslot function has GENERIC_READ, SYNCHRONIZE, and WRITE_DAC access to the mailslot object.

GENERIC_READ access for a mailslot combines STANDARD_RIGHTS_READ with rights allowing the process to read data from the mailslot, read mailslot attributes, and read extended attributes.

For more information about mailslots, see Chapter 55, »Mailslots«.


  49.3.3  Pipe Objects

The security attributes of named pipes differ slightly from those of anonymous pipes.


  49.3.3.1  Named Pipes

The handle returned by the CreateNamedPipe function always has SYNCHRONIZE access. It also has GENERIC_READ, GENERIC_WRITE, or both, depending on the open mode of the pipe. The following are the access rights for each open mode.

Open mode	Access rights
PIPE_ACCESS_DUPLEX	GENERIC_READ, GENERIC_WRITE, and SYNCHRONIZE
PIPE_ACCESS_INBOUND	GENERIC_READ and SYNCHRONIZE
PIPE_ACCESS_OUTBOUND	GENERIC_WRITE  and SYNCHRONIZE
GENERIC_READ access for a named pipe combines STANDARD_RIGHTS_READ access with rights that allow the process to read data from the named pipe and to read named-pipe attributes.

GENERIC_WRITE access for a named pipe combines STANDARD_RIGHTS_WRITE with rights that allow the process to write data to the named pipe and to write named-pipe attributes.


  49.3.3.2  Anonymous Pipes

The handles returned by the CreatePipe function have GENERIC_READ, GENERIC_WRITE, and SYNCHRONIZE access to the anonymous pipe, in addition to the right to write the attributes of the pipe. GENERIC_READ and GENERIC_WRITE access map to the same access rights as for named pipes.

For more information about pipes, see Chapter 54, »Pipes«.


  49.3.4  Kernel Objects

The following are the kernel objects for which the system defines special access rights:

•	Processes

•	Threads

•	Access tokens

•	File mapping


  49.3.4.1  Process Objects

The valid access rights for process objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
PROCESS_ALL_ACCESS	Specifies all possible access rights for a process object.
PROCESS_CREATE_PROCESS	Required to create a process.
PROCESS_CREATE_THREAD	Required to create a thread.
PROCESS_DUP_HANDLE	Required to duplicate a handle.
PROCESS_QUERY_INFORMATION	Required to retrieve certain information about a process, such as its priority class.
PROCESS_SET_INFORMATION	Required to set certain information about a process, such as its priority class.
PROCESS_TERMINATE	Required to terminate a process.
PROCESS_VM_OPERATION	Required to perform an operation on the address space of a process.
PROCESS_VM_READ	Required to read memory in a process.
PROCESS_VM_WRITE	Required to write to memory in a process.
SYNCHRONIZE	Required to wait for the process to terminate.
The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object.

For more information about processes, see Chapter 43, »Processes and Threads«.


  49.3.4.2  Thread Objects

The valid access rights for thread objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
SYNCHRONIZE	Required to wait for the thread to exit.
THREAD_ALL_ACCESS	Specifies all possible access rights for a thread object. A thread created with THREAD_ALL_ACCESS access is created with its execution suspended.
THREAD_DIRECT_IMPERSONATION	Required for a server thread that impersonates a client.
THREAD_GET_CONTEXT	Required to read the context of a thread using GetThreadContext.
THREAD_IMPERSONATE	Required to use a thread's security information directly without calling it by using a communication mechanism that provides impersonation services.
THREAD_QUERY_INFORMATION	Required to read certain information from the thread object.
THREAD_SET_CONTEXT	Required to write the context of a thread.
THREAD_SET_INFORMATION	Required to set certain information in the thread object.
THREAD_SET_THREAD_TOKEN	Required to set the impersonation token for a thread.
THREAD_SUSPEND_RESUME	Required to suspend or resume a thread.
THREAD_TERMINATE	Required to terminate a thread.
The handle returned by the CreateThread function has THREAD_ALL_ACCESS access to the thread object.

For more information about threads, see Chapter 43, »Processes and Threads«.


  49.3.4.3  Access-token Objects

A process or thread cannot wait on an access-token object because the access-token object type does not support the SYNCHRONIZE standard access type.

The access rights defined for access-token objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
TOKEN_ADJUST_DEFAULT	Required to adjust default information, such as the owner, primary group, and default ACL in an access token.
TOKEN_ADJUST_GROUPS	Required to adjust the groups in an access token.
TOKEN_ADJUST_PRIVILEGES	Required to adjust the privileges in an access token.
TOKEN_ASSIGN_PRIMARY	Required to attach a primary token to a process. The SE_CREATE_TOKEN_NAME privilege is also required to accomplish this task.
TOKEN_DUPLICATE	Required to duplicate an access token.
TOKEN_EXECUTE	Combines STANDARD_RIGHTS_EXECUTE and TOKEN_IMPERSONATE.
TOKEN_IMPERSONATE	Required to attach an impersonation access token to a process.
TOKEN_QUERY	Required to query an access token.
TOKEN_QUERY_SOURCE	Required to query the source of an access token.
TOKEN_READ	Combines STANDARD_RIGHTS_READ and TOKEN_QUERY.
TOKEN_WRITE	Combines STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT.
The TOKEN_ALL_ACCESS access right combines all possible access rights for a token.

The access rights for tokens are typically specified in calls to the OpenProcessToken and OpenThreadToken functions.


  49.3.4.4  File Mapping Objects

A process or thread cannot wait on an access-token object because the access-token object because the access-token object type does not support the SYNCHRONIZE standard access type.

The access rights defined for file mapping objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
FILE_MAP_READ	Read access to the file-mapping object is requested. This allows a readable view of the file to be mapped.
FILE_MAP_WRITE	Write access to the file mapping object is requested. This allows a writable view of the file to be mapped. If the file mapping access rights do not include PAGE_READWRITE, this access type does not allow writing the mapped file.
SECTION_EXTEND_SIZE	Required to extend the size of a file mapping object.
SECTION_MAP_EXECUTE	Required to complete an operation in a file mapping object.
SECTION_MAP_READ	Equivalent to FILE_MAP_READ.
SECTION_MAP_WRITE	Equivalent to FILE_MAP_WRITE.
SECTION_QUERY	Required to query a file mapping object.
If the call to the CreateFileMapping function specifies the PAGE_READWRITE protection flag, the handle to the file mapping object has SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE access. If the call to CreateFileMapping specifies PAGE_READONLY, the handle of the file mapping object has SECTION_QUERY | SECTION_MAP_READ access.

The FILE_MAP_ALL_ACCESS access right specifies all possible access rights for the file mapping object. The SECTION_ALL_ACCESS access right is equivalent to it.

For more information about file-mapping objects, see Chapter 47, »File Mapping«.


  49.3.5  Window-management Objects

The following are the securable window-management objects.

Securable Object	Description
Window station	A combination of the screen, keyboard, and mouse. It provides the first level of security for a work station and is the source of inheritable security for other user objects.
Desktop	The top-level window for an individual work station. This object is a subobject of a window-station object, from which it inherits security. The desktop object contains window and menu objects.
Window	A subobject of a desktop object, from which it inherits security.
Menu	A subobject of a desktop object, from which it inherits security.


  49.3.5.1  Window-station Objects

The following are the window-station access rights and their meanings.

Constant	Description
WINSTA_ACCESSCLIPBOARD	Required to use the clipboard.
WINSTA_ACCESSGLOBALATOMS	Required to manipulate global atoms.
WINSTA_CREATEDESKTOP	Required to create new desktop objects on the window station.
WINSTA_ENUMDESKTOPS	Required to enumerate existing desktop objects.
WINSTA_ENUMERATE	Required for the window station to be enumerated.
WINSTA_EXITWINDOWS	Required to successfully call the ExitWindows function. Window stations can be shared by users and this access type can prevent other users of a window station from logging off the window station owner.
WINSTA_READATTRIBUTES	Required to read the attributes of a window station object. This attribute includes color settings and other global window station properties.
WINSTA_READSCREEN	Required to access screen contents.
WINSTA_WRITEATTRIBUTES	Required to modify the attributes of a window station object. The attributes include color settings and other global window-station properties.
The following are the generic mappings for a window-station object.

Value	Maps to
GENERIC_READ	STANDARD_RIGHTS_READ, WINSTA_ENUMDESKTOPS, WINSTA_ENUMERATE, WINSTA_READATTRIBUTES, and WINSTA_READSCREEN
GENERIC_WRITE	STANDARD_RIGHTS_WRITE, WINSTA_ACCESSCLIPBOARD, WINSTA_CREATEDESKTOP, and WINSTA_WRITEATTRIBUTES
GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE, WINSTA_ACCESSGLOBALATOMS, and WINSTA_EXITWINDOWS
GENERIC_ALL	STANDARD_RIGHTS_REQUIRED, WINSTA_ACCESSCLIPBOARD, WINSTA_ACCESSGLOBALATOMS, WINSTA_CREATEDESKTOP, WINSTA_ENUMDESKTOPS, WINSTA_ENUMERATE, WINSTA_EXITWINDOWS, WINSTA_READATTRIBUTES, WINSTA_READSCREEN, and WINSTA_WRITEATTRIBUTES
An application can call the GetProcessWindowStation function to retrieve a handle of the window station. The security attributes of the window station can be retrieved and set by using this handle in calls to the GetUserObjectSecurity and SetUserObjectSecurity functions.


  49.3.5.2  Desktop Objects

A new desktop inherits its security descriptor from its parent window station.

The following are the desktop access rights and their meanings.

Constant	Description
DESKTOP_CREATEMENU	Required to create a menu associated with the desktop.
DESKTOP_CREATEWINDOW	Required to create a window on the desktop.
DESKTOP_ENUMERATE	Required for the desktop to be enumerated.
DESKTOP_ENUMWINDOWS	Required to enumerate window objects on a desktop.
DESKTOP_HOOKCONTROL	Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK	Required to perform journal playback on a desktop.
DESKTOP_JOURNALRECORD	Required to perform journal recording on a desktop.
The following are the generic mappings for a desktop object.

Value	Maps to
GENERIC_READ	DESKTOP_ENUMERATE, DESKTOP_ENUMWINDOWS, and STANDARD_RIGHTS_READ
GENERIC_WRITE	DESKTOP_CREATEMENU, DESKTOP_CREATEWINDOW, DESKTOP_HOOKCONTROL, DESKTOP_JOURNALPLAYBACK, DESKTOP_JOURNALRECORD, and STANDARD_RIGHTS_WRITE
GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE
GENERIC_ALL	DESKTOP_CREATEMENU, DESKTOP_CREATEWINDOW, DESKTOP_ENUMERATE, DESKTOP_ENUMWINDOWS, DESKTOP_HOOKCONTROL, DESKTOP_JOURNALPLAYBACK, DESKTOP_JOURNALRECORD, and STANDARD_RIGHTS_REQUIRED
An application can call the GetThreadDesktop function to retrieve a handle of the desktop for a given thread. The desktop's security attributes can be retrieved and set by using this handle in calls to GetUserObjectSecurity and SetUserObjectSecurity.


  49.3.5.3  Window Objects

The WIN_ACCESSWINDOW access right is required to perform any window operation.

A new window inherits its security descriptor from its parent desktop and is implicitly opened during its creation.

The following are the generic mappings for a window object.

Value	Maps to
GENERIC_READ	STANDARD_RIGHTS_READ
GENERIC_WRITE	STANDARD_RIGHTS_WRITE
GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE and WIN_ACCESSWINDOW
GENERIC_ALL	STANDARD_RIGHTS_REQUIRED and WIN_ACCESSWINDOW
For more information about window objects, see Chapter 1, "Windows." in Microsoft Win32 Programmer's Reference, Volume 1


  49.3.5.4  Menu Objects

The MENU_ACCESSMENU access right is required to perform any menu operation.

A new menu inherits its security descriptor from its parent desktop and is implicitly opened during during the call to the CreateMenu function.

The following are the generic mappings for a menu object.

Value	Maps to
GENERIC_READ	STANDARD_RIGHTS_READ
GENERIC_WRITE	STANDARD_RIGHTS_WRITE
GENERIC_EXECUTE	MENU_ACCESSMENU and STANDARD_RIGHTS_EXECUTE
GENERIC_ALL	MENU_ACCESSMENU and STANDARD_RIGHTS_REQUIRED
For more information about menu objects, see Chapter 16, "Menus" in Microsoft Win32 Programmer's Reference, Volume 1


  49.3.6  Registry Key Objects

The following are the registry-key access rights and their meanings.

Value	Meaning
KEY_ALL_ACCESS	Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK values.
KEY_CREATE_LINK	Required to create a link to a registry-key object.
KEY_CREATE_SUB_KEY	Required to create a subkey of a registry-key object.
KEY_ENUMERATE_SUB_KEYS	Required to enumerate the subkeys of a registry-key object.
KEY_EXECUTE	Equivalent to KEY_READ.
KEY_NOTIFY	Required to request change notifications for a registry key or for subkeys of a registry key.
KEY_QUERY_VALUE	Required to query a value of a registry-key object.
KEY_READ	Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
KEY_SET_VALUE	Required to create or set a value of a registry-key object.
KEY_WRITE	Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY values.
For more information about registry objects, see Chapter 52, »Registry and Initialization Files«.


  49.3.7  Service Objects

The access rights and generic mappings for service-control manager objects and service objects are given in the reference material for the OpenService and OpenSCManager functions. For information about service objects, see Chapter 58, »Services«.


  49.3.8  Synchronization Objects

There are three kinds of securable synchronization objects: semaphores, events, and mutexes. The fourth type of synchronization object is critical sections. Because they are per-process objects and not kernel objects, they are not securable.


  49.3.8.1  Semaphore Objects

The valid access rights for semaphore objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
SEMAPHORE_ALL_ACCESS	Specifies all possible access rights for a semaphore object.
SEMAPHORE_MODIFY_STATE	Specifies modify state (release) access.
SYNCHRONIZE	Specifies synchronization (wait) access.
The handle returned by the CreateSemaphore function has SEMAPHORE_ALL_ACCESS access to the semaphore object.


  49.3.8.2  Event Objects

The valid access rights for event objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
EVENT_ALL_ACCESS	Specifies all possible access rights for an event object.
EVENT_MODIFY_STATE	Specifies modify state (release) access.
SYNCHRONIZE	Specifies synchronization (wait or release) access.
The handle returned by the CreateEvent function has EVENT_ALL_ACCESS access to the semaphore object.


  49.3.8.3  Mutex Objects

The valid access rights for mutex objects are STANDARD_RIGHTS_REQUIRED and the rights given in the following table.

Value	Meaning
MUTEX_ALL_ACCESS	Specifies all possible access rights for a mutex object.
MUTEX_MODIFY_STATE	Specifies modify state (release) access.
SYNCHRONIZE	Specifies synchronization (wait or release) access.
The handle returned by the CreateMutex function has MUTEX_ALL_ACCESS access to the mutex object.


  49.4  Using Security

This section demonstrates some practical applications of the Win32 API security functions and structures. As noted in Section 49.3.1, »File and Directory Objects«, file objects can be secured only when the NTFS file system is in use.


  49.4.1  Denying All Access

The following example demonstrates adding an empty discretionary access-control list (ACL) to a file's security descriptor. An empty ACL implicitly denies all access to the file.

PSECURITY_DESCRIPTOR pSD;

PACL pACL;

DWORD cbACL = 1024;

/* Initialize a security descriptor. */

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,

    SECURITY_DESCRIPTOR_MIN_LENGTH);   /* defined in WINNT.H */

if (pSD == NULL) {

    ErrorHandler("LocalAlloc");

    return FALSE;

}

if (!InitializeSecurityDescriptor(pSD,

        SECURITY_DESCRIPTOR_REVISION)) { /* defined in WINNT.H */

    ErrorHandler("InitializeSecurityDescriptor");

    goto Cleanup;

}

/* Initialize a DACL. */

pACL = (PACL) LocalAlloc(LPTR, cbACL);

if (pACL == NULL) {

    ErrorHandler("LocalAlloc");

    goto Cleanup;

}

if (!InitializeAcl(pACL, cbACL, ACL_REVISION2)) {

    ErrorHandler("InitializeAcl");

    goto Cleanup;

}

/* Add an empty ACL to the SD to deny access. */

if (!SetSecurityDescriptorDacl(pSD,

        TRUE,     /* fDaclPresent flag  */

        pACL,

        FALSE)) { /* not a default DACL */

    ErrorHandler("SetSecurityDescriptorDacl");

    goto Cleanup;

}

/* Use the new SD as the file's security info. */

if (!SetFileSecurity(lpszTestFile,

        DACL_SECURITY_INFORMATION,

        pSD)) {

    ErrorHandler("SetFileSecurity");

    goto Cleanup;

}

Cleanup:

    if(pSD != NULL)

        LocalFree((HLOCAL) pSD);

    if(pACL != NULL)

        LocalFree((HLOCAL) pACL);


  49.4.2  Allowing Access

The following example demonstrates adding a NULL discretionary ACL to a file's security descriptor. A NULL ACL implicitly allows all access to the file.

Note: It is fine to write code like this that builds security descriptors from scratch. It is, however, a good practice for people who write code that builds or manipulates security descriptors to first write code that explores the default security descriptors that Windows NT places on objects. For example, if Windows NT by default includes in a DACL an ACE granting the Local Logon SID certain access, it's good to know that, so that a decision not to grant any access to the Local Logon SID would be a conscious decision

PSECURITY_DESCRIPTOR pSD;

/* Initialize a security descriptor. */

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,

    SECURITY_DESCRIPTOR_MIN_LENGTH);   /* defined in WINNT.H */

if (pSD == NULL) {

    ErrorHandler("LocalAlloc");

    return FALSE;

}

if (!InitializeSecurityDescriptor(pSD,

        SECURITY_DESCRIPTOR_REVISION)) { /* defined in WINNT.H */

    ErrorHandler("InitializeSecurityDescriptor");

    goto Cleanup;

}

/* Add a NULL disc. ACL to the security descriptor. */

if (!SetSecurityDescriptorDacl(pSD,

        TRUE,     /* specifying a disc. ACL  */

        (PACL) NULL,

        FALSE)) { /* not a default disc. ACL */

    ErrorHandler("SetSecurityDescriptorDacl");

    goto Cleanup;

}

/* Add the security descriptor to the file. */

if (!SetFileSecurity(lpszTestFile,

        DACL_SECURITY_INFORMATION,

        pSD)) {

    ErrorHandler("SetFileSecurity");

    goto Cleanup;

}

Cleanup:

    if(pSD != NULL)

        LocalFree((HLOCAL) pSD);

Rather than allowing all access by using a NULL ACL, applications generally allow access to an object by adding access-control entries (ACEs) to an ACL. The following example demonstrates finding a security identifier (SID) for a particular account and adding an access-allowed ACE for that account.

    PSECURITY_DESCRIPTOR pSD;

    PACL pACLNew;

    DWORD cbACL = 1024;

    PSID pSID;

    DWORD cbSID = 1024;

    LPSTR lpszAccount = "UserABC";

    LPSTR lpszDomain;

    DWORD cchDomainName = 80;

    PSID_NAME_USE psnuType;

    /* Initialize a new security descriptor. */

    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,

        SECURITY_DESCRIPTOR_MIN_LENGTH);  /* defined in WINNT.H  */

    if (pSD == NULL) {

        ErrorHandler("LocalAlloc");

        return FALSE;

    }

    if (!InitializeSecurityDescriptor(pSD,

            SECURITY_DESCRIPTOR_REVISION)) {

        ErrorHandler("InitializeSecurityDescriptor");

        goto Cleanup;

    }

    /* Initialize a new ACL.                 */

    pACLNew = (PACL) LocalAlloc(LPTR, cbACL);

    if (pACLNew == NULL) {

        ErrorHandler("LocalAlloc");

        goto Cleanup;

    }

    if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION2)) {

        ErrorHandler("InitializeAcl");

        goto Cleanup;

    }

    /* Retrieve the SID for UserABC.         */

    pSID = (PSID) LocalAlloc(LPTR, cbSID);

    psnuType = (PSID_NAME_USE) LocalAlloc(LPTR, 1024);

    lpszDomain = (LPSTR) LocalAlloc(LPTR, cchDomainName);

    if (pSID == NULL || psnuType == NULL || lpszDomain == NULL) {

        ErrorHandler("LocalAlloc");

        goto Cleanup;

    }

    if (!LookupAccountName((LPSTR) NULL, /* local name */

            lpszAccount,

            pSID,

            &cbSID,

            lpszDomain,

            &cchDomainName,

            psnuType)) {

        ErrorHandler("LookupAccountName");

        goto Cleanup;

    }

    if (!IsValidSid(pSID))

        TextOut(hdc, 10, yIncrement += 18,

            "SID is not valid.", 17);

    else

        TextOut(hdc, 10, yIncrement += 18,

            "SID is valid.", 13);

    /* Allow read but not write access to the file. */

    if (!AddAccessAllowedAce(pACLNew,

            ACL_REVISION2,

            GENERIC_READ,

            pSID)) {

        ErrorHandler("AddAccessAllowedAce");

        goto Cleanup;

    }

    /* Add a new ACL to the security descriptor.          */

    if (!SetSecurityDescriptorDacl(pSD,

            TRUE,              /* fDaclPresent flag  */

            pACLNew,

            FALSE)) {          /* not a default disc. ACL */

        ErrorHandler("SetSecurityDescriptorDacl");

        goto Cleanup;

    }

    /* Apply the new security descriptor to the file. */

    if (!SetFileSecurity("d:\\ntfs_sample_file",

            DACL_SECURITY_INFORMATION,

            pSD)) {

        ErrorHandler("SetFileSecurity");

        goto Cleanup;

    }

    TextOut(hdc, 10, yIncrement += 18,

        "Successfully added access-allowed ACE to file's DACL.", 53);

    Cleanup:

        FreeSid(pSID);

        if(pSD != NULL)

            LocalFree((HLOCAL) pSD);

        if(pACLNew != NULL)

            LocalFree((HLOCAL) pACLNew);

        if(psnuType != NULL)

            LocalFree((HLOCAL) psnuType);

        if(lpszDomain != NULL)

            LocalFree((HLOCAL) lpszDomain);


  49.4.3  Setting Privileges

The following example removes the discretionary ACL from a file. If necessary, ownership of the file is given to the Administrator account. If required, the SE_TAKE_OWNERSHIP_NAME privilege is enabled for the account.

LPSTR lpszOwnFile = "d:\\ntfs_sample_file";

PSID pSIDAliasAdmins = NULL;

static SID_IDENTIFIER_AUTHORITY

    siaNTAuthority = SECURITY_NT_AUTHORITY;

BOOL FAR PASCAL TakeOwnership()

{

    SECURITY_DESCRIPTOR sd;

    /*

     * Initialize a security descriptor and assign it a NULL

     * discretionary ACL to allow unrestricted access.

     * Assign the security descriptor to a file.

     */

    if (!InitializeSecurityDescriptor(&sd,

            SECURITY_DESCRIPTOR_REVISION)) {

        ErrorHandler("InitializeSecurityDescriptor");

        return FALSE;

    }

    if (!SetSecurityDescriptorDacl(&sd,

            TRUE,

            (PACL) NULL,

            FALSE)) {

        ErrorHandler("SetSecurityDescriptorDacl");

        return FALSE;

    }

    if (SetFileSecurity(lpszOwnFile,

            DACL_SECURITY_INFORMATION,

            &sd))

        return TRUE;

    else

        ErrorHandler("SetFileSecurity1");

    /*

     * If the preceding call to SetFileSecurity fails, create

     * an Administrator SID and use it to set the owner of

     * the security descriptor.

     */

    if (!AllocateAndInitializeSid(&siaNTAuthority,

            2,                            /* subauthority count  */

            SECURITY_BUILTIN_DOMAIN_RID,  /* first subauthority  */

            DOMAIN_ALIAS_RID_ADMINS,      /* second subauthority */

            0, 0, 0, 0, 0, 0,

            &pSIDAliasAdmins)) {

        ErrorHandler("AllocateAndInitializeSid");

        return FALSE;

    }

    if (!SetSecurityDescriptorOwner(&sd,

            pSIDAliasAdmins,

            FALSE)) {

        ErrorHandler("SetSecurityDescriptorOwner");

        FreeSid(pSIDAliasAdmins);

        return FALSE;

    }

    /*

     * If the following call to SetFileSecurity fails, enable

     * SE_TAKE_OWNERSHIP_NAME in the access token for the

     * current process and try again.

     */

    if (!SetFileSecurity(lpszOwnFile,

            OWNER_SECURITY_INFORMATION,

            &sd)) {

        ErrorHandler("SetFileSecurity2");

        if (!AssertTakeOwnership(TRUE)) {  /* locally defined    */

            MessageBox(NULL, "Must be logged on as Administrator",

                "AssertTakeOwnership", MB_OK);

            FreeSid(pSIDAliasAdmins);

            return FALSE;

        }

        if (!SetFileSecurity(lpszOwnFile,

                OWNER_SECURITY_INFORMATION,

                &sd)) {

            MessageBox(NULL, "Must be logged on as Administrator",

                "SetFileSecurity", MB_OK);

            FreeSid(pSIDAliasAdmins);

            return FALSE;

        }

    }

    /*

     * The Administrator is now the owner of the file.

     * Try again to assign a NULL ACL.

     */

    if (SetFileSecurity(lpszOwnFile,

            DACL_SECURITY_INFORMATION,

            &sd)) {

        MessageBox(NULL, "Added NULL DACL; protection removed",

            "SetFileSecurity", MB_OK);

        AssertTakeOwnership(FALSE);

        return TRUE;

    }

    else {

        AssertTakeOwnership(FALSE);

        ErrorHandler("SetFileSecurity3");

        return FALSE;

    }

}

BOOL FAR PASCAL AssertTakeOwnership(BOOL fEnable)

{

    HANDLE hToken;

    LUID TakeOwnershipValue;

    TOKEN_PRIVILEGES tkp;

    /* Retrieve a handle of the access token.           */

    if (!OpenProcessToken(GetCurrentProcess(),

            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,

            &hToken)) {

        ErrorHandler("OpenProcessToken");

        return FALSE;

    }

    /*

     * Enable the SE_TAKE_OWNERSHIP_NAME privilege or disable

     * all privileges, depending on the fEnable flag.

     */

    if(fEnable) {

        if (!LookupPrivilegeValue((LPSTR) NULL,

                SE_TAKE_OWNERSHIP_NAME,

                &TakeOwnershipValue)) {

            ErrorHandler("LookupPrivilegeValue");

            return FALSE;

        }

        tkp.PrivilegeCount = 1;

        tkp.Privileges[0].Luid = TakeOwnershipValue;

        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        AdjustTokenPrivileges(hToken,

            FALSE,

            &tkp,

            sizeof(TOKEN_PRIVILEGES),

            (PTOKEN_PRIVILEGES) NULL,

            (PDWORD) NULL);

        /* The return value of AdjustTokenPrivileges be texted. */

        if (GetLastError() != ERROR_SUCCESS) {

            ErrorHandler("AdjustTokenPrivileges");

            return FALSE;

        }

    }

    else {

        AdjustTokenPrivileges(hToken,

            TRUE,                  /* disable all privileges */

            (PTOKEN_PRIVILEGES) NULL,

            (DWORD) 0,

            (PTOKEN_PRIVILEGES) NULL,

            (PDWORD) NULL);

        /*

         * The return value of AdjustTokenPrivileges cannot be

         * tested.

         */

        if (GetLastError() != ERROR_SUCCESS) {

            ErrorHandler("AdjustTokenPrivileges");

            return FALSE;

        }

    }

    return TRUE;

}


  49.4.4  Security Editor

Both File Manager and the Microsoft Windows NT Registry Editor (RGEDT32.EXE) include a security editor that allows a user with the appropriate privileges and access rights to change the security attributes of files and registry keys. This security editor imposes guidelines on the form of the security information. Applications that modify the security of files, directories, or registry keys can follow these guidelines so the security editor will function correctly after the modifications.

The security editor accepts discretionary ACLs having either zero or more ACCESS_DENIED_ACE access-control entries (ACEs) or zero or more ACCESS_ALLOWED_ACE ACEs. The two ACE types cannot be mixed in a discretionary ACL. Neither does the security editor accept ACCESS_DENIED_ACE ACEs that deny only partial access. For example, it would reject an ACE that denies only read access to a file.

The security editor also imposes a requirement on inheritance flags. These flags are ignored for noncontainer objects, such as files, but are important for container objects, such as directories and registry keys. For container objects that support permissions on objects in the container, make sure that each security identifier (SID) has an ACE inherited by objects and an ACE inherited by containers. Accordingly, the discretionary ACL should contain ACEs in which the AceFlags member of the ACE_HEADER structure contains the OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags. Sometimes these flags can be combined in a single ACE. For example, a discretionary ACL that grants read access to a directory can contain a CONTAINER_INHERIT_ACE ACE that grants GENERIC_READ access to the user or group as well as an ACE with the OBJECT_INHERIT_ACE and INHERIT_ONLY_ACE flags that also grants GENERIC_READ access. In this case, the required flags could be combined into an ACE that grants GENERIC_READ access and combines the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.

The same rules for inheritance flags apply to system ACLs. The security editor does not support the SYSTEM_ALARM_ACE type and will not edit a system ACL containing one. As noted earlier, this ACE type is not supported by the current version of Windows NT.


  49.4.5  Designing a Protected Server

The designer of a server application that assigns security to private object types must make many decisions about the design of the security interface, such as those in the following list:

•	Define object.

•	Determine the types of objects and the access types required, including whether to support SYNCHRONIZE.

•	Determine whether an object is a container or noncontainer, as well as the appropriate inheritance flags.

For more information about container objects, see Chapter 56, »Networks«.

Define appropriate access types and generic mappings.

•	Determine impersonation characteristics.

•	Develop security descriptor for the initial object and for new objects assembled from the parent's security descriptor and the client's access token.

•	Consider string- versus handle-based object-manipulation functions.

•	Resolve potential conflicts in access rights. For example, decide what is to be done if an administrator and a user both have delete access to an object.

For example, the designer of a protected print server might choose to define a server object, a printer object, and a document object. The three access rights in the following table are likely to be required:

Access right	Description
Administrate	Allows the holder to add objects to and delete them from another object. This right applies to the server, the printers, and the documents.
Enumerate	Allows the holder to list a container object's contents. This right applies to the server and to the printers.
Use	Allow the holder to add items to a print queue. This right applies to the printers.


  49.5  Functions

Following are the functions used to control security.

AccessCheck
AccessCheckAndAuditAlarm
AddAccessAllowedAce
AddAccessDeniedAce
AddAce
AddAuditAccessAce
AdjustTokenGroups
AdjustTokenPrivileges
AllocateAndInitializeSid
AllocateLocallyUniqueId
AreAllAccessesGranted
AreAnyAccessesGranted
CopySid
CreatePrivateObjectSecurity
DdeImpersonateClient
DeleteAce
DestroyPrivateObjectSecurity
DuplicateToken
EqualPrefixSid
EqualSid
FindFirstFreeAce
FreeSid
GetAce
GetAclInformation
GetFileSecurity
GetKernelObjectSecurity
GetLengthSid
GetPrivateObjectSecurity
GetProcessWindowStation
GetSecurityDescriptorControl
GetSecurityDescriptorDacl
GetSecurityDescriptorGroup
GetSecurityDescriptorLength
GetSecurityDescriptorOwner
GetSecurityDescriptorSacl
GetSidIdentifierAuthority
GetSidLengthRequired
GetSidSubAuthority
GetSidSubAuthorityCount
GetThreadDesktop
GetTokenInformation
GetUserObjectSecurity
ImpersonateNamedPipeClient
ImpersonateSelf
InitializeAcl
InitializeSecurityDescriptor
InitializeSid
IsValidAcl
IsValidSecurityDescriptor
IsValidSid
LookupAccountName
LookupAccountSid
LookupPrivilegeDisplayName
LookupPrivilegeName
LookupPrivilegeValue
MakeAbsoluteSD
MakeSelfRelativeSD
MapGenericMask
ObjectCloseAuditAlarm
ObjectOpenAuditAlarm
ObjectPrivilegeAuditAlarm
OpenProcessToken
OpenThreadToken
PrivilegeCheck
PrivilegedServiceAuditAlarm
RevertToSelf
SetAclInformation
SetFileSecurity
SetKernelObjectSecurity
SetPrivateObjectSecurity
SetSecurityDescriptorDacl
SetSecurityDescriptorGroup
SetSecurityDescriptorOwner
SetSecurityDescriptorSacl
SetTokenInformation
SetUserObjectSecurity


Dynamic-Link Libraries
  Chapter 50    Dynamic-Link Libraries

50.1  About Dynamic-Link Libraries

In Microsoft Windows, dynamic linking provides a way for a process to call a function that is not part of its executable code. The executable code for the function is located in a dynamic-link library (DLL), containing one or more functions that are compiled, linked, and stored separately from the processes using them. The Microsoft Win32 application program interface (API) is implemented as a set of dynamic-link libraries, so any process using the Win32 API uses dynamic linking.

Dynamic linking allows an executable module (either a .DLL or .EXE file) to include only the information needed at run time to locate the executable code for a DLL function. This differs from the more familiar static linking, which requires a copy of a library function's executable code in the executable module of each application using it.

There are two methods for calling a function in a DLL:

•	Load-time dynamic linking occurs when an application's code makes an explicit call to a DLL function. This requires that the executable module of the application be built by linking with the DLL's import library, which supplies the information needed to locate the DLL function when the application starts. For more information, see Section 50.1.5, »Load-Time Dynamic Linking«.

•	Run-time dynamic linking occurs when a program uses the LoadLibrary and GetProcAddress functions to get the starting address of a DLL function. This eliminates the need to link with an import library. For more information, see Section 50.1.6, »Run-Time Dynamic Linking«.

A DLL attaches to a process when the process starts or when one of it threads calls the LoadLibrary function. When a DLL attaches to a process, the operating system maps the DLL module into the address space of the process, making the DLL's executable code available to the process. When a DLL detaches from a process at process termination or as a result of a call to the FreeLibrary function, the DLL module is unmapped from the address space of the process.

Like any other function, a DLL function is executed in the context of the thread (and the thread's process) that calls it. Therefore, the following conditions apply:

•	The threads of the process that called the DLL can use handles opened by a DLL function. Similarly, handles opened by any thread of the calling process can be used in the DLL function.

•	The DLL uses the user stack of the calling thread and the address space of the calling process.

•	Memory allocated by the DLL is in the address space of the calling process.

•	The threads of the process that called the DLL can read from or write to the globally declared variables in the DLL.


  50.1.1  Advantages of Dynamic Linking

Dynamic linking has the following advantages:

•	Many processes can use a single DLL simultaneously, sharing a single copy of the DLL in memory. This saves memory space and reduces swapping.

•	You can change the functions in a DLL without recompiling or relinking the applications that use them, as long as the functions' arguments and return values do not change. This differs from statically linked object code in which you must relink the application to update it when the functions change.

•	You can use a DLL for after-market support. For example, a display driver DLL can be modified to support a display that was not available when the application was shipped.

•	Programs written in different programming languages can call the same DLL function, as long as the programs follow the function's calling convention. The programs and the DLL function must be compatible in the order the function expects its arguments to be pushed onto the stack, whether the function or the application is responsible for cleaning up the stack, and whether any arguments are passed in registers.

A potential disadvantage to using DLLs is that the application is not self-contained; it depends on the existence of a separate DLL module. A process using load-time dynamic linking is terminated by the operating system if the DLL is not found at process startup. A process using run-time dynamic linking is not terminated in this situation, but the functionality provided by the DLL is not available to the program.


  50.1.2  Dynamic-Link Library Creation

To create a DLL, first create one or more source code files (.C) and a module definition file (.DEF). The source code file contains the exported functions for the DLL. The .DEF file lists these functions and defines other attributes of the DLL.

The compiler uses the .C file to create an object code file (.OBJ). The library manager creates an export file (.EXP) and an import library file (.LIB) from the .DEF file.

Finally, the linker uses the .OBJ, .EXP, and .LIB files to build the executable files for the DLL. The .OBJ and .EXP files provide the information the linker needs to build the .DLL file. The .LIB file contains the information the linker needs to resolve the external references to DLL functions, so that a program can locate the specified DLL at run time. The .LIB file enables the linker to build any executable module (.EXE or .DLL) that calls a function in the DLL. For more information about .DEF files, see Section 50.1.4, »The Module-Definition File«.

Note that the information in this section is based on using Win32 software development tools. Refer to the documentation provided with the development tools you are using for more detailed information about creating DLLs.


  50.1.3  The DLL Entrypoint Function

A DllEntryPoint function is an optional DLL function that the operating system calls to perform user-defined operations. DllEntryPoint is not a typical function, but is a reference to a function specified in the linker command line. A DLL is not required to have an entrypoint function, but it can be useful for initializing and cleaning up processes and threads. The name of a DLL's entrypoint function is specified by the hyphen entry switch of the linker. For example, the following command line specifies LibMain as the entrypoint function of MYDLL.DLL:

link -entry:LibMain -out:mydll.dll mydll.exp mydll.obj $(mylibs)

If an entrypoint function is specified, the operating system causes it to be called whenever any of the following events occurs:

•	The DLL attaches to a process. For processes using load-time dynamic linking, this occurs during initialization. For processes using run-time linking, the DLL attaches and the entrypoint function is called before LoadLibrary returns.

•	The DLL detaches from a process. This occurs when the process terminates or when the DLL is unloaded by a call to the FreeLibrary function. If the process terminates as a result of the TerminateProcess or the TerminateThread function, the system does not call the entrypoint function.

•	The DLL attaches to a thread. This occurs whenever a new thread is created in a process to which a DLL is attached.

•	The DLL detaches from a thread. This occurs whenever a thread of an attached process terminates, except as a result of the TerminateThread or the TerminateProcess function. When a DLL detaches from a process, the entrypoint function is called only once for the entire process, rather than once for each existing thread of the process.

The system causes the entrypoint function to be called, but it is called in the context of a process or thread attaching to or detaching from the DLL. This allows a DLL to use its entrypoint function for allocating memory in the address space of the process or to open handles accessible to the process. When called to attach a new thread, the entrypoint function can allocate memory for thread local storage (TLS) that is private to the new thread. For more about thread local storage, see Chapter 43, »Processes and Threads«.

When a DLL's entrypoint function is called for process attachment, it returns TRUE to indicate success. For processes using load-time linking, a return value of FALSE causes the process initialization to fail and the process terminates. For processes using run-time linking, a return value of FALSE causes the LoadLibrary function to return NULL, indicating failure. The return value of the entrypoint function is disregarded when it is called for any other reasons, such as process detach, thread attach, or thread detach.


  50.1.4  The Module-Definition File

A module definition (.DEF) file is a text file containing one or more module statements that describe various attributes of a dynamic-link library. The descriptions and examples in this section are based on the keywords and syntax used by the Win32 software development tools. Refer to the documentation provided with your development tools for complete documentation of module definition files.

A DLL requires a module-definition file to create an import library (.LIB) file and an export (.EXP) file. The linker uses the import library to build any executable module that uses the DLL; it also uses the export file to build the .DLL file.

A DLL's module definition file must include a LIBRARY statement and an EXPORTS statement. The LIBRARY statement identifies the module definition file as belonging to a DLL and must be the first statement in the file. The name specified in the LIBRARY statement identifies the library in the DLL's import library. The EXPORTS statement lists the names and, optionally, the ordinal values of the functions exported by the DLL. When ordinal values are specified, they must be in the range 1 through N, where N is the number of functions exported by the DLL.

The following is a DLL's module definition file that exports three functions and associates an ordinal value with each function.

LIBRARY mydll

EXPORTS

    Func_A @1

    Func_B @2

    Func_C @3

The module definition file can contain additional statements specifying other attributes of a DLL. For example, the SECTIONS statements can change the default scope of global and static variables. The following SECTIONS statement makes the DLL's initialized data shared, while the uninitialized variables are not.

SECTIONS

    .data READ WRITE SHARED    ; share initialized variables


  50.1.5  Load-Time Dynamic Linking

Load-time dynamic linking occurs when an application's code explicitly calls a DLL function. When the source code is compiled or assembled, the DLL function call generates an external function reference in the object code. To resolve this external reference, the application must be linked with the import library for the DLL.

Finding an external function in an import library informs the linker that the code for that function is in a dynamic-link library. To resolve external references to dynamic-link libraries, the linker simply adds information to the executable file that tells the system where to find the DLL code when the process starts up.

When the system starts a program that contains dynamically linked references, it uses the information in the program's executable file to locate the required DLLs. The system first searches the set of pre-installed DLLs, such as the performance library, (KERNEL32.DLL) and the security library, (USER32.DLL). The system then searches for the DLLs by using the following search path:

1.	The directory where the executable module for the current process is located.

2.	The current directory.

3.	The windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

The LIBPATH environment variable is not used.

If it cannot locate a specified DLL, the system terminates the process and displays a dialog box that reports the error. Otherwise, the system maps the DLL modules into the process's address space.

If any of the DLLs has a DllEntryPoint function, the operating system calls the function. DllEntryPoint specifies a code that indicates the DLL is attaching to the process. If the entrypoint function does not return TRUE, the system terminates the process and reports the error. For more information about the entrypoint function, see Section 50.1.3, »The DLL Entrypoint Function«.

Finally, the system modifies the executable code of the process to provide the starting addresses for the DLL functions.

Like the rest of a program's code, DLL code is mapped into the address space of the process when the process starts up and loaded into memory only when needed. As a result, the PRELOAD or LOADONCALL code attributes used by module-definition files to control loading in previous versions of Windows have no meaning in Windows NT.


  50.1.6  Run-Time Dynamic Linking

Run-time dynamic linking occurs when the process calls the LoadLibrary function to specify the name of a DLL and the GetProcAddress function to get the starting address of any function in the DLL. Run-time dynamic linking eliminates the need to link the process with an import library the process does not explicitly call the DLL's functions, so it does not generate the external references.

If the call to LoadLibrary specifies a DLL module already mapped into the address space of the calling process, LoadLibrary simply returns a handle of the DLL and increments the module's reference count. Otherwise, LoadLibrary attempts to locate the DLL on the same search path used for load-time dynamic linking (see Section 50.1.5, »Load-Time Dynamic Linking«). If the search succeeds, the system maps the DLL module into the address space of the process. If the DLL has a DllEntryPoint function, the operating system calls the function in the context of the thread that called LoadLibrary. The entrypoint function is not called if the DLL is already attached to the process due to load-time linking to a previous call to LoadLibrary. This occurs when no corresponding call to the FreeLibrary function has been made.

If the system cannot find the DLL or if the entrypoint function returns FALSE, LoadLibrary returns NULL. If LoadLibrary succeeds, it returns a handle of the DLL module. The process can use this handle to identify the DLL in a call to the GetProcAddress or FreeLibrary functions.

The GetModuleHandle function also returns a handle used in GetProcAddress or FreeLibrary. GetModuleHandle succeeds only if the DLL module is already mapped into the address space of the process by load-time linking or by a previous call to LoadLibrary. Unlike LoadLibrary, GetModuleHandle does not increment the module's reference count. The GetModuleFileName function retrieves the full path of the module associated with a handle returned by GetModuleHandle or LoadLibrary.

The process can use GetProcAddress to get the starting handle returned by either LoadLibrary or address of a function in the DLL using a DLL module handle returned by either LoadLibrary or GetModuleHandle. The function is specified by using its name or ordinal value as listed in the EXPORTS statement of the DLL's module definition file.

When the DLL module is no longer needed, the process can call the FreeLibrary function. This decrements the module's reference count and unmaps it from the address space of the process if the reference count is zero.

Run-time dynamic linking enables the process to continue executing even if a DLL is not available. This allows the process to use an alternative method to accomplish its objective. For example, if a process is unable to locate one DLL, it can try to use another, or it can notify the user of an error. If the user can provide the full path of the missing DLL, the process can use this information to load the library even though it is not in the normal search path. This contrasts with load-time linking in which the operating system simply terminates the process if it cannot find the DLL.

The developer need not know the names of either the DLLs or of the functions within a DLL. The process can get this information from a configuration file or from the user.

Run-time dynamic linking can cause problems if the DLL is using the DllEntryPoint function to perform initialization for each thread of a process, because threads existing when LoadLibrary is called will not be initialized. For an example showing how to deal with this problem, see Section 50.2.5, »Using Thread Local Storage in a Dynamic-Link Library«.


  50.1.7  Dynamic-Link Library Data

Windows NT supports the use of the following:

•	Global and static variables in a DLL module private to each process that uses the DLL.

•	Global and static variables shared by all processes simultaneously using a DLL.

•	Dynamically allocated memory private to each process that uses a DLL.

•	Dynamically allocated memory shared by multiple processes.

•	Static storage private to each thread of a multithreaded process.

The default scope of a DLL's variables is the same as in any statically linked code. Global variables in a DLL source code file are global to each process using the DLL. Static variables create permanent storage for each process, limiting their scope to the block in which they are declared. As a result, each process has its own instance of a DLL's global and static variables by default.

Win32 development tools enable you to use a DLL's module definition file to override the default scope of global and static variables. For more information, see Section 50.1.4, »The Module-Definition File«, and the documentation for the tools being used.

When a DLL allocates memory using any of the allocation functions (GlobalAlloc, LocalAlloc, HeapAlloc, VirtualAlloc, or malloc and other C run-time allocation functions) the memory is allocated in the address space of the calling process and is accessible only to the threads of that process. A DLL's module-definition file cannot be used to change the scope of dynamically allocated memory.

A DLL can use file mapping to allocate memory that can be shared among processes. For a general discussion of using file mapping to create named shared memory, see Chapter 47, »File Mapping«. For an example that uses the DllEntryPoint function to set up shared memory using file mapping, see Section 50.2.4, »Using Shared Memory in a Dynamic-Link Library«.

The thread local storage functions enable a DLL to allocate an index for storing and retrieving a different value for each thread of a multithreaded process. For example, a spreadsheet application can create a new instance of the same thread each time the user opens a new spreadsheet. A DLL providing the functions for various spreadsheet operations can use thread local storage to save information about the current state of each spreadsheet (row, column, and so on). For a general discussion of thread local storage, see Chapter 43, »Processes and Threads«. For an example that uses the DllEntryPoint function to set up thread local storage, see Section 50.2.5, »Using Thread Local Storage in a Dynamic-Link Library«.


  50.2  Using Dynamic-Link Libraries

The examples in this section illustrate the following tasks:

•	Creating a simple dynamic-link library.

•	Calling a DLL function by using load-time linking.

•	Calling a DLL function by using run-time linking.

•	Using a DLL's entrypoint function to create named shared memory accessible to all processes using the DLL.

•	Using thread local storage in a DLL.


  50.2.1  Creating a Simple Dynamic-Link Library

Dynamic-link libraries make common functions available to a number of processes or threads at once. The following file, MYPUTS.C, contains a simple string printing function. This DLL does not use a DllEntryPoint function because it has no initialization or cleanup functions to perform.

#include <windows.h>

/*

 * A function that writes a null terminated string to

 * console output.

 */

VOID myPuts(LPTSTR lpszMsg) {

    DWORD cchWritten;

    HANDLE hStdout;

    /* Get a handle to the console output. */

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    /* Write a null-terminated string to the console output. */

    while (*lpszMsg)

        WriteFile(hStdout, lpszMsg++, 1, &cchWritten, NULL);

}

The module-definition file for this DLL is MYPUTS.DEF, and it contains the following information:

LIBRARY myputs

EXPORTS

     myPuts

The name specified in the LIBRARY statement identifies the DLL in the DLL's import library. Load-time dynamic linking enables the system to use this name for locating the DLL. If run-time dynamic linking is being used, the LoadLibrary function does not use this name to locate the DLL. The EXPORTS statement indicates that other .EXE or .DLL modules can call the myPuts function.

The source code in MYPUTS.C is compiled to produce an object module, MYPUTS.OBJ. The library manager uses the module-definition file (MYPUTS.DEF) to create the import library (MYPUTS.LIB) and the export file (MYPUTS.EXP). The linker uses MYPUTS.EXP and MYPUTS.OBJ to produce the executable DLL module (MYPUTS.DLL). The MYPUTS.LIB import library is not used in creating MYPUTS.DLL, but the linker uses it to create any executable module (.EXE or .DLL) that calls the myPuts function.

Following are some typical command lines used to compile and link a DLL. For more information about compiling and linking dynamic-link libraries and programs that use them, refer to the documentation for the development tools you are using.

cvars=-DWIN32 -D_MT -DSTRICT

# Compile myputs.c to create myputs.obj.

myputs.obj: myputs.c

    $(cc)  $(cflags) $(cvars) myputs.c

# Create the DLL's import library.

# Also create the myputs.exp export file.

myputs.lib: myputs.def

    $(lib) -machine:i386 \

    -def:myputs.def     \

    -out:myputs.lib

# Link myputs.obj and myputs.exp to create myputs.dll.

# myputs.lib is not used here but is included as a

# dependency to force creation of myputs.exp.

myputs.dll: myputs.obj myputs.lib

    $(link)          \

    -out:myputs.dll  \

    myputs.exp myputs.obj $(conlibs)

# If dll has a DllEntryPoint function, substitute a line

# like this to specify the name of the entrypoint function.

#    $(link) -entry:LibMain    \


  50.2.2  Using Load-Time Dynamic Linking

Once you have created a dynamic-link library, you can use it in an application. The following file, LOADTIME.C, is the source code for a simple console process that uses the myPuts function from MYPUTS.DLL.

/*

 *   File:  loadtime.c

 *   A simple program that uses myPuts() from myputs.dll

 */

#include <windows.h>

VOID myPuts(LPTSTR);   /* a function from a DLL */

VOID main(VOID) {

    myPuts("message printed using the DLL function\n");

}

Because LOADTIME.C calls the DLL function explicitly, the executable module for the application must be linked with the import library (MYPUTS.LIB). Following are some typical command lines used for compiling and linking a program that uses a DLL.

# Compile loadtime.c to create loadtime.obj.

loadtime.obj: loadtime.c

    $(cc)  $(cflags) $(cvars) loadtime.c

# Link loadtime.obj and myputs.lib to create loadtime.exe.

loadtime.exe: loadtime.obj myputs.lib

    $(link) $(conflags) \

    -out:loadtime.exe loadtime.obj myputs.lib $(conlibs)


  50.2.3  Using Run-Time Dynamic Linking

You can use the same dynamic-link library in both load-time and run-time dynamic linking. If the system can find the specified DLL module, the following source code produces the same output as the load-time example in the previous section. The program uses the LoadLibrary function to get a handle of MYPUTS.DLL. If LoadLibrary succeeds, the program uses the returned handle in the GetProcAddress function to get the starting address of the DLL's myPuts function. After calling the DLL function, the program calls the FreeLibrary function to detach the DLL from the process.

The following example illustrates an important difference between run-time and load-time dynamic linking. If the MYPUTS.DLL file is not available, the application using load-time dynamic linking simply terminates. The run-time dynamic linking example, however, is able to respond to the error.

/*

 *   File:  runtime.c

 *   A simple program that uses LoadLibrary and

 *   GetProcAddress to access myPuts() from the myputs DLL

 */

#include <stdio.h>

#include <windows.h>

typedef VOID (*MYPROC)(LPTSTR);

VOID main(VOID) {

    HINSTANCE hinstLib;

    MYPROC ProcAdd;

    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

    /* Get a handle to the DLL module. */

    hinstLib = LoadLibrary("myputs");

    /* If a handle is valid, try to get the function address. */

    if (hinstLib != NULL) {

        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts");

        /* If the function address is valid, call the function. */

        if (fRunTimeLinkSuccess = (ProcAdd != NULL))

            (ProcAdd) ("message via DLL function\n");

        /* Free the DLL module. */

        fFreeResult = FreeLibrary(hinstLib);

  }

    /* If unable to call the DLL function, use the alternative. */

    if (! fRunTimeLinkSuccess)

        printf("message via alternative method\n");

}

Because the program uses run-time dynamic linking, it is not necessary to link with the DLL's import library when creating the program's executable module. The following lines are typical of the command lines used to compile and link a program using run-time linking.

# Compile runtime.c to create runtime.obj.

runtime.obj: runtime.c

    $(cc)  $(cflags) $(cvars) runtime.c

# Link runtime.obj to create loadtime.exe.

runtime.exe: runtime.obj

    $(link) $(conflags) \

    -out:runtime.exe runtime.obj $(conlibs)


  50.2.4  Using Shared Memory in a Dynamic-Link Library

This section shows the use of a DLL's entrypoint function to set up memory that can be shared by multiple processes. In this DLL, the name of the entrypoint function is LibMain. The module definition file for this DLL is MYPUTS.DEF, and it contains the following information.

LIBRARY myputs

EXPORTS

     myPuts

The example uses file mapping to map a block of named shared memory into the address space of each process to which the DLL is attached. The entrypoint function calls the CreateFileMapping function to create a file-mapping object whenever the DLL attaches to a new process. You can use this function to either create or open a named file-mapping object. The first process to which the DLL attaches creates the file-mapping object. Subsequent processes open a handle of the existing object. The GetLastError function triggers initialization of the shared memory, because it returns NO_ERROR to the first process and ERROR_ALREADY_EXISTS to subsequent processes.

The MapViewOfFile function maps the file-mapping object into the address space of each process, returning a pointer to the memory. Note that the shared memory can be mapped to a different address in each process. For this reason, each process has its own instance of lpvMem, declared as a global variable so it is available to the DLL's functions. The example assumes that the DLL's global data is not shared, so each attaching process has its own instance of lpvMem. By default, DLL data is not shared, but this can be modified by the DLL's module definition file (see Section 50.1.4, »The Module-Definition File«).

Any shared DLL memory persists only as long as the DLL is attached to a process. In this example, the shared memory is released when the last handle of the file-mapping object is closed. To create persistent shared memory, a DLL can create a detached process (see Chapter 43, »Processes and Threads«) when the DLL attaches to the first process. If this detached process uses the DLL and does not terminate, it has a handle of the file-mapping object that prevents the shared memory from being released.

/*

 *   File:  dllshmem.c

 *

 *   DLL entrypoint function sets up shared memory using

 *   named file mapping.

 */

#include <windows.h>

#include <memory.h>

#define SHMEMSIZE 4096

static LPVOID lpvMem = NULL; /* address of shared memory */

/*

 * LibMain() is the DllEntryPoint function for this DLL.

 */

BOOL LibMain(HINSTANCE hinstDLL,   /* DLL module handle  */

        DWORD fdwReason,      /* reason called           */

        LPVOID lpvReserved) { /* reserved                */

    HANDLE hMapObject = NULL;   /* handle to file mapping */

    BOOL fInit, fIgnore;

    switch (fdwReason) {

        /*

         * DLL is attaching to a process, due to process

         * initialization or a call to LoadLibrary.

         */

          case DLL_PROCESS_ATTACH:

            /* create named file mapping object */

            hMapObject = CreateFileMapping(

                (HANDLE) 0xFFFFFFFF, /* use paging file    */

                NULL,                /* no security attr.  */

                PAGE_READWRITE,      /* read/write access  */

                0,                   /* size: high 32-bits */

                SHMEMSIZE,           /* size: low 32-bits  */

                "dllmemfilemap");    /* name of map object */

            if (hMapObject == NULL)

                return FALSE;

            /* The first process to attach initializes memory. */

            fInit = (GetLastError() != ERROR_ALREADY_EXISTS);

            /* Get a pointer to file mapped shared memory. */

            lpvMem = MapViewOfFile(

                hMapObject,     /* object to map view of    */

                FILE_MAP_WRITE, /* read/write access        */

                0,              /* high offset: map from    */

                0,              /* low offset: beginning    */

                0);             /* default: map entire file */

            if (lpvMem == NULL)

                return FALSE;

            /* Initialize memory if this is the first process. */

            if (fInit)

                memset(lpvMem, '\0', SHMEMSIZE);

            break;

        /* The attached process creates a new thread. */

        case DLL_THREAD_ATTACH:

            break;

        /* The thread of the attached process terminates. */

        case DLL_THREAD_DETACH:

            break;

        /*

         * The DLL is detaching from a process, due to

         * process termination or a call to FreeLibrary.

         */

        case DLL_PROCESS_DETACH:

            /* Unmap shared memory from process' address space. */

            fIgnore = UnmapViewOfFile(lpvMem);

            /* Close the process' handle to the file-mapping object. */

            fIgnore = CloseHandle(hMapObject);

            break;

        default:

          break;

  }

    return TRUE;

    UNREFERENCED_PARAMETER(hinstDLL);

    UNREFERENCED_PARAMETER(lpvReserved);

}

/*

 * SetSharedMem() sets the contents of shared memory.

 */

VOID SetSharedMem(LPTSTR lpszBuf) {

    LPTSTR lpszTmp;

    /* Get the address of the shared memory block. */

    lpszTmp = (LPTSTR) lpvMem;

    /* Copy the null-terminated string into shared memory. */

    while (*lpszBuf)

        *lpszTmp++ = *lpszBuf++;

    *lpszTmp = '\0';

}

/*

 * GetSharedMem() gets contents of shared memory.

 */

VOID GetSharedMem(LPTSTR lpszBuf, DWORD cchSize) {

    LPTSTR lpszTmp;

    /* Get the address of the shared memory block. */

    lpszTmp = (LPTSTR) lpvMem;

    /* Copy from shared memory into the caller's buffer. */

    while (*lpszTmp && --cchSize)

        *lpszBuf++ = *lpszTmp++;

    *lpszBuf = '\0';

}


  50.2.5  Using Thread Local Storage in a Dynamic-Link Library

This section shows the use of a DLL's entrypoint function to set up a thread local storage (TLS) index to provide private storage for each thread of a multithreaded process.

The entrypoint function uses the TlsAlloc function to allocate a TLS index whenever the DLL attaches to a process. Each thread of the process can then use this index to store a pointer to its own block of memory.

When the entrypoint function is called with the DLL_PROCESS_ATTACH code, it does the following:

1.	Uses the TlsAlloc function to allocate a TLS index.

2.	Allocates a block of memory to be used exclusively by the initial thread of the process.

3.	Uses the TLS index in a call to the TlsSetValue function to store a pointer to the allocated memory.

Each time the process creates a new thread, the entrypoint function is called with the DLL_THREAD_ATTACH code. The entrypoint function then allocates a block of memory for the new thread and stores a pointer to it by using the TLS index. Each thread can use the TLS index in a call to TlsGetValue to retrieve the pointer to its own block of memory.

When a thread terminates, the entrypoint function is called with the DLL_THREAD_DETACH code and the memory for that thread is freed. When a process terminates, the entrypoint function is called with the DLL_PROCESS_DETACH code and the TLS index is freed.

The TLS index is stored in a global variable, making it available to all the DLL's functions. The following example assumes that the DLL's global data is not shared, because the TLS index is not necessarily the same for each process to which the DLL is attached.

static DWORD dwTlsIndex; /* address of shared memory */

/*

 * LibMain() is the DllEntryPoint function for this DLL.

 */

BOOL LibMain(HINSTANCE hinstDLL,   /* DLL module handle  */

        DWORD fdwReason,           /* reason called      */

        LPVOID lpvReserved) {      /* reserved           */

    LPVOID lpvData;

    BOOL fIgnore;

    switch (fdwReason) {

        /*

         * The DLL is attaching to a process, due to process

         * initialization or a call to LoadLibrary.

         */

        case DLL_PROCESS_ATTACH:

              /* Allocate a TLS index. */

              if ((dwTlsIndex = TlsAlloc()) == 0xFFFFFFFF)

                  return FALSE;

            /* No break: Initialize the index for first thread. */

        /* The attached process creates a new thread. */

        case DLL_THREAD_ATTACH:

            /* Initialize the TLS index for this thread. */

            lpvData = (LPVOID) LocalAlloc(LPTR, 256);

            if (lpvData != NULL)

                fIgnore = TlsSetValue(dwTlsIndex, lpvData);

            break;

        /* The thread of the attached process terminates. */

        case DLL_THREAD_DETACH:

            /* Release the allocated memory for this thread. */

            lpvData = TlsGetValue(dwTlsIndex);

            if (lpvData != NULL)

                LocalFree((HLOCAL) lpvData);

            break;

        /*

         * The DLL is detaching from a process, due to

         * process termination or call to FreeLibrary.

         */

        case DLL_PROCESS_DETACH:

            /* Release the allocated memory for this thread. */

            lpvData = TlsGetValue(dwTlsIndex);

            if (lpvData != NULL)

                LocalFree((HLOCAL) lpvData);

            /* Release the TLS index. */

            TlsFree(dwTlsIndex);

            break;

        default:

            break;

    }

    return TRUE;

    UNREFERENCED_PARAMETER(hinstDLL);

    UNREFERENCED_PARAMETER(lpvReserved);

}

When a process uses load-time linking with this DLL, the entrypoint function is sufficient to manage the thread local storage. Problems can occur with a process that uses run-time linking, because the TLS memory is not allocated for threads that exist before the LoadLibrary function is called to attach the process. The following example solves this problem by checking the value returned by the TlsGetValue function and allocating memory if the value indicates that the TLS slot for this thread is not set.

LPVOID lpvData;

/* Retrieve a data pointer for the current thread. */

lpvData = TlsGetValue(dwTlsIndex);

/* If NULL, allocate memory for this thread. */

if (lpvData == NULL) {

    lpvData = (LPVOID) LocalAlloc(LPTR, 256);

    if (lpvData != NULL)

        TlsSetValue(dwTlsIndex, lpvData);

}


  50.3  Functions

Following are the functions used in dynamic linking.

DllEntryPoint
FreeLibrary
GetModuleFileName
GetModuleHandle
GetProcAddress
LoadLibrary
LoadLibraryEx
LoadModule


Resources
  Chapter 51    Resources

51.1  About Resources

A resource is binary data that a resource compiler or developer adds to an application's executable file. A resource can be either standard or defined. The data in a standard resource describes an icon, cursor, menu, dialog box, bitmap, font, accelerator table, message-table entry, string-table entry, or version. An application-defined resource, also called a custom resource, contains any data required by a specific application.

This chapter describes the functions that enable applications to find a resource in a module; load a resource into memory; add, delete or replace a resource in an executable file; and generate a list of the resources contained in a module. For specific information about the organization of resource data within executable files, refer to the resource formats documentation.

For information about how to create standard resources, refer to the following table.

Resource	Chapter
Bitmap	Chapter 29, Bitmaps," in Microsoft Win32 Programmer's Reference, Volume 1
Cursor	Chapter 21, "Cursors," in Microsoft Win32 Programmer's Reference, Volume 1
Dialog box	Chapter 18, "Dialog Boxes," in Microsoft Win32 Programmer's Reference, Volume 1
Font	Chapter 35, "Fonts and Text," in Microsoft Win32 Programmer's Reference, Volume 1
Accelerator table	Chapter 17, "Keyboard Accelerators," in Microsoft Win32 Programmer's Reference, Volume 1
Icon	Chapter 23, "Icons," in Microsoft Win32 Programmer's Reference, Volume 1
Menu	Chapter 16, "Menus," in Microsoft Win32 Programmer's Reference, Volume 1
Message-table entry	Your message-compiler documentation
String-table entry	Chapter 53, »String Manipulation and Unicode«
Version information	Chapter 80, »File Installation Library«
For information about how to include resource data in a Microsoft Windows executable file, refer to the documentation for your resource compiler.


  51.1.1  Finding and Loading Resources

Before using a resource, an application must load it into memory. The FindResource and FindResourceEx functions find a resource in a module and return a handle to the binary resource data. FindResource locates a resource by type and name. The FindResourceEx function locates the resource by type, name, and language. Information about FindResource in this chapter also applies to FindResourceEx.

The LoadResource function uses the resource handle returned by FindResource to load the resource into memory. After an application loads a resource by using LoadResource, Windows automatically unloads and reloads the resource as memory conditions and application execution require, so that it is not necessary for an application to explicitly unload a resource that is no longer needed.

An application can use FindResource and LoadResource to find and load any type of resource, but these functions should be used only if the application must access the binary resource data for subsequent function calls. To use a resource immediately, an application should use one of the following resource-specific functions to find and load resources in one call.

Function	Action
FormatMessage	Loads and formats a message-table entry.
LoadAccelerators	Loads an accelerator table.
LoadBitmap	Loads a bitmap resource.
LoadCursor	Loads a cursor resource.
LoadIcon	Loads an icon resource.
LoadMenu	Loads a menu resource.
LoadString	Loads a string-table entry.
For example, an application can use the LoadIcon function to load an icon for display on a screen. However, the application should use FindResource and LoadResource if it is loading the icon to copy its data to another application.

Before terminating, an application should release the memory occupied by accelerator tables, bitmaps, cursors, icons, and menus by using one of the functions in the following table.

Resource	Release function
Accelerator table	DestroyAcceleratorTable
Bitmap	DeleteObject
Cursor	DestroyCursor
Icon	DestroyIcon
Menu	DestroyMenu
When the application terminates, Windows automatically releases the memory occupied by the other types of resources.


  51.1.2  Adding, Deleting, and Replacing Resources

Applications must frequently add, delete, or replace resources in executable files. Two methods can be used to accomplish these tasks. The first is to edit the resource-definition file, recompile the resources, and add the recompiled resources to the application's executable file. The second method is to copy the resource data directly into the application's executable file.

For example, to localize an English-language application for use in Norway, it may be necessary to replace the English dialog box with one using Norwegian. A developer creates an appropriate dialog box by using a dialog box editor or by writing a template in the resource-definition file. Then the developer recompiles the resources and adds the new resources to the application's executable file.

If an appropriate dialog box exists in binary form, however, the developer can copy the data directly to the executable file being localized by using three Windows functions. The BeginUpdateResource function creates an update handle for the executable file whose resources are to be changed. The UpdateResource function uses this handle to add, delete, or replace a resource in the executable file. The EndUpdateResource function closes the handle.

After an update handle to an executable file is created by using BeginUpdateResource, an application can use UpdateResource repeatedly to make changes to the resource data. Each call to UpdateResource contributes to an internal list of additions, deletions, and replacements but does not actually write the data to the executable file. Immediately before closing the update handle, EndUpdateResource writes the accumulated changes to the executable file.

Sometimes, an application must copy resources or find resource sizes. The LoadLibrary function provides a module handle to an executable file whose resources are to be copied, and the LockResource function provides a pointer to the resource data in the specified module. The SizeofResource function returns the size, in bytes, of a specified resource.


  51.1.3  Enumerating Resources

Three Windows functions enable an application to obtain lists of resource types, names, and languages in a specified module. The EnumResourceTypes function provides a list of resource types found in the module, the EnumResourceNames function provides the name of each resource within a given type, and the EnumResourceLanguages function provides the language of each resource of a given name and type. These functions and their associated callback functions enable applications to create a list of all resources in a module. This process is described in Section 51.2.2, »Creating a Resource List«.


  51.2  Using Resources

This section illustrates how to use the Windows resource functions to add a resource to an executable file and to list all the resources in an executable file.


  51.2.1  Updating Resources

The following example copies a dialog box resource from one executable file, HAND.EXE, to another, FOOT.EXE, by following these steps:

1.	The LoadLibrary function loads the executable file HAND.EXE.

2.	The FindResource and LoadResource functions locate and load the dialog box resource named If from the file.

3.	The LockResource function returns a pointer to the dialog box resource data.

4.	The BeginUpdateResource function opens an update handle FOOT.EXE.

5.	The UpdateResource function copies the dialog box resource from HAND.EXE to FOOT.EXE.

6.	The EndUpdateResource function completes the update.

The following code implements these steps.

HRSRC hResLoad;     /* handle to loaded resource         */

HANDLE hExe;        /* handle to existing .EXE file      */

HRSRC hRes;         /* handle/ptr. to res. info. in hExe */

HANDLE hUpdateRes;  /* update resource handle            */

char *lpResLock;    /* pointer to resource data          */

BOOL result;

/* Load the .EXE file that contains the dialog box you want to copy. */

hExe = LoadLibrary("hand.exe");

if (hExe == NULL) {

    ErrorHandler("Could not load exe.");

}

/* Locate the dialog box resource in the .EXE file. */

hRes = FindResource(hExe, "AboutBox", RT_DIALOG);

if (hRes == NULL) {

    ErrorHandler("Could not locate dialog box.");

}

/* Load the dialog box into global memory. */

hResLoad = LoadResource(hExe, hRes);

if (hResLoad == NULL) {

    ErrorHandler("Could not load dialog box.");

}

/* Lock the dialog box into global memory. */

lpResLock = LockResource(hRes);

if (lpResLock == NULL) {

    ErrorHandler("Could not lock dialog box.");

}

/* Open the file to which you want to add the dialog box resource. */

hUpdateRes = BeginUpdateResource("foot.exe", FALSE);

if (hUpdateRes == NULL) {

    ErrorHandler("Could not open file for writing.");

}

/* Add the dialog box resource to the update list. */

result = UpdateResource(hUpdateRes,     /* update resource handle     */

             RT_DIALOG,                 /* change dialog box resource */

             "AboutBox",                /* dialog box name            */

             MAKELANGID(LANG_NEUTRAL,

                 SUBLANG_NEUTRAL),      /* neutral language ID        */

             lpResLock,                 /* ptr to resource info       */

             SizeofResource(hExe, hRes)); /* size of resource info.   */

if (result == FALSE) {

    ErrorHandler("Could not add resource.");

}

/* Write changes to FOOT.EXE and then close it. */

if (!EndUpdateResource(hUpdateRes, FALSE)) {

    ErrorHandler("Could not write changes to file.");

}

/* Clean up. */

if (!FreeLibrary(hExe)) {

    ErrorHandler("Could not free executable.");

}


  51.2.2  Creating a Resource List

The following example creates a list of every resource in the HAND.EXE file. The list is written to the RESINFO.TXT file.

The code demonstrates how to load the executable file, create a file in which to write resource information, and call the EnumResourceTypes function to send each resource type found in the module to the EnumTypesFunc function, an application-defined callback function. This callback function uses the EnumResourceNames function to pass the name of every resource within the specified type to the EnumNamesFunc function, another application-defined callback function. EnumNamesFunc uses the EnumResourceLanguages function to pass the language of every resource of the specified type and name to the EnumLangsFunc function, a third callback function. EnumLangsFunc writes information about the resource of the specified type, name, and language to the RESINFO.TXT file.

char szBuffer[80]; /* print buffer for EnumResourceTypes         */

DWORD cbWritten;   /* number of bytes written to res. info. file */

int cbString;      /* length of string in sprintf                */

/* Declare callback functions. */

BOOL EnumTypesFunc(

    HANDLE hModule,

    LPTSTR lpType,

    LONG lParam);

BOOL EnumNamesFunc(

    HANDLE hModule,

    LPCTSTR lpType,

    LPTSTR lpName,

    LONG lParam);

BOOL EnumLangsFunc(

    HANDLE hModule,

    LPCTSTR lpType,

    LPCTSTR lpName,

    WORD wLang,

    LONG lParam);

/* Load the .EXE whose resources you want to list. */

hExe = LoadLibrary("hand.exe");

if (hExe == NULL) {

    ErrorHandler("Could not load .EXE.");

}

/* Create a file to contain the resource info. */

hFile = CreateFile("resinfo.txt",      /* name of file    */

    GENERIC_READ | GENERIC_WRITE,      /* access mode     */

    0,                                 /* share mode      */

    (LPSECURITY_ATTRIBUTES) NULL,      /* no security     */

    CREATE_ALWAYS,                     /* create flags    */

    FILE_ATTRIBUTE_NORMAL,             /* file attributes */

    (HANDLE) NULL);                    /* no template     */

if (hFile == INVALID_HANDLE_VALUE) {

    ErrorHandler("Could not open file.");

}

/* Find all of the loaded file's resources. */

cbString = sprintf(szBuffer,

    "The file contains the following resources:\n\n");

WriteFile(hFile,           /* file to hold resource info. */

    szBuffer,              /* what to write to the file   */

    (DWORD) cbString,      /* number of bytes in szBuffer */

    &cbWritten,            /* number of bytes written     */

    NULL);                 /* no overlapped I/O           */

EnumResourceTypes(hExe,              /* module handle     */

    (ENUMRESTYPEPROC)EnumTypesFunc,  /* callback function */

    0);                              /* extra parameter   */

/*

 * Unload the executable file whose resources were

 * enumerated and close the file created to contain

 * the resource information.

 */

FreeLibrary(hExe);

CloseHandle(hFile);

/********************************************************

    FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)

    PURPOSE:  Resource type callback

*********************************************************/

BOOL EnumTypesFunc(

    HANDLE hModule,   /* module handle             */

    LPTSTR lpType,    /* address of resource type  */

    LONG lParam)      /* extra parameter, could be */

                      /* used for error checking   */

{

    int cbString;

    /*

     * Write the resource type to a resource information file.

     * The type may be a string or an unsigned decimal

     * integer, so test before printing.

     */

    if ((ULONG)lpType & 0xFFFF0000) {

        cbString = sprintf(szBuffer, "Type: %s\n", lpType);

    }

    else {

        cbString = sprintf(szBuffer, "Type: %u\n", (USHORT)lpType);

    }

    WriteFile(hFile, szBuffer, (DWORD) cbString,

        &cbWritten, NULL);

    /* Find the names of all resources of type lpType. */

    EnumResourceNames(hModule,

                      lpType,

                      (ENUMRESNAMEPROC)EnumNamesFunc,

                      0);

    return TRUE;

}

/********************************************************

    FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)

    PURPOSE:  Resource name callback

*********************************************************/

BOOL EnumNamesFunc(

    HANDLE hModule,   /* module handle             */

    LPCTSTR lpType,   /* address of resource type  */

    LPTSTR lpName,    /* address of resource name  */

    LONG lParam)      /* extra parameter, could be */

                      /* used for error checking   */

{

    int cbString;

    /*

     * Write the resource name to a resource information file.

     * The name may be a string or an unsigned decimal

     * integer, so test before printing.

     */

    if ((ULONG)lpName & 0xFFFF0000) {

        cbString = sprintf(szBuffer, "\tName: %s\n", lpName);

    }

    else {

        cbString = sprintf(szBuffer, "\tName: %u\n",

                      (USHORT)lpName);

    }

    WriteFile(hFile, szBuffer, (DWORD) cbString,

        &cbWritten, NULL);

    /*

     * Find the languages of all resources of type

     * lpType and name lpName.

     */

    EnumResourceLanguages(hModule,

                          lpType,

                          lpName,

                          (ENUMRESLANGPROC)EnumLangsFunc,

                          0);

    return TRUE;

}

/*************************************************************

    FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)

    PURPOSE:  Resource language callback

**************************************************************/

BOOL EnumLangsFunc(

    HANDLE hModule,  /* module handle            */

    LPCTSTR lpType,  /* address of resource type */

    LPCTSTR lpName,  /* address of resource name */

    WORD wLang,      /* resource language        */

    LONG lParam)     /* extra parameter, could be

                        used for error checking  */

{

    HANDLE hResInfo;

    char szBuffer[80];

    int cbString = 0;

    hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);

    /* Write the resource language to the resource information file. */

    cbString = sprintf(szBuffer, "\t\tLanguage: %u\n",

                  (USHORT)wLang);

    WriteFile(hFile, szBuffer, (DWORD) cbString,

        &cbWritten, NULL);

    /* Write the resource handle and size to buffer. */

    cbString = sprintf(szBuffer,

                  "\t\thResInfo == %lx,  Size == %lu\n\n",

                  hResInfo,

                  SizeofResource(hModule, hResInfo));

    WriteFile(hFile, szBuffer, (DWORD) cbString,

        &cbWritten, NULL);

    return TRUE;


  51.2.3  Functions

Following are the functions used with resources.

BeginUpdateResource
EndUpdateResource
EnumResLangProc
EnumResNameProc
EnumResourceLanguages
EnumResourceNames
EnumResourceTypes
EnumResTypeProc
FindResource
FindResourceEx
LoadResource
LockResource
SizeofResource
UpdateResource


Registry and Initialization Files
  Chapter 52    Registry and Initialization Files

52.1  About the Registry and Initialization Files

In Microsoft Windows, applications use initialization files to store information that otherwise would be lost when the application closes. These files typically contain such information as user preferences for the configuration of the application. Initialization files, however, have the following inherent limitations:

•	Information in initialization files is typically available only to the application that put it there.

•	The text format of initialization files allows casual manipulation by potentially naive end users.

•	Separate initialization files for many applications can proliferate on a hard disk.

•	There is no way to secure initialization files against tampering.

•	Initialization files do not support multiple users.

•	Initialization files do not support for multiple versions of the same app.

•	Initialization files are not recoverable.

•	Information in initialization files cannot be accessed or administered remotely in any consistent way.

Microsoft Windows version 3.1 included a new feature: a registration database. A registration database contains information that supports shell applications (such as Windows File Manager) and applications that use object linking and embedding (OLE). Each piece of information in the database is identified by a key, which may have a value (data) associated with it. Windows 3.1 introduced a set of functions to support querying and setting information in the database. This database was not meant as a place for applications to store private configuration information; initialization files were required for that purpose.

The Win32 application programming interface (API) expands the usefulness of the version 3.1 registration database in two fundamental ways; the database now uses more keys and each key can hold more data. The new database is called the registry. The functions that manipulate the registration database in Windows 3.1 work with the Win32 registry, but some of them have been superseded in the Win32 API by extended versions.

The purpose of the registry is to meet the following goals:

•	Provide one source for configuration information, making initialization and configuration files (such as CONFIG.SYS and WIN.INI) obsolete.

Many of these files, however, are maintained for compatibility with previous versions of Windows or Windows apps.

•	Enumerate, track, and configure the applications, device drivers, and operating system control parameters.

•	Enumerate and track the hardware on a computer.

•	Standardize the user interface for configuration information through the use of Windows Control Panel.

•	Reduce the likelihood of syntactic errors in configuration information.

•	Separate user-, application-, and computer-related information, so that separate data for multiple users can be maintained on a single computer.

•	Provide security for configuration data. This security prevents unauthorized changes to critical data but allows users direct control over matters of personal preference.

•	Provide a set of network-independent functions for setting and querying configuration information and enable direct examination of configuration data over a network.

•	Provide storage that is recoverable after system crashes.

•	Provide atomicity of edits.

Applications, device drivers, and the system itself use the registry api to store and retrieve data. The registry stores this data in files which appear in the file system. These files are in a private binary format, and are held open for exclusive access, so apps cannot write to them directly, but must use the api instead.


  52.1.1  Structure of the Registry

The registry is stored in binary format in a series of files in the SYSTEM32 directory of Microsoft Windows NT. (Hives that contain user profiles may reside elsewhere.) These files correspond to hives; that is, discrete bodies of registry information, rooted at the top of the registry hierarchy. The size of the registry is user-configurable, limited only by system resources. The default registry size limit is one-fourth the size of the system's paged pool size.

Data in the registry is in the form of a hierarchically structured tree. Each entry node in the tree is called a key. The registry is something like a file system, in that each key can contain both subkeys (analogous to directories) and data entries (analogous to files).

Applications use the registry in much the same way as they use initialization files, as a place where information can be stored and retrieved.

Sometimes, the presence of a key is all the information that an application requires; other times, an application opens a key and uses the data associated with that key. For the Windows 3.1 registration database, this data was in the form of a string. For the Win32 registry, a key can have any number of data entries, and the data can be in any form. Each data entry is called a value.

Each key can contain the following items.

Key component	Description
Name	String used to gain access to the key. This name must be unique relative to other subkeys at the same level in the hierarchy (that is, KeyA and KeyB could each have a subkey KeyC, but KeyA could not have two KeyC subkeys). A key name cannot contain backslash (\) or null characters. This key component is required.
Class	Object class name. Intended for use in associating class method code with class instances stored in the registry. Not normally used by apps. This key component is optional.
Security Descriptor	Keys use standard Windows NT security descriptors, and can thus express auditing control and full access control. Normal security inheritance rules apply. This is key component is optional.
Last write time	A time stamp indicating the last time the key was modified. Any change to a value is considered a modification of the value's parent key.
Value(s)	Zero or more pieces of information to be stored with the key. This key component is optional. A value consists of the following three parts.
Value component	Description
Name	Identifies the value. The name can be up to 32,767 Unicode characters (65,534 bytes) in size. Backslash characters (\) are legal in value names. A NULL name (that is, "") is also legal to allow compatibility with Windows 3.1.
Type	Defines the type of data stored in this value. In Windows 3.1, this type was always REG_SZ, designating a null-terminated string. In the Win32 API, types are defined for most data formats. Although the system does not use this type information, applications should use the predefined types so that registry tools can find and manipulate the value data. Types with values below 0x7fffffff are reserved for system use.
Data	Specifies user data of arbitrary length and format. May not exceed 1 megabyte in Windows NT 3.1 release.
All name strings in the registry are stored in Unicode format. The registry preserves the case of any strings stored in the registry but ignores the case in all operations. (Data stored in the Data section of values is arbitrary, but strings should be stored as Unicode there as well.) For more information about Unicode, see Chapter 53, »String Manipulation and Unicode«.

The registry enforces a rule of atomicity: for any value entry, a given change either either occurs in its entirety, or the change does not occur at all. This means that the name, type, size, and data will always match, and all of the data in the value entry will be consistent. This is true even if the system crashes while a value entry is being updated. Keys are always consistent with the value entries they contain; to repeat, this is true even if the system crashes during an update.

Consistency amoung multiple values of the same key, or multiple keys, is NOT enforced by the system. Applications that write multiple values and require that they be consistent with one another must build their own transaction mechanism on top of the Registry's atomicity enforcement mechanism.

Whenever an application opens a key, it must supply the handle of another key in the registry that is already open. The system defines four standard handles that are always open. An application can use the following predefined handles as entry points to the registry.

Entry Points	Use
HKEY_CLASSES_ROOT	Registry entries subordinate to this handle define types (or classes) of documents and the properties associated with these classes.
	This is the entry point used in Windows version 3.1; the information it contains has not changed for Windows NT.
	Information stored under this handle is used by Windows shell applications and by OLE applications. Filename extensions are associated with applications that can work with files of that type. The OLE information includes the server command line, appropriate data types, and the action taken by an activated OLE object. This handle is an alias for HKEY_LOCAL_MACHINE, Software\Classes.
HKEY_CURRENT_USER	Registry entries subordinate to this handle define the preferences of the current user. These preferences include the settings of environment variables, information about program groups, colors, printers, network connections, and application preferences. The information for this handle is stored under the HKEY_USERS key.
HKEY_LOCAL_MACHINE	Registry entries subordinate to this handle define the configuration state of the system, including information about the bus type, system memory, and installed hardware and software.
HKEY_USERS	Registry entries subordinate to this handle define the default user configuration for users on the local computer and the user configuration for the current user. (User profiles appear as subtrees under this handle, the HKEY_CURRENT_USER is an alias to the profile of the current user.)
By convention, data in HKEY_CURRENT_USER overrides similar data in HKEY_LOCAL_MACHINE. That is, per-user preferences should normally override per-machine defaults. However, the system does not enforce this convention; it is the responsibility of application code to do so.

Standardized keys help an application navigate in the registry and make it possible to develop tools that a system administrator can use to manipulate categories of information. Applications that add data to the registry should always work within the framework of predefined keys, so that the administrative tools can find and use the new data. There are many predefined keys in addition to the four entry points already discussed; they are listed later in this chapter.

To see the contents of the registry, developers can run the Registry Editor (REGEDT32.EXE), a Windows application that ships with Windows NT. This application is not meant to be used as a standard means of modifying the registry. However, using it is an excellent way to get acquainted with the contents of the registry and to monitor changes to the registry's contents.


  52.1.2  Mapping and Initialization Files

Many benefits of the registry are available even to applications that do not explicitly write information to it or read information from it. When an application uses a profile or private profile function to get or set information in a configuration or initialization file, the function may be mapped to the registry instead of to the specified file. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

The system is likely to map function calls to the registry if an application modifies system-component initialization files, such as WIN.INI, SYSTEM.INI, CONTROL.INI, and WINFILE.INI. The change in the storage location has no effect on the GetPrivateProfileInt function's behavior.

Applications can use the IniFileMapping key to simplify their installation procedure. To do this, an application can use an installation routine that calls such functions as GetPrivateProfileString and WritePrivateProfileString. It can use this routine to write either to the registry or to a private initialization file, depending on whether the host system is running Windows NT. For example, if an application writes to an initialization file named ABC.INI, it can use its standard initialization routine to read from and write to the registry by adding a subkey named ABC.INI to the IniFileMapping key.


  52.2  Structure of HKEY_LOCAL_MACHINE

Note   The arrangement of registry information may have changed since the publication of this book.

Most applications store information under the HKEY_LOCAL_MACHINE key during their installation procedure. This key contains information specific to the local computer, irrespective of the user. Information such as the name and version of the installing software, the capabilities of OLE-enabled applications, and the names and types of device drivers are stored in this key.

The HKEY_LOCAL_MACHINE key has five subkeys: Hardware, Security, Sam, Software, and System. Applications can query Hardware, Software, and System. They may write to Software and System.


  52.2.1  Hardware

The Hardware key is a volatile key, constructed from information gathered by the system each time it starts. This key contains information an application can query to determine the type and state of physical devices attached to the local computer, the resources claimed by various device drivers, and the relationships between device drivers. Applications cannot set information in this key, since this key is overwritten whenever the computer is restarted.

The Hardware key contains three subkeys: Description, DeviceMap, and ResourceMap.


  52.2.1.1  Description

The Description subkey of the Hardware key contains information that describes the hardware on the local computer. Each piece of hardware is described by the following named values.

Named value	Contents
Component information	Binary data that identifies the component
Identifier	String that names the component
Configuration data	Binary data that gives the configuration of the component
The structure of the tree under the Description key varies somewhat with the type of computer (ISA, EISA, ARC, etc) and the bus structure of the computer. (How many and what types of buses does it have.)

The general layout is a key whose name identifies a general object type such as "CentralProcessor" or "EisaAdapter." Under that key will be keys named "0," "1," etc, representing various instances of the object. If the object is a container object (e.g. a bus) then the structure is repeated below it. Thus, one might find a key named

 ...\Description\EisaAdapter\0\DiskController\0

and another key named

 ...\Description\EisaAdapter\1\DiskController\2

The first key describes the 0th disk controller on the first EISA bus on the machine. The second key describes the 2th disk controller on the second EISA bus on the machine.

An application looking for a particular type of device needs to walk the tree and find all instances of that device (e.g. "DiskController") throughout the tree, if it wants to find all of the devices.

Note that a key like ...\EisaAdapter\0 can have value entries that report configuration data about the bus itself, and configuration data that can be read from the bus, but which the system cannot interpret.


  CentralProcessor

The CentralProcessor subkey contains numbered keys corresponding to the number of CPUs on the local computer. If there is only one CPU, subkey 0 describes it. The values of these keys reveal model and stepping data for the processors, among other things.


  MultifunctionAdapter

The MultifunctionAdapter subkey contains zero-based numbered keys corresponding to the number of multifunction adapters (bus controllers) on the local computer. Each numbered key contains the following zero-based numbered keys.

Key	Contents
DiskController	Keys corresponding to the disk controllers. Floppy disk drives are listed under the FloppyDiskPeripheral subkey of each numbered DiskController key. The values describing each floppy disk drive are associated with numbered subkeys of FloppyDiskPeripheral.
DisplayController	Keys corresponding to the display controllers. Displays are listed under the MonitorPeripheral subkey of each numbered DisplayController key. The values describing each display are associated with numbered subkeys of MonitorPeripheral.
KeyboardController	Keys corresponding to the keyboard controllers. Keyboards are listed under the KeyboardPeripheral subkey of each numbered KeyboardController key. The values describing each keyboard are associated with numbered subkeys of KeyboardPeripheral.
ParallelController	Keys corresponding to the controllers for the parallel ports.
PointerController	Keys corresponding to the pointer controllers. Pointers are listed under the PointerPeripheral subkey of each numbered PointerController key. The values describing each pointer are associated with numbered subkeys of PointerPeripheral.
SerialController	Keys corresponding to the controllers for the serial ports.


  52.2.1.2  DeviceMap

The DeviceMap subkey of the Hardware key maps devices to their drivers. Each key contained by DeviceMap contains one or more named values indicating the location in the registry for the relevant driver information. For example, the PointerPort key may have only the following value, if the local computer has a single mouse device:

\Device\PointerPort0 : REG_SZ :
\REGISTRY\Machine\System\ControlSet001\Services\Inport

In this example, colons separate the name, type, and data elements of the value. This example is displayed on two lines here for formatting reasons; there is no line break in the value data.

This path allows the system to find information about the mouse driver. This information is stored under the following keys:

HKEY_LOCAL_MACHINE\System\ControlSet001\Services\Inport

The DeviceMap key typically contains the following keys:

Keyboard Class
Keyboard Port
Parallel Ports
Pointer Class
Pointer Port
Serialcomm
Video
SCSI


  52.2.1.3  ResourceMap

The ResourceMap subkey of the Hardware key maps device drivers to lists of resources that the drivers use. Applications do not write this data, however, they may read it to understand how resources such as interrupts and dma channels are allocated on the system. For example, an installation program can read the resource map to compute which of the interrupt vectors the card it supports can use are not already in use elsewhere in the system.

Application writers who require further information on resource maps should study the header file NTConfig.h. The application WinMSD.exe allows examination of resource map data.


  52.2.2  Security and SAM

The Security and SAM keys contain all of the security information for the local computer. None of the keys contained by Security or SAM can be modified by an application. Applications that must query security information should use the security functions to do so. For more information about security, see Chapter 49, »Security«.


  52.2.3  Software

The Software key contains information about the software on the local computer that is independent of per-user configurations. That is, this key contains such information as the manufacturer and version number of software. This key also contains file associations and OLE information.

The Software key can contain many subkeys, but three are of prime importance: Classes, Company name, and Program Groups. (Company name is a placeholder for an actual company name, of which there may be many on a given system.)


  52.2.3.1  Classes

The Classes subkey of the Software key defines types (or classes) of documents. Windows shell applications and OLE applications use the information stored here. Filename extensions are associated with applications that can work with files of that type. OLE information includes the server command line, appropriate data types, and the action taken by an activated OLE object.

The HKEY_CLASSES_ROOT entry-point handle maps to the HKEY_LOCAL_MACHINE\Software\Classes key.

The Classes key contains two kinds of keys: filename-extension keys, which indicate the application associated with files whose names have that extension, and class-definition keys, which indicate the shell and OLE properties of documents in that class.


  Filename-Extension Keys

The names of filename-extension keys are in the form .ext. An .ext key defines all files with that extension as members of a specified class. The registering application specifies the document class for an extension in the value associated with the .ext key name.

The .ext key name associates a class with a specific filename extension. For example, if a voice-annotation application named TALK.EXE were registered as an OLE server, it might use .tlk as the filename-extension key and use "Talk" as the value of that key. The application would then create a "Talk" key as the class-definition key.


  Class-Definition Keys

The names of class-definition keys are the names of document classes. For example, if a voice-annotation application uses .tlk as a filename-extension key and uses "Talk" as the value of that key, it would also use "Talk" as a class-definition key. The application would record its name (for example, "Talk Voice Annotation") as the value of the class-definition key.

Registry entries that are subordinate to the class-definition keys describe the properties of a class. The registry can describe two kinds of document properties for each class of document: shell properties and protocol properties.

Shell properties describe how a document of a given class interacts with Windows shell applications. There are two key names for shell properties: open and print. The open properties describe how the class responds to a request from a Windows shell application to open a document. The print properties describe how the class responds to a request from Windows Print Manager to print a document. Both the open and print keys must have the command subkey. The value assigned to command specifies the command line used to run the application. If appropriate, this value can include command-line options. For example, the value of the open key for Paintbrush (PBRUSH.EXE) is "pbrush.exe %1."

If an application supports dynamic data exchange (DDE), it can also define the ddeexec subkey for either or both of the open and print key names. The value specified for the ddeexec key name is treated as a DDE command. Defining ddeexec is particularly useful if an application already supports DDE open and print commands. Using DDE messages can add flexibility, particularly for applications that support multiple document interface (MDI), because a DDE message string can include more than one command. The ddeexec key subkeys contains the following.

Key	Contents
application	Application name to use in establishing the DDE conversation. If the registering application does not specify an application key, the system uses the application name specified in the command key.
topic	Topic name of the DDE conversation. If the application does not register a topic key, the system uses the System topic as the default topic name.
ifexec	DDE command to use when initiation of the DDE conversation fails (for example, if the application is not running). When the initiation fails, the command specified by the command key is carried out and then the string specified with the ifexec key is sent. (If an application does not specify a value for the ifexec key, the command specified by the command key is executed when initiation fails and the string specified with the ddeexec key is sent again.)
For more information about DDE, see Chapter 26, "Dynamic Data Exchange," in Microsoft Win32 Programmer's Reference, Volume 1 and Chapter 77, »Dynamic Data Exchange Management Library«.

Protocol properties are the second kind of document properties the registry can describe for each class of document. A protocol is a convention for manipulating a document or some other collection of data. The Protocol key contains keys that describe the properties of a protocol. Although a class can support any number of protocols, currently only two are defined. Both protocol names are used as key names. The most common protocol, StdFileEditing, is used by all documents that support OLE. The second protocol, StdExecute, is used by OLE client applications that must send DDE execute commands to OLE server applications. For more information about using these protocols, see the OLE documentation.

The StdFileEditing protocol contains the following subkeys:

Key	Description
server	Command line that an OLE client application uses to start the server application for a linked or embedded object.
handler	Name of a dynamic-link library (DLL) that acts as an object handler for OLE objects.
verb	This key does not have a value. Subkeys identify the kind of action a server should take when it opens an object. These subkeys are consecutive numbers, beginning with zero. The 0 subkey corresponds to the primary verb for the objects supported by the server. For example, the value for 0 is often "Edit" and the value for the 1 subkey is often "Play."


  52.2.3.2  Company Name

The Company name keys of the Software key contain the names and version numbers of the software installed on the local computer. (Company name is a placeholder for the name of the company that produced the software.) Installing applications should record this information in the following form:

HKEY_LOCAL_MACHINE\Software\CompanyName\ProductName\Version

This information is specific to the local computer; information about the configuration of the application is stored on a per-user basis under the HKEY_CURRENT_USER key.


  52.2.3.3  Program Groups

The Program Groups subkey of the Software key contains the common program groups.They are program groups that are used in common by all users of the computer. (A program group is a window in Program Manager containing icons that represent applications.) The program groups for individual users are stored elsewhere in the registry, for example, in HKEY_CURRENT_USER\Program Groups. The name of each subkey of the Program Groups key is the name of a common program group. The value of each of these subkeys is binary data describing the common program group. Applications should use the shell dynamic data exchange (DDE) interface to modify this data. For more information about shell DDE, see Chapter 84, »Shell Dynamic Data Exchange Interface«.


  52.2.4  System

The System key contains information about devices and services. Information that Windows and Windows-based applications retrieved from the CONFIG.SYS configuration file in previous versions of Windows is now stored under this key. Applications that provide device drivers or services add or modify information under this key. The System key contains the following keys:

ControlSetnnn
Select
Setup
Clone
CurrentControlSet

These keys are described in detail in the following sections.


  52.2.4.1  ControlSetnnn

The ControlSetnnn subkeys for the System key describe control sets. A control set is a set of configurable options for a particular computer. A computer will have more than one ControlSetnnn subkey after it has booted. However, only one ControlSetnnn subkey is in use at any time. The CurrentControlSet key is an alias for the ControlSetnnn key that is currently in use. It provides a symbolic link to that key.

Applications typically do not modify the information in the ControlSetnnn keys; modifications to configuration information are usually made through the CurrentControlSet key.

When the system starts, it obtains configuration information from a ControlSetnnn key. One of the system's first startup actions is to store a copy of that startup ControlSetnnn key as the Clone key for safekeeping. When the system determines that it has successfully booted, it copies the Clone key to another ControlSetnnn key, and makes the Clone key inaccessible. The CurrentControlSet key is an alias to the particular ControlSetnnn key used to start the system. The second ControlSetnnn key, copied from Clone, is kept as a safety backup. Its configuration information has proven to be capable of starting the system.

Thus, the ControlSetnnn keys prevent incorrect configuration information from creating a computer that cannot be started. If, during a system boot, the configuration information in the startup ControlSetnnn key prevents the system from starting up, the system switches to the safety backup ControlSetnnn key. The system uses that backup ControlSetnnn key to complete the startup routine. It is the last known good key. Its identity is stored in the Select key. For more information about this procedure, see Section 52.2.4.2, »Select«.

Each ControlSetnnn key has two subkeys: Control and Services.


  Control

The Control subkey of the ControlSetnnn key contains configuration information for the computer. The Control key contains the following keys.

Key	Contents
ComputerName	Two keys, ComputerName and ActiveComputerName, specifying the names of the default and active computers.
GroupOrderList	Specifies the load order of drivers within a group.
Keyboard Layout	Available DLLs for the keyboard layout, and which one is used as the default layout.
Lsa	Authentication package for the local security authority.
NetworkProvider	Two keys named: Active and Order. The Active key contains one or more subkeys that specify the active network provider, for example, LanmanWorkstation. The Order key has no subkeys; its value specifies the order in which the system should load these providers.
Nls	Information about national language support. The Nls key contains three subkeys: CodePage, Language, and OEMLocale. The values for the CodePage subkey specify the available code pages. The values for the Language subkey specify the available languages and the default setting.
Print	Information about the current printers and printing environment. This key can contain the following subkeys:
Subkey	Contents
Environments	This key does not have a value. Subkeys of this key have the names of environments, for example, Windows NT x86 or Windows NT R4000. Each Environment key has two subkeys: Drivers and Print Processors.
	Drivers keys have subkeys whose names are printer drivers. The values of these subkeys are driver specific.
	Print Processors keys have a single value that specifies the print processor, for example, "WinPrint."
Monitors	Subkeys of this key have the names of network printing monitors. The names, as well as any subkeys and values are monitor specific.
Printers	This key does not have a value. Subkeys of this key have the names of installed printers. Each subkey has named values that describe the printer parameters. The printer subkeys can each contain a subkey named PrinterDriverData.
ProductOptions	Product type, for example, "Windows."
ServiceGroupOrder	Order in which the system loads services. The data required for some of the services is stored in the GroupOrderList key.
Session Manager	Global variables used by the session manager and the following subkeys:
Subkey	Contents
DOS Devices
	MS-DOS devices, such as "PRN," "AUX," "NUL," "PIPE," "MAILSLOT," and "UNC."
Environment
	Environment variables, such as "ComSpec," "Os2LibPath," "LibPath," "Path," "NtVersion," and "WinDir."
KnownDLLs
	Directory in which session-manager DLLs are stored and the names of those DLLs. The named values are "DllDirectory," "kernel32," "gdi32," "user32," "rpcrt4," and "advapi32."
Memory Management
	Paging options. The named values are "PagedPoolSize," "NonPagedPoolSize," and "PagingFiles."
SubSystems
	Available subsystems. The named values are "Required," "Optional," "Debug," "Windows," "Os2," and "Posix."
Setup	Hardware setup options. The named values are "Video," "Pointer," and "Keyboard."
TimeZoneInformation	Named values for time-zone information: "Bias," "StandardName," "StandardStart," "StandardBias," "DaylightName," "DaylightStart," "DaylightBias," and "ActiveTimeBias."
VirtualDeviceDrivers	Virtual-device drivers.
Windows	Directory and system directory for Windows. The named values are "Directory" and "SystemDirectory."
WOW	Options for Windows-on-Windows. The named values are "LogonSwitch," "cmdline," "size," "wowcmdline," and "wowsize."
hivelist	Location of the files that contain registry information. There is value for each hive, giving the path of the file backing that hive.


  Services

The Services subkey of the ControlSetnnn key contains information about device drivers, file systems, hardware adapters, and service programs used by the computer.

Each subkey of the Services key is the name of a service (e.g. a device driver) Each subkey has at least four named values: "Type," "Start," "Group," and "ErrorControl." Most driver keys also use either the "Dependencies" or "Tag" value name.

When a subkey of the Services key contains a key, that key is either Linkage or Parameters. The named values of the Linkage key specify link options for the driver; the named values are Bind and Export. The named values for the Parameters key vary according to the device driver.


  52.2.4.2  Select

The Select subkey of the System key contains information about the control set for the local computer. This key contains no subkeys, but it has the following named values.

Named value	Contents
Current	Control set from which the CurrentControlSet key is derived. If this value is 0x1, the key producing CurrentControlSet is ControlSet001.
Default	Default control set. If this value is 0x1, the default control set is ControlSet001.
LastKnownGood	Last control set that successfully started the system. If this value is 0x1, the last control set known to be good is ControlSet001.
Failed	Flag indicating whether the control set identified by the "Default" value successfully started the system. If this value is 0, the default control set was successful. If it is 1, the system could not use the default control set to start, and the "Current" and "LastKnownGood" values identify the control set that was used instead.
System administrators can use these values to verify that applications that write information to the System key are successfully modifying the registry.


  52.2.4.3  Setup

The Setup subkey of the System key contains values that identify the setup type and command line. The named values are "SetupType" and "CmdLine."


  52.2.4.4  Clone

The Clone subkey of the System key is a copy of the control set used to start the system. The system makes the copy before any changes are made to the control set. Making a copy before any changes can occur helps ensure that the computer always has a working control set.

If the system starts successfully, this key is identified by the "LastKnownGood" value. For more information about this value, see Section 52.2.4.2, »Select«.


  52.2.4.5  CurrentControlSet

The CurrentControlSet subkey of the System key contains the current configuration information for the local computer. The information in this key is in exactly the same form as the information for ControlSetnnn, which is described in Section 52.2.4.1, »ControlSetnnn«.


  52.3  Structure of HKEY_USERS

The HKEY_USERS key contains a .DEFAULT subkey and one or more subkeys whose names are the security identifiers (SIDs) of the users. The subkeys of the .DEFAULT key are a subset of the subkeys for the users' keys. The information in the .DEFAULT key is assigned to new accounts on the local system.

The registry information for each known user is stored directly in a separate file. By default, these files reside in the ...\SYSTEM32\CONFIG directory of Windows NT.

The HKEY_CURRENT_USER predefined handle is made to refer to the currently logged on user, it is reset each time someone logs on. The description of HKEY_CURRENT_USER in this section includes information that is also relevant for HKEY_USERS.

The HKEY_CURRENT_USER key contains the configuration information that is specific to the current user. This kind of information was previously stored in the WIN.INI initialization file. A user profile (that is, a set of configuration information) is saved for every user that logs on to the local computer. When a user logs on, the user's SID is compared against the known SIDs in the registry. If the system "knows" the SID for the user logging on, the system loads the profile for that user. Otherwise, the system uses the configuration information stored in HKEY_USERS\.DEFAULT.

For more information about security identifiers, see Chapter 49, »Security«.

The HKEY_CURRENT_USER key contains the following keys.

Key	Contents
Console	Subkeys that specify the options and window size for a console. (A console is an interface that provides input and output for character-mode applications.)
Control Panel	Subkeys that describe Windows Control Panel applications.
Environment	Values that specify the user's environment variables.
Keyboard Layout	Value that specifies the current keyboard layout.
Network	Subkeys that specify the redirected device (for example, a drive letter). Each subkey has four named values: "RemotePath," "UserName," "ProviderName," and "ConnectionType."
Printers	Value that specifies the default printer.
Program Groups	Subkeys that describe the user's program groups. (Note that common program groups are stored in HKEY_LOCAL_MACHINE\Software\ProgramGroups.)
Software	Subkeys that describe the user-configurable options of installed software. Every installing application and every application that stores user options writes information to this key.
The following sections describe these keys in more detail.


  52.3.1  Console

The Console subkey of the HKEY_CURRENT_USER key contains subkeys that specify the options and window size for a console. The Console key has one standardized subkey: Configuration.

The Configuration key contains named values that describe the configuration of the console. The names of the values are "FillAttr," "CommandRecallBufferSize," "ScreenBufferColumns," "ScreenBufferRows," "WindowColumns," and "WindowRows."

Additional keys describe the configuration of console applications. The key names are the names of the applications, and they vary from system to system.


  52.3.2  Control Panel

The Control Panel subkey of the HKEY_CURRENT_USER key contains subkeys that describe Control Panel applications. The following keys are defined.

Key	Contents
Color Schemes	Values that describe the color schemes for the Color Schemes section of the Colors application. The names of the values are the names of the color schemes, for example, "Arizona" and "Bordeaux."
Colors	Values that describe the colors of screen elements, from the Screen Elements section of the Colors application. The names of the values are the names of the screen elements, for example, "Desktop" and "Window Text."
Current	Value that describes the current color setting. The name of this value is "Color Schemes."
Custom Colors	Values that describe any custom colors the user has defined in the Custom Colors section of the Colors application. The names of the values are "ColorA" through "ColorP."
Desktop	Values that describe the settings of the options in the Desktop application. This key has the following values.
Value	Contents
CoolSwitch	Flag that is 1 when the ALT+TAB key combination causes the title and icon for each open application to appear on the screen, providing easy switching between applications. The value is 0 when ALT+TAB cycles through the open applications instead.
CursorBlinkRate	Any integer between 1200 (the slowest blink rate) and 200 (the fastest).
BorderWidth	Width of the border, in pixels.
ScreenSaveTimeOut	Number of seconds of inactivity before the screen saver is activated.
ScreenSaveActive	Flag that is 1 when the screen saver is active and 0 when it is not.
SCRNSAVE.SCR	No data. This value name specifies the file containing the default screen saver; there is no data associated with this value name.
Pattern	Description of the pattern chosen by the user in the Patterns section of the Desktop application. The data is a series of integers that describe the bitmap.
Wallpaper	Name of the bitmap file for the current wallpaper.
TileWallPaper	Flag that is 1 when the wallpaper is tiled and 0 when it is centered.
GridGranularity	Grid granularity, in pixels.
IconSpacing	Icon spacing, in pixels.
IconVerticalSpacing	Icon vertical spacing, in pixels.
IconTitleWrap	Flag that is 1 when the icon titles wrap and 0 when they do not.
IconTitleFaceName	Name of the font used for icon titles.
IconTitleSize	Size of the icon titles, in points.
IconTitleStyle	Style of the icon titles. When this value is 0, the default style is used.
International	Named values that specify settings in the International application. Values that begin with the letter "s" are strings, and values that begin with the letter "i" are integers.
Value	Description
Locale	Locale identifier.
sLanguage	Language.
sCountry	Country.
iCountry	Country code.
sList	List separator.
iMeasure	Flag that is 1 for the English system and 0 for metric.
sDecimal	Character used as a decimal separator.
sThousand	Character used as the separator between every three digits in numbers larger than 999.
iDigits	Default number of digits that follow the decimal separator character in decimal notation.
iLZero	Flag that is 1 if a zero precedes the decimal separator character when a number is less than one and 0 if no zero precedes the character.
sCurrency	Monetary symbol used to denote a currency value. This symbol is a dollar sign ($) in the United States.
iCurrDigits	Number of digits following the decimal separator character in currency values.
iCurrency	Placement of the monetary symbol in relation to the number in a currency value. The following values are defined.
Value	Meaning
0	$1
1	1$
2	$ 1
3	1 $
iNegCurr	Method used to denote a negative currency value. The values are defined.
Value	Meaning
0	($123.45)
1	-$123.45
2	$-123.45
3	$123.45-
4	(123.45$)
5	-123.45$
6	123.45-$
7	123.45$-
8	-123.45 $
9	-$ 123.45
10	123.45 $-
sDate	Character used to separate days, months, and years in dates.
sTime	Character used to separate hours, minutes, and seconds in time values.
sShortDate	Format used to report the short form of the date. The following values are defined.
Value	Meaning
M/d/yy	Month/day/last two digits of year
d/M/yy	Day/month/last two digits of year
yy/M/d	Last two digits of year/month/day
sLongDate	Format used to report the long form of the date. The following values are defined.
Value	Meaning
dddd, MMMM dd, yyyy	Day of week, month and date, year
dddd, dd MMMM, yyyy	Day of week, date and month, year
dddd, yyyy MMMM, dd	Day of week, year and month, date
iDate	Flag that is 0 for the M/d/yy short date format, 1 for the d/M/yy format, and 2 for the yy/M/d format.
iTime	Flag that is 0 for time reporting in a 12-hour format and 1 for a 24-hour format.
iCentury	Flag that is 0 for the year designated with a four-digit number and 1 for the year designated with a two-digit number.
iTLZero	Flag that is 0 for no zero preceding one-digit hours in time values and 1 for a leading zero.
iDayLZero	Flag that is 0 for no zero preceding one-digit days in dates and 1 for a leading zero.
iMonLZero	Flag that is 0 for no zero preceding one-digit months in dates and 1 for a leading zero.
s1159	Flag that is AM to designate that 11:59 is the last time prior to PM.
s2359	Flag that is PM to designate that 23:59 is the last time prior to AM.
Keyboard	Named values for the settings in the Keyboard application. This key has the following values.
Value	Contents
KeyboardSpeed	Keyboard repeat rate. The data is a value from 0 (the slowest rate) to 31 (the fastest).
KeyboardDelay	Delay, in seconds, before the keyboard begins to repeat. The data is a value from 3 (the longest delay) to 0 (the shortest).
InitialKeyboardIndicators	Initial keyboard indicators. The default setting is 0.
MMCPL	Named values specifying the number of applications in Control Panel, the dimensions of the Control Panel window, and the paths to any applications the user has added to Control Panel. The name of this key is derived from "Multimedia Control Panel." This key has the following values.
Value	Contents
NumApps	Number of applications in Control Panel.
X	X-coordinate of the upper left corner of the Control Panel window.
Y	Y-coordinate of the upper left corner of the Control Panel window.
W	Width of the Control Panel window, in pixels.
H	Height of the Control Panel window, in pixels.
Mouse	Named values that correspond to the options in the Mouse application. This key has the following values.
Value	Contents
SwapMouseButtons	Flag that indicates whether the functionality of the mouse buttons has been swapped. If the value is 0, they have not been swapped; if it is "Yes," they have.
DoubleClickSpeed	Duration required between two mouse clicks for them to be considered a double click, in milliseconds. The slowest setting is 900; the fastest setting is 100.
MouseThreshold1	Mouse threshold for mouse button number one, in pixels. (The mouse threshold is the maximum distance the mouse may move during a double-click without causing the system to interpret the event as two single clicks.) The minimum setting is 0; the maximum setting is 4.
MouseThreshold2	Mouse threshold for mouse button number two, in pixels. The minimum setting is 0; the maximum setting is 6.
MouseSpeed	Mouse tracking speed. The slowest setting is 0; the fastest setting is 2.
	The data for the mouse-threshold values is set by the system, not by options in the Mouse application.
Patterns	Named values corresponding to the patterns the user can specify in the Desktop application. The names of the values are the names displayed in the Pattern list box.
Screen Saver.name	Named values corresponding to the settings for each of the screen savers. The name portion of the key name identifies the screen saver, for example, "Marquee" or "Stars." The values for each key are dependent on the configuration options for that screen saver.
Sound	A named value, "Beep," whose data is "yes" if the beep is activated.


  52.3.3  Environment

The Environment subkey of the HKEY_CURRENT_USER key contains named values corresponding to the "user environment variables" the user can specify in the System application in Control Panel. The name of each value is the name of an environment variable, for example, "tmp" and "include." The data for each value is a path. In earlier versions of Windows, this information was stored in the AUTOEXEC.BAT file.


  52.3.4  Keyboard Layout

The Keyboard Layout subkey of the HKEY_CURRENT_USER key contains a value named "Active" that defines the current active keyboard layout. This value is set in the Keyboard Layout list box in the International application in Control Panel.


  52.3.5  Network

The Network subkey of the HKEY_CURRENT_USER key contains subkeys that specify the redirected device (for example, a drive letter). Each subkey has four named values: "RemotePath," "UserName," "ProviderName," and "ConnectionType."


  52.3.6  Printers

The Printers subkey of the HKEY_CURRENT_USER key contains a named value, "Default," whose data is the name of the default printer.


  52.3.7  Program Groups

The Program Groups subkey of the HKEY_CURRENT_USER key contains subkeys that describe the user's program groups. (Note that common program groups are stored in the HKEY_LOCAL_MACHINE\Software\Program Groups key.)


  52.3.8  Software

The Software subkey of the HKEY_CURRENT_USER key contains subkeys that describe the configurable settings of installed software. Every installing application that can be customized by the user or that saves its state when it closes should save that information in the Software key. This key contains most of the information that was stored in the WIN.INI initialization file and in private files in earlier versions of Windows.

The name of each key contained by the Software key should have the following form:

Software\CompanyName\ApplicationName\ApplicationVersion[\AnyRequiredSubkeys]

For example, the Windows NT Clock application (CLOCK.EXE) stores configuration information by using the following sequence of key names: Software\Microsoft\Clock. Values associated with the Clock key specify configuration information for the application.

Much of the configuration information for Windows is stored in the Software key as follows: Software\Microsoft\Windows NT\CurrentVersion. The CurrentVersion key contains the following keys.

Key	Contents
Extensions	Values that identify the executable files associated with specified filename extensions. For example, the value that associates filenames that have the .TXT extension with Windows Notepad is named txt; the data for this value is "notepad.exe ^.txt."
Print Manager	A value named "Print Manager" whose data is binary initialization information. This key contains a subkey, Printers. The Printers subkey contains values whose names are the current printers and whose data is also binary initialization information.
Program Manager	Keys that describe the configuration of Program Manager; these keys are Groups, Restrictions, and Settings.
	The Groups key contains values that describe the order of the program groups. The values are named "Group1" through "Groupn"; the data for each value is the name of a program group.
	The Restrictions key contains values that specify any restrictions for the current user when the user works with Program Manager. The data for each value is a flag in which 1 means the restriction is in force and 0 means that the restriction does not apply. The names of the values are "NoRun," "NoClose," "EditLevel," "Restrictions," "NoFileMenu," and "NoSaveSettings."
	The Settings key contains the following values describing the configurable settings for Program Manager.
Value	Contents
MinOnRun	Flag that indicates whether Program Manager should be minimized when it starts. The value is 1 to display Program Manager minimized and is 0 otherwise.
AutoArrange	Flag that indicates whether the icons in Program Manager are arranged automatically. The value is 1 to arrange them automatically and is 0 otherwise.
SaveSettings	Flag that indicates whether the settings are saved when Program Manager terminates. The value is 1 to save the settings and is 0 otherwise.
display.drv	Name of the display driver.
Window	Series of integers specifying the x- and y-coordinates of the upper left corner of the Program Manager window, its width, and its height.
Order	Series of integers that specify the order in which the program groups appear in the Program Manager window. The integers correspond to the group numbers specified by the Group subkey of the Program Manager key.
TrueType	Values corresponding to the TrueType options a user can set in the Fonts application in Control Panel. The "TTEnable" value is a flag that is 1 if TrueType fonts are enabled and 0 otherwise. The "TTonly" value is a flag that is 1 if only TrueType fonts are to be used and is 0 otherwise.
Windows	Values describing some of the configurable options of Windows. The values correspond to the [windows] section of the WIN.INI file. This key has the following values.
Value	Contents
load	Filenames or path and filenames for applications that are run minimized when Windows starts.
run	Filenames or the names of documents that are associated with filenames for applications that are run when Windows starts.
NullPort	Null port.
Programs	List of filename extensions identifying executable files, for example, "com exe bat pif cmd."


  52.4  Storing Information in the Registry

The registry is an excellent place to store relatively small amounts of initialization and configuration data. Although there are few technical limits to the type and size of data an application can store, there are practical guidelines for registry use that can make a large difference in system efficiency. Configuration and initialization data should be stored in the registry, but other kinds of information should be stored elsewhere.


  52.4.1  Storage Space

Generally, data of more than one or two kilobytes (K) should be stored as a file and referred to by using a key in the registry, rather than by being stored as a value. Rather than repeatedly duplicating large pieces of data in the registry, an application should save the data as a file and refer to the file. Executable images should never be stored in the registry, since a user's profile could be used on computers with different types of CPUs.

Storing information in the registry consumes far fewer resources than storing it in a file system. To store a byte of data as a file requires between 512 and 8000 bytes of overhead, depending on the file system. Storage in the registry is much more efficient than this. The following table shows the approximate amounts of storage space required by various parts of the registry:

Component	Approximate size
Security descriptor	20 bytes plus the size of the security descriptor itself
Value	38 bytes plus the value name plus the data
List of values	4 bytes per entry
List of subkeys	4 or 5 bytes per entry
Key	90 bytes plus the preceding items in this table.
A value entry uses much less space than a key, particularly when the size of a security descriptor is taken into account. To save space, applications should group similar data together as a structure and store the structure as a value, rather than storing each of the structure members as a separate key. (Storing the data in binary form allows an application to store data in one value that otherwise would be made up of several incompatible types.) A separate key should be used whenever unique access rights are required, because keys are protected by security descriptors.

The size of a single value entry is limited to one MB. The size of the registry is user-configurable, limited only by system resources. The default registry size limit is one-fourth the size of the system's paged pool.

For this version of Windows NT, no limits are imposed on the amount of information a single application can write to the registry. However, to avoid storage problems later, applications should use the registry only as specified in this section.


  52.4.2  Applications and the Registry

Before putting configuration and initialization data into the registry, applications should divide the data into two categories: computer-specific data and user-specific data. By making this distinction, an application can support multiple users, and yet locate user-specific data over a network and use that data in different locations, allowing location-independent profile information.

When the application is installed, it should record the computer-specific data under the HKEY_LOCAL_MACHINE key. In particular, it should create keys for the company name, product name, and version number, as in the following example:

HKEY_LOCAL_MACHINE\Software\CompanyName\ProductName\Version

If the application supports object linking and embedding, it should record that information under HKEY_LOCAL_MACHINE\Software\Classes, as described in Section 52.2.3.1, »Classes«.

An application should record user-specific data under the HKEY_CURRENT_USER key, as in the following example:

HKEY_CURRENT_USER\Software\CompanyName\ProductName\Version\...

Subkeys of this user-specific Version key are application specific.

In Windows 3.1, the preferred mechanism for changing the registration database was to produce a text file listing the entries and then merge them with the database by using a command-line option with Registry Editor (REGEDIT.EXE). Because key values in the Windows NT registry can be in any data format, this method for changing the registry is not supported in Windows NT.


  52.4.3  Changing User Profiles

If a server application must write to a specific user's initialization information, the application might have to circumvent the mapping specified in the IniFileMapping key. It can do this by using the following sequence of functions:

ImpersonateClient
OpenProfileUserMapping
WriteProfileString
CloseProfileUserMapping
RevertToSelf

The OpenProfileUserMapping and CloseProfileUserMapping functions enable the application to ensure that the correct HKEY_CURRENT_USER key is updated by a function such as WriteProfileString.


  52.5  Using the Registry Functions

An application can open or create a key, query the registry, write to the registry, work with registry files, and delete information from the registry.


  52.5.1  Opening, Creating, and Closing Keys

To open or create a key, an application always refers to it as a subkey of a currently open key. The four predefined (HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS, and HKEY_CURRENT_USER) are always open. The following functions are used to open a key.

Function	Description
RegOpenKey	Opens a key. This function is provided for compatibility with Windows version 3.1; it does not enable an application to request specific access rights.
RegOpenKeyEx	Opens a key with specified access rights.
The following functions are used to create a key.

Function	Description
RegCreateKey	Creates or opens a key. This function is provided for compatibility with Windows version 3.1; it does not enable an application to set security attributes.
RegCreateKeyEx	Creates or opens a key with the specified security attributes and access rights.
An application can use the RegCloseKey function to close a key and write the information it contains into the registry. This function does not necessarily write the information to the registry before returning; it can take as much as several seconds for the cache to be flushed to the hard disk. If an application must explicitly write registry information to the hard disk, it can use the RegFlushKey function. RegFlushKey, however, uses many system resources and should be called only when necessary.


  52.5.2  Querying the Registry

To query information in the registry, an application typically enumerates the subkeys of a key until it finds a particular one, and then retrieves data from the value or values associated with it.

An application can call one of the following functions to enumerate subkeys.

Function	Description
RegEnumKey	Enumerates subkeys of a specified key.
RegEnumKeyEx	Enumerates subkeys of a specified key and also returns the class of the subkey.
To retrieve detailed information about a particular subkey, an application can call the RegQueryInfoKey function. The RegGetKeySecurity function retrieves a copy of the security descriptor protecting a key. For more information about security descriptors, see Chapter 49, »Security«.

An application can use the following functions to retrieve the values associated with a key.

Function	Description
RegEnumValue	Enumerates the values for a specified key.
RegQueryValue	Retrieves a value for a specified key. This function was introduced in Windows 3.1, but in that version a key could have only one value and values had no names. Therefore, this function can retrieve the data only for a value that has a NULL name.
RegQueryValueEx	Retrieves the type and data information for a named value. An application typically calls the RegEnumValue function to determine the value names and then the RegQueryValueEx function to retrieve the data for the names.
The RegQueryValue and RegQueryValueExn functions also differ in how they treat unexpanded references to environment variables. If an unnamed value contains an unexpanded environment variable (for example, %PATH%), RegQueryValue expands the variable into the storage buffer provided as one of the parameters. RegQueryValueEx, however, does not expand these references. (Windows NT applications can use the ExpandEnvironmentStrings function to expand environment variables.)


  52.5.3  Writing to the Registry

An application can use either the RegSetValue or RegSetValueEx function to associate a value and its data with a key. RegSetValue was introduced in Windows version 3.1 and can work only with strings (the REG_SZ type). RegSetValueEx, however, can write values with any type of data. Either of these functions can create a key and its value at the same time.

To change a key's security, an application can use the RegSetKeySecurity function. For more information about security descriptors, see Chapter 49, »Security«.


  52.5.4  Working with Registry Files

Applications can save part of the registry in a file and then load the contents of the file back into the registry. This is useful when a large amount of information is being manipulated, when many entries are being made in the registry, or when the information is transitory and must be loaded and then unloaded again. Applications that back up and restore parts of the registry are likely to use these registry files.

To save a key and its subkeys and values to a registry file, an application can call the RegSaveKey function. To write the registry file back to the registry, the application can call any of the following functions.

Function	Description
RegLoadKey	Loads registration information from a specified file into a specified subkey under HKEY_USERS or HKEY_LOCAL_MACHINE on the caller's computer or on a remote computer. The function creates the specified subkey. If the specified subkey already exists, the function fails.
	After calling this function, an application can use the RegUnLoadKey function to restore the registry to its previous state.
RegReplaceKey	Replaces a key and all its subkeys and values in the registry with the information contained in a specified file. The new information takes effect the next time the system is started.
RegRestoreKey	Loads registry information from a specified file into a specified key on the caller's computer or on a remote computer. This function replaces the keys and values below the specified key with the keys and values that are subsidiary to the top-level key in the file.


  52.5.5  Deleting Information from the Registry

To delete a value from a key, an application can use the RegDeleteValue function. To delete a key it can use the RegDeleteKey function.

A deleted key is not removed until the last handle to it has been closed. Subkeys and values cannot be created under a deleted key.


  52.5.6  Enumerating Keys and Values

The following example demonstrates the use of the RegEnumKey, RegEnumValue, and RegQueryInfoKey functions. The hKey parameter passed to each function is the handle of an open key. This key must be opened before the call and closed afterward.

VOID QueryKey(HWND hDlg, HANDLE hKey)

{

    CHAR     achKey[MAX_PATH];

    CHAR     achClass[MAX_PATH] = "";  /* buffer for class name   */

    DWORD    cchClassName = MAX_PATH;  /* length of class string  */

    DWORD    cSubKeys;                 /* number of subkeys       */

    DWORD    cbMaxSubKey;              /* longest subkey size     */

    DWORD    cchMaxClass;              /* longest class string    */

    DWORD    cValues;              /* number of values for key    */

    DWORD    cchMaxValue;          /* longest value name          */

    DWORD    cbMaxValueData;       /* longest value data          */

    DWORD    cbSecurityDescriptor; /* size of security descriptor */

    FILETIME ftLastWriteTime;      /* last write time             */

    DWORD i, j;

    DWORD retCode, retValue;

    CHAR  achValue[MAX_VALUE_NAME];

    DWORD cchValue = MAX_VALUE_NAME;

    CHAR  achBuff[80];

    /* Get the class name and the value count. */

    RegQueryInfoKey(hKey,        /* key handle                    */

        achClass,                /* buffer for class name         */

        &cchClassName,           /* length of class string        */

        NULL,                    /* reserved                      */

        &cSubKeys,               /* number of subkeys             */

        &cbMaxSubKey,            /* longest subkey size           */

        &cchMaxClass,            /* longest class string          */

        &cValues,                /* number of values for this key */

        &cchMaxValue,            /* longest value name            */

        &cbMaxValueData,         /* longest value data            */

        &cbSecurityDescriptor,   /* security descriptor           */

        &ftLastWriteTime);       /* last write time               */

    SetDlgItemText(hDlg, IDE_CLASS, achClass);

    SetDlgItemInt(hDlg, IDE_CVALUES, cValues, FALSE);

    SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),

        LB_ADDSTRING, 0, (LONG) "..");

   /*

    * Loop until RegEnumKey fails. Then get the name of each child

    * key and type it into the box.

    */

    /* Enumerate the child keys. */

    SetCursor(LoadCursor(NULL, IDC_WAIT));

    for (i = 0, retCode = ERROR_SUCCESS;

            retCode == ERROR_SUCCESS; i++) {

        retCode = RegEnumKey(hKey, i, achKey, MAX_PATH);

        if (retCode == (DWORD)ERROR_SUCCESS)

            SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),

                LB_ADDSTRING, 0, (LONG) achKey);

    }

    SetCursor(LoadCursor (NULL, IDC_ARROW));

    /* Enumerate the key values. */

    SetCursor(LoadCursor(NULL, IDC_WAIT));

    if (cValues)

        for (j = 0, retValue = ERROR_SUCCESS;

                j < cValues; j++) {

            cchValue = MAX_VALUE_NAME;

            achValue[0] = '\0';

            retValue = RegEnumValue(hKey, j, achValue,

                &cchValue,

                NULL,

                NULL,    /* &dwType, */

                NULL,    /* &bData,  */

                NULL);   /* &bcData  */

            if (retValue != (DWORD) ERROR_SUCCESS &&

                    retValue != ERROR_INSUFFICIENT_BUFFER) {

                wsprintf (achBuff,

                    "Line:%d 0 based index = %d, retValue = %d, "

                     "ValueLen = %d",

                     __LINE__, j, retValue, cchValue);

                MessageBox (hDlg, achBuff, "Debug", MB_OK);

            }

            achBuff[0] = '\0';

            /* Add each value to a list box. */

            if (!lstrlen(achValue))

                lstrcpy(achValue, "<NO NAME>");

            wsprintf(achBuff, "%d) %s ", j, achValue);

            SendMessage(GetDlgItem(hDlg,IDL_LISTBOX2),

                LB_ADDSTRING, 0, (LONG) achBuff);

        }

    SetCursor(LoadCursor(NULL, IDC_ARROW));

}


  52.6  Functions and Messages

Following are the functions and messages used with the registry and initialization files.


  Functions

CloseProfileUserMapping
GetPrivateProfileInt
GetPrivateProfileSection
GetPrivateProfileString
GetProfileInt
GetProfileSection
GetProfileString
OpenProfileUserMapping
RegCloseKey
RegConnectRegistry
RegCreateKey
RegCreateKeyEx
RegDeleteKey
RegDeleteValue
RegEnumKey
RegEnumKeyEx
RegEnumValue
RegFlushKey
RegGetKeySecurity
RegLoadKey
RegNotifyChangeKeyValue
RegOpenKey
RegOpenKeyEx
RegQueryInfoKey
RegQueryValue
RegQueryValueEx
RegReplaceKey
RegRestoreKey
RegSaveKey
RegSetKeySecurity
RegSetValue
RegSetValueEx
RegUnLoadKey
WritePrivateProfileSection
WritePrivateProfileString
WriteProfileSection
WriteProfileString


  Messages

WM_DEVMODECHANGE
WM_WININICHANGE


String Manipulation and Unicode
  Chapter 53    String Manipulation and Unicode

53.1  About Strings and Unicode

The complexities of an expanding global market for applications written for Microsoft Windows and the difficulty of maintaining extremely large programming projects have forced many developers to manage character strings in increasingly sophisticated ways. This chapter documents the ways in which Windows helps developers manipulate strings, gives details about the implementation of national language support in Windows programming, and discusses Unicode, the new global character-encoding system.

For details about Unicode beyond the scope of this chapter, see The Unicode (™)  Standard: Worldwide Character Encoding, Version 1.0, Volumes 1 and 2, Addison-Wesley Publishing Company: 1991, 1992, ISBN 0201567881.


  53.1.1  Character Sets

A character set is a mapping of characters to their identifying numeric values. Most of the character sets commonly used in computers are single-byte character sets in which each character is identified by a value one byte wide. The large number of characters in Asian languages led to the development of multibyte character sets, in particular the double-byte character set (DBCS). Microsoft Windows NT incorporates a new global standard for character encoding: Unicode. The following sections discuss these character sets.


  53.1.1.1  Single-byte Character Sets

A single-byte character set is a mapping of 256 individual characters to their identifying numeric values. The character codes 0x20 through 0x7E represent standardized displayable characters, but the characters represented by the remaining codes vary among character sets. The ASCII character set covers the range 0x00 through 0x7F.

In Windows, the ANSI character set is used in window manager and graphics device interface (GDI), but the MS-DOS file allocation table (FAT) file system uses a character set called the original equipment manufacturer (OEM) character set. Variations on the character sets, called code pages, include different special characters, typically customized for a language or group of languages. The OEM code page generally used in the United States is code page 437.

Applications that use the Win32 application programming interface (API) can use Unicode to avoid the inconsistencies of varied code pages and as an aid in developing easily localized applications. For more information about Unicode, see Section 53.1.1.3, »Unicode«.

An application can use the GetACP function to retrieve the ANSI code-page identifier for the system or use the GetOEMCP function to retrieve the OEM code-page identifier.

The OemToChar and OemToCharBuff functions allow an application to convert a character or string from the OEM code page to either the ANSI code page or Unicode. To convert in the other direction, you can use either the CharToOem or CharToOemBuff function. In addition, an application can use the MultiByteToWideChar and WideCharToMultiByte functions to map single-byte character set (SBCS) strings to Unicode and Unicode strings to SBCS strings.

The GetCPInfo function fills a CPINFO structure with information that includes the size, in bytes, of the largest character in the code page and the default character used when a character code is entered that has no corresponding entry in the code page.


  53.1.1.2  Double-byte Character Sets

The double-byte character set (DBCS) is called an expanded 8-bit character set because its smallest unit is a byte. It can be thought of as the ANSI character set for some Asian versions of Windows (particularly the Japanese version). Win32 functions for the Japanese version of Windows accept DBCS strings for the ANSI versions of the functions. However, unlike the handling of Unicode, DBCS character handling requires detailed changes in the character-processing algorithms throughout an application's source code.

An application can use the IsDBCSLeadByte function to determine whether a given character is the first byte in a 2-byte character; this helps identify double-byte character sets. In addition, an application can use the MultiByteToWideChar and WideCharToMultiByte functions to map DBCS strings to Unicode and Unicode strings to DBCS strings.


  53.1.1.3  Unicode

Unicode is a worldwide character-encoding standard. Windows uses it exclusively at the system level for character and string manipulation. Unicode simplifies localization of software and improves multilingual text processing. By implementing it in an application, a developer can enable the application with universal data exchange capabilities for global marketing, using a single binary file for every possible character code.

Unicode defines semantics for each character, standardizes script behavior, provides a standard algorithm for bidirectional text, and defines cross-mappings to other standards. Among the scripts supported by Unicode are Latin, Greek, Han, Hiragana, and Katakana. Supported languages include, but are not limited to, German, French, English, Greek, Chinese, and Japanese.

Unicode can represent all the world's characters in modern computer use, including technical symbols and special characters used in publishing. Because each Unicode character is 16 bits wide, it is possible to have separate values for up to 65,536 characters. Unicode-enabled functions are often referred to as "wide-character" functions.

Win32 functions support applications that use either Unicode or the regular ANSI character set. Mixed use in the same application is also possible. Adding Unicode support to an application is easy, and a developer can even maintain a single set of sources from which to compile an application that supports either Unicode or the Windows ANSI character set.

Win32 functions support Unicode by assigning its strings a specific data type and providing a separate set of entry points and messages to support this new data type. A series of macros and naming conventions make transparent migration to Unicode, or even compiling both non-Unicode and Unicode versions of an application from the same set of sources, a straightforward matter.

Implementing Unicode as a separate data type also enables the compiler's type checking to ensure that only Unicode parameters are used with functions expecting Unicode strings.


  53.1.2  String Manipulation in Windows

Many Windows functions duplicate or enhance familiar string-manipulation functions from the standard C library. Many of the enhancements enable Windows functions to work with Unicode or extended character sets. For example, the Windows functions in the following table are identical to standard C functions except that the Windows functions are enhanced for use with Unicode.

Windows function	Standard C function
lstrcat	strcat
lstrcmp	strcmp
lstrcmpi	strcmpi
lstrcpy	strcpy
lstrlen	strlen
The strlen standard C function, for example, always returns the number of bytes in a string, but the lstrlen function returns the number of characters, regardless of whether the characters are 1 or 2 bytes wide.

The following Windows functions differ from standard C functions such as tolower and toupper in that they operate on any character in a character set. By using the CharLower function, for example, a Windows-based application can convert an uppercase U with an umlaut (Ü) to lowercase (ü). For more information about character sets, see Section 53.1.1.1, »Single-byte Character Sets«.

Function	Description
CharLower	Converts a character or string to lowercase.
CharLowerBuff	Converts a character string to lowercase.
CharNext	Moves to the next character in a string.
CharPrev	Moves to the preceding character in a string.
CharUpper	Converts a character or string to uppercase.
CharUpperBuff	Converts a string to uppercase.
The following Windows functions make determinations about a character based on the semantics of the language selected by the user. These functions are Unicode enabled.

Function	Description
IsCharAlpha	Determines whether a character is alphabetic.
IsCharAlphaNumeric	Determines whether a character is alphanumeric.
IsCharLower	Determines whether a character is lowercase.
IsCharUpper	Determines whether a character is uppercase.
The wsprintf and wvsprintf functions are extensions to the standard C functions sprintf and vsprintf. The Windows versions support format specifications unique to Unicode.


  53.1.2.1  String Resources

An application that maintains character strings in resources can be translated into new languages with minimum effort. Instead of searching for strings in the source modules, a developer can simply translate the strings in the resource file and relink the application. In addition, using string resources simplifies creation of Unicode and non-Unicode versions of the application from the same source files.

The LoadString function loads a string resource from an application's executable file. The FormatMessage function loads a string resource and interprets formatting options that may be embedded in the string.

Windows 32-bit resources in binary form are stored in Unicode format. When loading resources, applications can use the Unicode version of the resource functions (LoadStringW, for example) to obtain resources as Unicode data.


  53.1.2.2  Locales and Language Identifiers

A sophisticated application can use Windows functions to retrieve specific information about the language and locale for the system on which the application is installed. This can be important for handling language- and locale-specific strings.

A locale identifier is a language/sub-language identifier and a reserved word combined into a doubleword value. There are two predefined locale identifiers: LOCALE_SYSTEM_DEFAULT, which identifies the system default locale, and LOCALE_USER_DEFAULT, which identifies the locale of the current user. An application can call the GetSystemDefaultLCID and GetUserDefaultLCID functions to retrieve the current locale identifiers. To retrieve the current language identifiers, an application can call the GetSystemDefaultLangID and GetUserDefaultLangID functions. For a list of locale and language identifiers, see Appendix C, »Locale Identifiers«.

The CompareStringW function compares two Unicode strings based on a supplied locale identifier.

The GetLocaleInfoW function can retrieve many different kinds of information about a locale. Appendix C, »Locale Identifiers«.

The GetStringTypeW function retrieves information about a Unicode string on a character-by-character basis.


  53.1.3  Unicode in Windows

Win32 API elements that use characters are generally implemented in one of three formats:

•	A generic version that can be compiled for either ANSI or Unicode

•	An ANSI version

•	A Unicode version

The following sections discuss Unicode data types and how they are used in functions and messages; the use of resources, filenames, and command-line arguments; and methods of translating between different types of strings.


  53.1.3.1  Data Types

Most string operations for Unicode can be written by using the same logic used for handling the Windows ANSI character set, except that the basic unit of operation is a 16-bit character instead of an 8-bit byte. The header files provide a number of type definitions that make it easy to create sources that can be compiled for Unicode or for the ANSI character set.

The following example shows the method used in the Win32 header files to define three sets of data types: a set of generic type definitions that can compile for either ANSI or Unicode, and two sets of specific type definitions. The first set of specific type definitions is for use with the existing Windows (ANSI) character set, and the other is for use with Unicode (or wide) characters.

/* Generic types */

#ifdef UNICODE

 typedef wchar_t TCHAR;

#else

 typedef unsigned char TCHAR;

#endif

typedef TCHAR * LPTSTR, *LPTCH;

/* 8-bit character specific */

typedef unsigned char CHAR;

typedef CHAR *LPSTR, *LPCH;

/* Unicode specific (wide characters) */

typedef unsigned wchar_t WCHAR;

typedef WCHAR *LPWSTR, *LPWCH;

The letter T preceding a type definition designates a generic type that can be compiled for either ANSI or Unicode. The letter W preceding a type definition designates a wide-character (Unicode) type. For the actual implementation of this method, see the WINNT.H header file.

An application using generic data types can be compiled for Unicode simply by defining UNICODE before the include statements for the header files. To compile the code for ANSI, omit the UNICODE definition.

Developers are encouraged to use the generic data types, but the specific types exist for applications that require mixed-type control.


  53.1.3.2  Function Prototypes

Function prototypes are also provided in generic, ANSI, and Unicode varieties, as shown below. The generic function prototype consists of the standard function name implemented as a macro. The preprocessor expands each macro into one of the specific function prototypes, depending on whether UNICODE is defined. The letters A (ANSI) and W (wide) are added at the end of the function names in the specific function prototypes. In this example, the generic prototype uses the generic type LPTSTR for the text parameter, but the A and W prototypes use the LPCSTR and LPCWSTR character types, respectively.

SetWindowText(HWND hwnd, LPTSTR lpText);

SetWindowTextA(HWND hwnd, LPCSTR lpText);

SetWindowTextW(HWND hwnd, LPCWSTR lpText);

An application can use the generic function and make Unicode dependent on whether the UNICODE option is used to compile the code, or it can make mixed calls by using the explicit function names ending with A and W.

This three-prototype approach applies to all functions with text arguments. Always use a generic function prototype with the generic string and character types. All function names that end with an uppercase W take wide-character arguments.

Some functions exist only in wide-character versions and can be used only with the appropriate data type.

The reference material for each Unicode-enabled function is labeled with a Unicode icon. If the function exists as a macro that the preprocessor must expand into an ANSI or Unicode form, only the macro form is documented.

Note   Whenever a function has a length parameter for a character string, the length should be given as a count of characters (TCHAR units) in the string. However, functions that require or return pointers to untyped memory blocks, such as the GlobalAlloc function, are exceptions.


  53.1.3.3  Messages

Although applications generally use the same window class, messages between windows of different classes are transparently translated by the system.

Even though a window function is implemented to receive messages in Unicode or ANSI format, the window procedure can still send messages or call functions of either type.

The following messages have text arguments and are subject to automatic text translation. (For information about automatic translation, see Section 53.2.3, »Subclassing and Automatic Message Translation«.)

CB_ADDSTRING	LB_SELECTSTRING
CB_DIR	WM_ASKCBFORMATNAME
CB_FINDSTRING	WM_CHAR
CB_GETLBTEXT	WM_CHARTOITEM
CB_INSERTSTRING	WM_CREATE
CB_SELECTSTRING	WM_DEADCHAR
EM_GETLINE	WM_DEVMODECHANGE
EM_REPLACESEL	WM_GETTEXT
EM_SETPASSWORDCHAR	WM_MDICREATE
LB_ADDFILE	WM_MENUCHAR
LB_ADDSTRING	WM_NCCREATE
LB_DIR	WM_SETTEXT
LB_FINDSTRING	WM_SYSCHAR
LB_GETTEXT	WM_SYSDEADCHAR
LB_INSERTSTRING	WM_WININICHANGE


  53.1.3.4  String Functions

All of the string functions listed in this section exist in ANSI and Unicode implementations to support ANSI and Unicode arguments. There are, however, subtle differences among some of them.

The following string functions do not require special comment; their ANSI and Unicode implementations work identically.

CharNext
CharPrev
lstrcat
lstrcpy
lstrlen

The value returned by the lstrlen function is always the number of characters, regardless of whether the ANSI or Unicode form is used.

The following string functions are sensitive to the locale of the current thread (as derived from the locale the user selects in Control Panel). The lstrcmp and lstrcmpi functions do not perform byte comparisons like their ANSI C namesakes; they compare strings according to the rules of the selected locale.

CharLower
CharLowerBuff
CharUpper
CharUpperBuff
lstrcmp
lstrcmpi

The following functions convert between the OEM character set and either ANSI or Unicode, depending on which version is used.

CharToOem
CharToOemBuff
OemToChar
OemToCharBuff

The print function wsprintf supports Unicode by providing the following new and changed data types in its format specifications. These format specifications affect the way the wsprintf function interprets the corresponding passed-in parameter.

Format specification	ANSI version	Unicode version
c	CHAR	WCHAR
C	WCHAR	CHAR
hc, hC	CHAR	CHAR
hs, hS	LPSTR	LPSTR
lc, lC	WCHAR	WCHAR
ls, lS	LPWSTR	LPWSTR
s	LPSTR	LPWSTR
S	LPWSTR	LPSTR
The data type for the output text always depneds on the version of the function. Where the data type of the passed-in parameter and of the output text do not agree, wsprintf will perform a conversion from Unicode to ANSI, or vice versa, as required.

For the Unicode version of wsprintf, the format string is Unicode, as is the output text.


  53.1.3.5  Standard C Functions

The standard C libraries contain wide-character versions of the ANSI string functions that begin with the letters str. The wide-character versions of the functions start with the letters wcs (or sometimes _wcs). The Unicode data type is compatible with the wide-character data type wchar_t in ANSI C; this allows access to the wide-character string functions.

Generic functions exist for all standard C string functions. They start with the letters _tcs and are listed in the TCHAR.H header file. These functions use the generic data types TCHAR and TCHAR*

An application must add the following lines to its program in order to use the generic functions and compile for Unicode:

#define _UNICODE

#include <tchar.h>

#include <wchar.h>

Note that both the TCHAR.H and WCHAR.H are required, and that the leading underscore on the _UNICODE variable is also required.

The wcstombs and mbstowcs functions can convert from the character set supported by the standard C library to Unicode and back, with some limitations. For more information about translating strings to and from Unicode, see Section 53.1.3.7, »Translation Between String Types«.

The printf function defined in TCHAR.H supports the same format specifications as wsprintf; for details, see Section 53.1.3.4, »String Functions«. Similarly, TCHAR.H contains a wprintf function, in which the format string itself is a Unicode string.


  53.1.3.6  Filenames

In Windows, the ANSI character set is used in window manager and GDI; the MS-DOS FAT file system uses the OEM character set. Windows applications that create MS-DOS files have sometimes had to use the CharToOem and OemToChar functions to translate between these character sets. However, the New Technology file system (NTFS) file system is capable of storing filenames in Unicode; no translation is necessary with NTFS.

With Unicode implementations of the file-system functions, it is not necessary to perform translations to and from ANSI and OEM character sets. Instead, a developer can use a single source file to compile non-Unicode versions of an application by providing macros for functions that are not invoked when compiling for Unicode, such as CharToOem and OemToChar.

The special filename characters in MS-DOS are unchanged in Unicode filenames:

" \ ," "/," ".," "?," "*."

These special characters are in the ASCII range of characters (0x00 through 0x7F) and their Unicode equivalents are simply the same values in a 2-byte form: 0x0000 through 0x007F.


  53.1.3.7  Translation Between String Types

The following Win32 functions translate character strings from one string type to another.

Function	Description
FoldStringW	Translates one wide-character string to another.
LCMapStringW	Maps a character string by locale.
ToUnicode	Translates a virtual-key code into a Unicode character.
MultiByteToWideChar	Maps a multibyte string into a wide-character string.
WideCharToMultiByte	Maps a wide-character string into a multibyte string.
The WideCharToMultiByte and MultiByteToWideChar functions are particularly useful for applications that support several string types. ANSI C also defines the conversion functions wcstombs and mbstowcs, but they can only convert to and from the character set supported by the standard C library.


  53.1.3.8  Command-line Arguments

An application can use the GetCommandLine function to retrieve Unicode command-line arguments by calling it as a Unicode function.


  53.2  Using Strings and Unicode

This section describes how to perform the following tasks:

•	Use generic data types to convert code so that it can be compiled for either ANSI or Unicode from a single source file

•	Register window classes for ANSI and Unicode applications

•	Subclass

•	Use automatic message translation

•	Use characters with special meanings in Unicode

•	Work with functions that have no Unicode equivalents


  53.2.1  Using Generic Data Types

If you use generic data types in your code, it can be compiled for Unicode simply by defining UNICODE before the include statements for the header files. To compile the code for ANSI, omit the UNICODE definition.

To convert code that processes strings so it can be compiled for either ANSI or Unicode, follow these steps.

1.	Change all character and string types used for text to TCHAR, LPTSTR, or LPTCH.

2.	Be sure that pointers to nontext data buffers or binary byte arrays are coded with the LPBYTE type and not mistakenly with the LPTSTR or LPTCH type. Declare pointers of indeterminate type explicitly as void pointers by using LPVOID, as appropriate.

3.	Make pointer arithmetic type independent. Using units of TCHAR size yields an answer in bytes when the UNICODE option is not defined and in words when it is. The following expression actually calculates the size of the string, not a count of its elements.

cCount = lpEnd - lpStart;

Change the expression to the following form to return a type-independent count.

cCount = (lpEnd - lpStart) / sizeof(TCHAR);

There is no need to change a statement like the following one, because the pointer increment points to the next character element.

chNext = *++lpText;

4.	Replace literal strings and manifest character constants with macros. Change expressions like the following one.

    while(*lpFileName++ != '\\') {

        .

        .

        .

    }

Use the TEXT macro as follows in this expression.

    while(*lpFileName++ != TEXT('\\')) {

        .

        .

        .

    }

Precede a literal string in the Unicode form of a function by the letter L. The TEXT macro causes strings to be evaluated as L"string" when UNICODE is defined, and to "string" otherwise. The following call to the Unicode version of lstrlen demonstrates the use of the L identifier.

cch == lstrlenW(L"hello world");

For easier management, move literal strings into resources, especially if they contain characters outside the ASCII range (that is, 0x00 through 0x7F).

5.	Call only the Unicode versions of the standard C library string functions, as listed in Section 53.1.3.5, »Standard C Functions«.

6.	Change any code that relies on 255 as the largest value for a character.

When you compile code that you have changed as outlined above, the compiler creates the same binary file as it did before you made the changes. When you compile the code using the UNICODE option, however, it is compiled as a Unicode application.


  53.2.2  Registering Window Classes

A window class is supported by a window procedure. You can register a window class by using either the RegisterWindowClassA or RegisterWindowClassW function. If you register the window class by using RegisterWindowClassA, the application tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; if you register it by using RegisterWindowClassW, the application requests that the system pass text parameters of messages as Unicode. The IsWindowUnicode function enables applications to query the nature of each window.

The following example shows how to register an ANSI window class and a Unicode window class and how to write the window procedures for both cases. For the purposes of this example, all functions and structures are shown with the specific A or W data types. Using the techniques explained in Section 53.2.1, »Using Generic Data Types«, you could alternatively write this example by using generic data types, so that it could be compiled as either ANSI or Unicode, depending on whether UNICODE is defined.

/* Register an ANSI window class. */

WNDCLASSA AnsiWndCls;

AnsiWndCls.style         = CS_DBLCLKS | CS_PARENTDC;

AnsiWndCls.lpfnWndProc   = (WNDPROC)AnsiWndProc;

AnsiWndCls.cbClsExtra    = 0;

AnsiWndCls.cbWndExtra    = 0;

AnsiWndCls.hInstance     = hmodUser;

AnsiWndCls.hIcon         = NULL;

AnsiWndCls.hCursor       = LoadCursor(NULL, (LPTSTR)IDC_IBEAM);

AnsiWndCls.hbrBackground = NULL;

AnsiWndCls.lpszMenuName  = NULL;

AnsiWndCls.lpszClassName = "TestAnsi";

RegisterClassA(&AnsiWndCls);

/* Register a Unicode window class. */

WNDCLASSW UnicodeWndCls;

UnicodeWndCls.style         = CS_DBLCLKS | CS_PARENTDC;

UnicodeWndCls.lpfnWndProc   = (WNDPROC)UniWndProc;

UnicodeWndCls.cbClsExtra    = 0;

UnicodeWndCls.cbWndExtra    = 0;

UnicodeWndCls.hInstance     = hmodUser;

UnicodeWndCls.hIcon         = NULL;

UnicodeWndCls.hCursor       = LoadCursor(NULL,(LPTSTR)IDC_IBEAM);

UnicodeWndCls.hbrBackground = NULL;

UnicodeWndCls.lpszMenuName  = NULL;

UnicodeWndCls.lpszClassName = L"TestUnicode";

RegisterClassW(&UnicodeWndCls);

The following example shows the difference between handling the WM_CHAR message in an ANSI window procedure and a Unicode window procedure.

/* ANSI Window Procedure */

LONG AnsiWndProc(HWND hwnd, UINT message,

                 WPARAM wParam, LPARAM lParam)

{

    /* Dispatch the messages that can be received. */

    switch (message) {

        case WM_CHAR:

            /*

             * wParam - the value of the key

             * lParam - (not used in this example)

             */

            if (lstrcmpA("Q", (LPCSTR) wParam)) {

                 .

                 .

                 .

            }

            else {

                 .

                 .

                 .

            }

            break;

        .

        .   /* process other messages */

        .

    }

}

/* Unicode Window Procedure */

LONG UniWndProc(HWND hwnd, UINT message,

    WPARAM wParam, LPARAM lParam)

{

    /* Dispatch the messages that can be received. */

    switch (message) {

        case WM_CHAR:

            /*

             * wParam - the value of the key

             * lParam - (not used in this example)

             */

            if (lstrcmpW(L"Q", (LPCWSTR) wParam)) {

                 .

                 .

                 .

            }

            else {

                 .

                 .

                 .

            }

            break;

        .

        .   /* process other messages */

        .

    }

}

All text in messages received by AnsiWndProc will be composed of ANSI characters, and all text in messages received by UniWndProc will be composed of Unicode characters.


  53.2.3  Subclassing and Automatic Message Translation

Subclassing is a technique that allows an application to intercept and process messages sent or posted to a particular window before the window has a chance to process them. The system automatically translates messages into ANSI or Unicode form, depending on the form of the function that subclassed the window procedure.

The following call to the SetWindowLongA function subclasses the current window procedure associated with the window identified by the hwnd parameter. The new window procedure, NewWndProc, will receive messages with text in ANSI format.

OldWndProc = (WNDPROC) SetWindowLongA(hwnd,

    GWL_WNDPROC, (LONG)NewWndProc);

When NewWndProc has finished processing a message, it uses the CallWindowProc function as follows to pass the message to OldWndProc.

CallWindowProc(OldWndProc, hwnd, uMessage, wParam, lParam);

If OldWndProc was created with a class style of UNICODE, messages will be translated from the ANSI form received by NewWndProc into Unicode.

Similarly, a call to the SetWindowLongW function would subclass the current window procedure with a window procedure that expects Unicode text messages. Message translation, if necessary, is performed during the processing of the CallWindowProc function.

For more information about subclassing, see Programmer's Reference, Volume 1, Chapter 4, Window Procedures.


  53.2.4  Using Special Characters in Unicode

There are a few special characters and characters with unusual meanings in Unicode text strings. To avoid unexpected problems with these characters, use the rules in the following sections.


  53.2.4.1  Null-terminated Strings

Always cast zero to TCHAR when using null-terminated strings. The code 0x0000 is the Unicode string terminator for null-terminated strings. A single null byte is not sufficient for this code, because many Unicode characters contain null bytes as either the high or the low byte. An example is the letter A, for which the character code is 0x0041.


  53.2.4.2  Byte-order Mark

Always prefix a Unicode plain text file with a byte-order mark. Because Unicode plain text is a sequence of 16-bit codes, it is sensitive to the byte ordering used when the text was written.

A byte-order mark is not a control character that selects the byte order of the text; it simply informs an application receiving the file that the file is byte ordered.

Ideally, all Unicode text would follow only one set of byte-ordering rules. This is not possible, however, because microprocessors differ in the position of the least significant byte: Intel® and MIPS® processors have the least significant byte first; Motorola processors (and byte-reversed Unicode files) have it last. With only a single set of byte-ordering rules, users of one type of microprocessor would be forced to swap the byte order every time a plain text file is read from or written to, even if the file is never transferred to another system based on a different microprocessor.

The preferred place to specify byte order is in a file header, but text files do not have headers. Therefore, Unicode has defined a character (0xFEFF) and a noncharacter (0xFFFE) as byte-order marks. They are mirror byte-images of each other.

Since the sequence 0xFEFF is exceedingly rare at the outset of regular non-Unicode text files, it can serve as an implicit marker or signature to identify the file as a Unicode file. Applications written to read both Unicode and non-Unicode text files should use the presence of this sequence as a near-certain indicator that the file is a Unicode file. (Compare this technique to using the MS-DOS EOF marker to terminate text files.)

When an application finds 0xFEFF at the beginning of a text file, it typically processes the file as though it were a Unicode file, although it may also perform further heuristic checks to verify that this is true. Such a check could be as simple as a test of whether the variation in the low-order bytes is much higher than the variation in the high-order bytes. For example, if ASCII text is converted to Unicode text, every second byte is zero. Also, checking both for the linefeed and carriage-return characters (0x000A and 0x000D) and for even or odd file size can provide a strong indicator of the nature of the file.

When an application finds 0xFFFE at the beginning of a text file, it interprets it to mean the file is a byte-reversed Unicode file. The application can either swap the order of the bytes or alert the user that an error has occurred.

The Unicode byte-order mark character is not found in any code page, so it disappears if data is converted to ANSI. Unlike other Unicode characters, it is not replaced by a default character when it is converted. If a byte-order mark is found in the middle of a file, it is not interpreted as a Unicode character and has no effect on text output.

The Unicode value 0xFFFF is illegal in plain text files and cannot be passed between Windows functions. The value 0xFFFF is reserved for an application's private use.


  53.2.4.3  Escape Sequences and Control Characters

Translate escape sequences character by character into Unicode. When an ASCII plain text file is converted to Unicode, there is a chance that it will subsequently be converted back to ASCII. Converting escape sequences into Unicode on a character-by-character basis, rather than as a single 2-byte characters makes it possible to perform the reverse conversion without recognizing and parsing the escape sequences as such. For example, ESC+A should become 0x001B (ESC), 0x0041 (A), rather than 0x411B.

The first 32 sixteen-bit characters in Unicode are intended for the 32 control characters. This approach supports the existing use of control characters for formatting purposes — that is, Unicode applications can treat these control characters in exactly the same way as they treat their ASCII equivalents.


  53.2.4.4  Line and Paragraph Separators

Use the line-separator character (0x2028) and the paragraph-separator character (0x2029) to divide plain text. A new line is begun after each line separator. A new paragraph is begun after each paragraph separator.

Because these are separator codes, it is not necessary to start the first line or paragraph in the file with them, or to end the last line or paragraph with them. (Doing so would indicate that there is an empty line or paragraph in that location.)

The line separator can be used to indicate an unconditional end of line. However, line separators do not correspond to the carriage-return and linefeed characters, or to the carriage-return−linefeed character combination; they must be processed separately from carriage return and linefeed characters.

The paragraph separator can be inserted between paragraphs of text. This allows plain text files to be created that can be formatted with different line widths on different systems. The receiving system can ignore any line breaks and break paragraphs only at the paragraph separators.


  53.2.4.5  ASCII Control Codes 0x000D and 0x000A

The Unicode standard does not prescribe a specific meaning for the control codes 0x000D (carriage return) and 0x000A (linefeed). There is no requirement that these codes be used in combination, and if used individually, either code may represent either itself only or both codes together. It is entirely up to the application to determine what these codes represent. (Applications have always had to interpret these control codes in ASCII; the Unicode policy is not a change in their use.)


  53.2.4.6  Nonspacing Characters and Diacritics

When breaking lines or otherwise separating text, be sure to keep nonspacing characters with their base characters. Many scripts contain characters that visually combine with other characters on output — for example, the diacritical marks (or "floating accents"). In Unicode, nonspacing characters follow their base character.


  53.2.5  Using Functions Without Unicode Equivalents

Windows functions that have not been exported in a Unicode version have typically been replaced by more powerful or extended functions that do support Unicode. If you are porting code that calls the OpenFile function, for example, you can support Unicode by using the CreateFile or CreateFileEx function instead.

If a function has no Unicode equivalent, you can map characters to and from 8-bit character sets before and after the function call. For example, the number-formatting functions atoi and itoa use only the digits 0 through 9. Normally, mapping Unicode to 8-bit characters could cause loss of data, but you can avoid this by making your code type independent and conditionalizing the expressions. For example, the following statements are type dependent and should be changed to support Unicode.

    char str[4];

    num = atoi(str);

These statements could be rewritten as follows to make them type independent.

    TCHAR tstr[4];

    CHAR strTmp[SIZE];

    #ifdef UNICODE

    wcstombs(strTmp, (const wchar_t *) tstr, sizeof(strTmp));

    num = atoi(strTmp);

    #else

    num = atoi(tstr);

    #endif

In this example, the wcstombs function is the standard C function that translates Unicode to ASCII. The example relies on the fact that the digits 0 through 9 can always be translated from Unicode to ASCII, even if some of the surrounding text cannot. The atoi function stops at any character that is not a digit. You can use the LCMapStringW function if you need to process text that includes the native digits provided for some of the scripts in Unicode.


  53.3  Functions

Following are the functions used with string manipulation.

CharLower
CharLowerBuff
CharNext
CharPrev
CharToOem
CharToOemBuff
CharUpper
CharUpperBuff
CompareStringW
FoldStringW
FormatMessage
GetACP
GetCPInfo
GetLocaleInfoW
GetOEMCP
GetStringTypeW
GetSystemDefaultLangID
GetSystemDefaultLCID
GetThreadLocale
GetUserDefaultLangID
GetUserDefaultLCID
IsCharAlpha
IsCharAlphaNumeric
IsCharLower
IsCharUpper
IsDBCSLeadByte
IsValidCodePage
LCMapStringW
LoadString
lstrcat
lstrcmp
lstrcmpi
lstrcpy
lstrlen
MultiByteToWideChar
OemToChar
OemToCharBuff
SetThreadLocale
WideCharToMultiByte
wsprintf
wvsprintf
AnsiLower (obsolete)
AnsiLowerBuff (obsolete)
AnsiNext (obsolete)
AnsiPrev (obsolete)
AnsiToOem (obsolete)
AnsiToOemBuff (obsolete)
AnsiUpper (obsolete)
AnsiUpperBuff (obsolete)
OemToAnsi (obsolete)
OemToAnsiBuff (obsolete)


Pipes
  Chapter 54    Pipes

54.1  About Pipes

A pipe is a communication conduit with two ends: A process with a handle to one end can communicate with a process having a handle to the other end. Pipes can be one-way — where one end is read-only and the other end is write-only, or two-way — where both ends of the pipe can read or write. The Microsoft Win32 application programming interface (API) provides both anonymous (unnamed) pipes and named pipes. This chapter describes how to create, manage, and use pipes.


  54.1.1  Anonymous Pipes

An anonymous pipe is an unnamed, one-way pipe that transfers data between a parent process and a child process, or between two child processes of the same parent process. Although it is possible to use anonymous pipes for communication between unrelated processes, it is easier to use named pipes for that purpose (see Section 54.1.2, »Named Pipes«). Anonymous pipes are always local, and cannot be used for communication over a network.

The CreatePipe function creates an anonymous pipe and returns two handles: one to the read end and one to the write end of the pipe. The read handle has only read access to the pipe, and the write handle has only write access to the pipe. To communicate through the pipe, a handle to one of the ends must be passed to another process. Usually, this is done through inheritance, where a child process inherits a handle from its parent process. The inheritability of these handles is controlled by the creating process in the following ways:

•	The CreatePipe function specifies a SECURITY_ATTRIBUTES structure. If the bInheritHandle member of this structure is TRUE, the handles can be inherited.

•	The DuplicateHandle function can change the inheritability of a pipe handle. This enables a process to create a noninheritable duplicate of an inheritable pipe handle, or to create an inheritable duplicate of a noninheritable pipe handle.

•	The CreateProcess function enables a parent process to specify whether the new child process will inherit all or none of the parent's inheritable handles.

When a child process inherits a handle, the system enables the process to access the pipe referred to by that handle. However, to do so, the process must retrieve the value of the handle. To do this, the parent process must communicate the handle value to the child process. Typically, this is done using the SetStdHandle and GetStdHandle functions, which set and retrieve the standard handles (standard input, standard output, or standard error) of a process. The parent process can specify a pipe handle in a call to SetStdHandle before the child process is created. The current standard handles of the parent process are inherited by the child process. So, when the child process starts up, it can use the GetStdHandle function to retrieve the handle value. The parent process can change its own standard handles without affecting the standard handles of its existing child processes.

To read from the pipe, a process uses the read handle in a call to the ReadFile function. Unless an error occurs, ReadFile does not return until the specified number of bytes has been read or all handles to the write end of the pipe have been closed.

To write to the pipe, a process uses the write handle in a call to the WriteFile function. WriteFile does not return until the specified number of bytes has been written or an error occurs. If the pipe's buffer is full and bytes remain to be written, WriteFile does not return until some other process or thread reads from the pipe, making more buffer space available. CreatePipe enables the creating process to specify a buffer size for the pipe, or it can use the default buffer size.

Asynchronous (overlapped) read and write operations are not supported for anonymous pipes. This means that the ReadFileEx and WriteFileEx functions cannot be used with anonymous pipes. The lpOverLapped parameter of the ReadFile and WriteFile functions is ignored when used with an anonymous pipe.

An anonymous pipe exists until all handles to both read and write ends of the pipe are closed by the CloseHandle function.


  54.1.2  Named Pipes

A named pipe is a one-way or two-way pipe for communicating between a server process and one or more client processes. A server process specifies a name when it calls the CreateNamedPipe function to create one or more instances of a named pipe. All instances of a named pipe share the same pipe name, but each instance has its own buffers and handles and provides a separate conduit for client-server communication. When a client process specifies a pipe name in the CreateFile or CallNamedPipe functions, it connects to an instance of the pipe. This enables multiple client processes to use the same named pipe simultaneously.

Subject to security checks, any client process can access a named pipe, making it easy to communicate between related or unrelated processes. Named pipes can be used locally to communicate between processes on the same machine or across a network, to connect processes on different machines.

In Windows NT, the difference between client and server processes is greatly diminished, because any Windows NT process can act as both a server and a client, making peer-to-peer communication possible. As used here, server refers to a process that uses CreateNamedPipe to create a named pipe, and client refers to a process that uses CreateFile or CallNamedPipe to connect to an instance of a named pipe.


  54.1.3  Pipe Names

Each named pipe must have a unique name that distinguishes it from other named pipes. Use the following form when specifying the name of a pipe in the CreateNamedPipe, CreateFile, WaitNamedPipe, or CallNamedPipe functions.

\\servername\pipe\pipename

The server process cannot create a pipe on a computer, so CreateNamedPipe must use a period to indicate the local computer — for example:

\\.\pipe\pipename

Client processes using CreateFile, WaitNamedPipe, or CallNamedPipe can use a period to specify a local pipe, but must specify the name of a server to open a pipe on a remote computer.

The pipename part of the name can include any character, including numbers and special characters. The entire pipe name string can be up to 256 characters long. Pipe names are not case sensitive.


  54.1.4  Named Pipe Modes

A number of modes associated with a named pipe or with a handle to a named pipe affect the use and behavior of the pipe. Some of these modes can be set differently for each handle to a pipe, while others must be the same for all handles to a pipe.

The server process specifies the following modes when it calls the CreateNamedPipe function. The type and access modes must be the same for all instances of a pipe.

Mode	Meaning
Type	PIPE_TYPE_BYTE or PIPE_TYPE_MESSAGE. The type mode determines whether data is written to a named pipe as a stream of messages or as a stream of bytes. If no type is specified in CreateNamedPipe, the default is PIPE_TYPE_BYTE. A handle to a byte pipe must be in byte-read mode. A handle to a message pipe can be in either byte-read or message-read mode. For more information about pipe types, see Section 54.1.7, »Named Pipe Type and Read Mode«.
Access	PIPE_ACCESS_INBOUND, PIPE_ACCESS_OUTBOUND, or PIPE_ACCESS_DUPLEX. This is equivalent to specifying the read or write access of the server's handles to the pipe, where inbound is equivalent to GENERIC_READ access, outbound is equivalent to GENERIC_WRITE access, and duplex is equivalent to GENERIC_READ | GENERIC_WRITE access. Client processes using CreateFile to connect to a named pipe must specify an access compatible with the access specified by the server. For example, a client must specify GENERIC_READ access for an outbound pipe.
The remaining pipe modes can differ for each pipe handle. This means that the client and server ends of the same pipe instance can use different modes. The CreateNamedPipe function sets all of these modes for the pipe handles of a server. The CreateFile function supports setting the overlapped and write-through modes for the pipe handles of a client. Both client and server processes use the SetNamedPipeHandleState function to set the read and wait modes of a pipe handle.

Mode	Meaning
Read	PIPE_READMODE_BYTE or PIPE_READMODE_MESSAGE. In byte-read mode, data is read from a named pipe as a stream of bytes. In message-read mode, data is read from a named pipe as a stream of messages. Only byte-read mode is allowed for byte-type pipes. Either byte- or message-read mode is allowed for message-type pipes. The default is byte-type mode, if no read mode is specified in CreateNamedPipe. For more information about read modes, see Section 54.1.7, »Named Pipe Type and Read Mode«.
Wait	PIPE_WAIT or PIPE_NOWAIT. In blocking-wait mode, the ReadFile, WriteFile, and ConnectNamedPipe functions wait indefinitely — in some situations — for a process on the other end of the pipe to perform an action. In nonblocking-wait mode, the functions return if they cannot finish their operations immediately. For more information about wait modes, see Section 54.1.8, »Blocking and Nonblocking Pipe Operations«.
Overlapped	FILE_FLAG_OVERLAPPED. In overlapped mode, the functions that perform read, write, and connect operations that take a significant time to be completed can return immediately. This enables the thread to perform other operations while the time-consuming operation executes in the background. For more information about overlapped mode, see Section 54.1.9, »Synchronous and Overlapped Input and Output«.
Write-through	FILE_FLAG_WRITE_THROUGH. In write-through mode, the functions that write to a named pipe do not return until the data written is transmitted across the network and in the pipe's buffer on the remote computer. This mode affects only write operations on byte-type pipes, and then only when the client and server processes are on different computers. If write-through mode is not enabled, the write function returns successfully, even if the data is not transmitted. For more information about write-through modes, see Section 54.1.10, »Write-through to Remote Clients«.
The initial read mode for a pipe handle is specified when a server process calls CreateNamedPipe. If PIPE_READMODE_BYTE is specified, or if no read mode is specified, the pipe handle is created in byte-read mode. If both PIPE_READMODE_MESSAGE and PIPE_TYPE_MESSAGE are specified, the handle is created in message-read mode. For a client process, a pipe handle returned by the CreateFile function is always in byte-read mode initially. Both client and server processes can use the SetNamedPipeHandleState function to change the read mode of a pipe handle. For a message-type pipe, the read mode can be different for server and client handles to the same pipe instance.


  54.1.5  Named Pipe Operations

The first time the server calls CreateNamedPipe, the function specifies the maximum number of instances of the pipe that can exist simultaneously. Limited by this maximum, the server can call CreateNamedPipe repeatedly to create additional instances of the pipe. If the function succeeds, each call returns a handle to the server end of a named pipe instance.

As soon as a pipe instance is created, a client process can connect to it by calling the CreateFile or CallNamedPipe functions. If a pipe instance is available, CreateFile returns a handle to the client end of the pipe instance. If no instances of the pipe are available, a client process can use the WaitNamedPipe function to wait for one to become available.

A client process can also use the CallNamedPipe function to combine into a single operation the functions that connect to a pipe instance (waiting for one to be available, if necessary), write a message, read a message, and close its pipe handle. The CallNamedPipe function can be used only by a client process and only with a message-type pipe.

A server process specifies a handle to a pipe instance in a call to the ConnectNamedPipe function to determine when a client process is connected to it. If the pipe handle is in blocking mode, the ConnectNamedPipe operation does not return until a client is connected.

Client and server processes can call one of several functions — in addition to CallNamedPipe — to read from and write to a named pipe. The behavior of these functions depends on the type of pipe and the modes in effect for the specified pipe handle.

•	The ReadFile and WriteFile functions can be used with either byte-type or message-type pipes.

•	The ReadFileEx and WriteFileEx functions can be used with either byte-type or message-type pipes, if the pipe handle was opened for overlapped operations.

•	The PeekNamedPipe function can be used to read without removing the contents of either a byte-type or a message-type pipe. PeekNamedPipe can also return additional information about the pipe instance.

•	The TransactNamedPipe function can be used with message-type pipes if the pipe handle of the calling process is set to message-read mode. This function writes a request message and reads a reply message in a single operation, enhancing network performance.

For a pipe handle in byte-read mode, a read operation is completed successfully when all available bytes in the pipe are read or when the specified number of bytes is read.

For a pipe handle in message-read mode, a ReadFile or ReadFileEx operation is completed successfully only when the entire message is read. If the specified number of bytes to read is less than the size of the next message, the function reads as much of the message as possible before returning FALSE (with the GetLastError function returning ERROR_MORE_DATA). In this case, you can read the remainder of the message by making additional calls to ReadFile, ReadFileEx, or PeekNamedPipe. Note that PeekNamedPipe returns TRUE after reading a complete or partial message, and reports the number of bytes remaining in a partially read message.

For a message-type pipe with multiple unread messages, a read operation using a message-read pipe handle returns after reading one message. An operation using a byte-read handle does not distinguish between the messages — it reads all available bytes up to the specified number.

When a client and server finish using a pipe instance, the server calls the DisconnectNamedPipe function to close the connection to the client process. This function makes the client's handle invalid (if it has not already been closed). Any unread data in the pipe is discarded. To ensure that all bytes or messages written to the pipe are read by the client, the server first calls the FlushFileBuffers function, which does not return until the client has read all data from the pipe. After the client is disconnected, the server calls the CloseHandle function to close its handle to the pipe instance. Alternatively, the server can use ConnectNamedPipe to enable a new client to connect to this instance of the pipe.

A process can retrieve information about a named pipe by calling the GetNamedPipeInfo function, which returns the type of the pipe, the size of the input and output buffers, and the maximum number of pipe instances that can be created. The GetNamedPipeHandleState function reports on the read and wait modes of a pipe handle, the current number of pipe instances, and additional relevant information for pipes that communicate over a network. The SetNamedPipeHandleState function sets the read mode and wait modes of a pipe handle. For client processes communicating with a remote server, the function also controls the maximum number of bytes to collect or the maximum time to wait before transmitting a message (assuming the client's handle was not opened with write-through mode enabled).


  54.1.6  The Named Pipe Server Process

The simplest server process can use the CreateNamedPipe function to create a single instance of a pipe, connect to a single client, communicate with the client, disconnect the pipe, close the pipe handle, and terminate. Typically, however, a server process must communicate with multiple client processes. A server process can use a single pipe instance by connecting to and disconnecting from each client in sequence, but performance would be poor. To handle multiple clients simultaneously, the server process must create multiple pipe instances.

The Win32 API supports three basic strategies for servicing multiple pipe instances. The server process can do the following.

•	Create multiple threads (and/or processes) with a separate thread for each instance of the pipe. For an example of a multithreaded server process, see Section 54.2.2, »Example: A Multithreaded Server«.

•	Overlap operations by specifying an OVERLAPPED structure in the ReadFile, WriteFile, and ConnectNamedPipe functions. For an example of a server process that uses overlapped operations, see Section 54.2.3, »Example: A Server Using Overlapped Input and Output«.

•	Overlap operations by using the ReadFileEx and WriteFileEx functions, which specify a completion routine to be executed when the operation is complete. For an example of a server process that uses completion routines, see Section 54.2.4, »Example: A Server Using Completion Routines«.

The multithreaded server strategy is easy to write, because the thread for each instance handles communications for only a single client. The system allocates processor time to each thread as needed. But each thread uses system resources, which is a potential disadvantage for a server that handles a large number of clients. Other complications occur if the actions of one client necessitate communications with other clients (as with a network game program, where a move by one player must be communicated to the other players).

With a single-threaded server, it is easier to coordinate operations that affect multiple clients, and it is easier to protect shared resources (for example, a database file) from simultaneous access by multiple clients. The challenge of a single-threaded server is that it requires the coordination of overlapped operations in order to allocate processor time for handling the simultaneous needs of the clients.


  54.1.7  Named Pipe Type and Read Mode

The type of a pipe determines how data is written to a named pipe, and the read mode determines how data is read from a named pipe. Data can be transmitted through a named pipe as either a stream of bytes or as a stream of messages. When using the CreateNamedPipe function to create an instance of a named pipe, the server process specifies the type, the type it must specify for all instances.

A byte pipe is created if PIPE_TYPE_BYTE is specified, or by default if no type is specified. This means that data is written to the pipe as a stream of bytes, and the system does not differentiate between the bytes written in different write operations. A handle to a byte-type pipe can be in byte-read mode only.

A message type pipe is created if PIPE_TYPE_MESSAGE is specified. This means that the system treats each write operation to the pipe as a message unit. A handle to a message type pipe can be in either byte or message read mode.


  54.1.8  Blocking and Nonblocking Pipe Operations

The wait mode (blocking or nonblocking) of a pipe handle determines whether the ReadFile, WriteFile, and ConnectNamedPipe functions return immediately in situations that would otherwise require an indefinite wait. By default, all named pipe handles returned by the CreateNamedPipe or CreateFile functions are created with blocking mode enabled. Nonblocking mode can be enabled for a server's pipe handle by specifying PIPE_NOWAIT in CreateNamedPipe. Both server and client processes can change a pipe handle's wait mode by specifying either PIPE_WAIT or PIPE_NOWAIT in a call to the SetNamedPipeHandleState function.

Note that nonblocking mode is supported for compatibility with Microsoft LAN Manager version 2.0, and should not be used to achieve overlapped input and output (I/O) with named pipes. Instead, use overlapped I/O, which enables time-consuming ReadFile, WriteFile, and ConnectNamedPipe operations to execute in the background after the function returns. For more information about overlapped I/O, see Section 54.1.9, »Synchronous and Overlapped Input and Output«.

A ReadFile operation is affected by the wait mode of a pipe handle when the pipe is empty. With a blocking handle, the operation is not completed successfully until data is available from a thread writing to the other end of the pipe. Using a nonblocking handle, the function returns FALSE immediately and the GetLastError function returns ERROR_NO_DATA.

A WriteFile operation is affected by a pipe handle's wait mode when there is insufficient space in the pipe's buffer to hold all the data. With a blocking handle, the write operation cannot succeed until sufficient space is created in the buffer by a thread reading from the other end of the pipe. With a nonblocking handle, the write operation returns TRUE immediately, without writing any bytes (for a message-type pipe) or after writing as many bytes as the buffer holds (for a byte-type pipe).

A ConnectNamedPipe operation is affected by the wait mode of a pipe handle when there is no client connected or waiting to connect to the pipe instance. With a blocking handle, the connect operation does not succeed until a client process connects to the pipe instance by calling either CreateFile or CallNamedPipe. With a non-blocking handle, the connect operation returns FALSE immediately and the GetLastError function returns ERROR_PIPE_LISTENING.

The wait mode of a pipe handle does not affect read or write operations when using the TransactNamedPipe or CallNamedPipe functions.


  54.1.9  Synchronous and Overlapped Input and Output

The Win32 API supports both synchronous and asynchronous (overlapped) operations on named pipes. The ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe functions can run either synchronously or asynchronously. The ReadFileEx and WriteFileEx functions can run only asynchronously. When functions run synchronously, they do not return until the operation is finished. This means that the execution of the calling thread can be blocked for an indefinite period while it waits for a time-consuming operation to finish. When functions run asynchronously, they return immediately even before their operations are finished. This enables a time-consuming operation to be executed in the background while the calling thread is free to perform other tasks. In the Win32 API, this asynchronous execution is known as overlapped I/O.

Overlapped operations make it possible for one pipe to read and write data simultaneously and for a single thread to perform simultaneous I/O operations on multiple pipe handles. This enables a single-threaded server process to handle communications with multiple client processes efficiently . For examples that illustrate overlapped operations by a server process, see Section 54.2.3, »Example: A Server Using Overlapped Input and Output«, and Section 54.2.4, »Example: A Server Using Completion Routines«.

For a server process to use synchronous operations to communicate with more than one client, it must create a separate thread for each client process. This makes it possible for one or more threads to run while other threads are waiting. For an example of a multithreaded server process that uses synchronous operations, see Section 54.2.2, »Example: A Multithreaded Server«.

To enable overlapped operations on a named pipe, specify the FILE_FLAG_OVERLAPPED flag when the handle is created (by the CreateNamedPipe function for a server process or the CreateFile function for a client process). If this flag is not specified, overlapped mode is disabled. The overlapped mode of a pipe handle cannot be changed after the pipe handle has been created. The overlapped mode can be different for server and client handles to the same pipe instance.

The ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe functions can be performed asynchronously only if the specified pipe handle has overlapped mode enabled and a pointer to an OVERLAPPED structure is specified. If the OVERLAPPED pointer is NULL, the operation is performed synchronously, even though the pipe handle has overlapped mode enabled. When the functions are performed asynchronously, one of the following occurs:

•	If the operation is complete when the function returns, the return value indicates the success or failure of the operation. If an error occurs, the return value is FALSE and the GetLastError function returns something other than ERROR_IO_PENDING.

•	If the operation has not finished when the function returns, the return value is FALSE and GetLastError returns ERROR_IO_PENDING. In this case, the calling thread must wait until the operation has finished. The calling thread must then call the GetOverlappedResult function to determine the results.

The hEvent member of the specified OVERLAPPED structure must contain a handle to a manual reset — not an auto reset — event object. This is a synchronization object created by the CreateEvent function. The thread that initiates the overlapped operation uses the event object to determine when the operation is finished. For more information about event objects, see Chapter 44, »Synchronization«.

An event object is either in a signaled or not-signaled state. If an overlapped function returns before its operation has finished, the system sets the state of the event object to not-signaled. When the operation is finished, the system sets the state to signaled. The thread can detect the object's state by specifying a handle to the event object in a call to one of the wait functions: WaitForSingleObject, WaitForMultipleObjects, WaitForSingleObjectEx or WaitForMultipleObjectsEx. These functions do not return until the state of a specified object is signaled or until a time-out interval has elapsed. For the wait functions that wait for multiple objects, the function's return value indicates which of the objects is signaled. This enables a server process to use a loop that does the following:

1.	Specifies multiple event objects in a call to WaitForMultipleObjects or WaitForMultipleObjectsEx, and then waits for one of the objects to be in a signaled state.

2.	Uses the wait function's return value to determine which overlapped operation is finished.

3.	Performs the tasks necessary to clean up the completed operation and initiate the next operation for that pipe handle. This may involve starting another overlapped operation for the same pipe handle.

If the hEvent member of the OVERLAPPED structure is a NULL pointer instead of a handle to an event object, the calling thread can use the pipe handle to determine when an overlapped operation has finished. In this case, the system sets the state of the pipe handle to signaled or not-signaled, as described previously for the state of an event object. It is strongly recommended that, rather than relying on the pipe handle, you always use an event object when performing overlapped operations. In particular, you should not use the pipe handle for this purpose if you are performing simultaneous operations on the same handle. The reason for this is that you would have no way of knowing which operation's completion caused the pipe handle to be signaled. When performing simultaneous operations on the same pipe handle, the only safe technique is to use a separate OVERLAPPED structure with its own event object for each operation.

The ReadFileEx and WriteFileEx functions provide another form of overlapped I/O. Unlike the overlapped ReadFile and WriteFile functions, which use an event object to signal completion, the extended functions specify a completion routine. A completion routine is a function that is queued for execution when the read or write operation is finished. The completion routine is not executed until the thread that called ReadFileEx and WriteFileEx enters an alertable wait by calling one of the extended wait functions: WaitForSingleObjectEx, WaitForMultipleObjectsEx, or SleepEx. These functions are like the normal wait functions in that they return when a specified object is in the signaled state or when a time-out interval has elapsed. However, these functions can also perform an alertable wait that occurs when their fAlertable flag is set to TRUE. In an alertable wait, the functions that also return when a ReadFileEx or WriteFileEx completion routine is queued for execution. A server process can use the extended functions to perform a sequence of read and write operations for each client that connects to it. Each read or write operation in the sequence specifies a completion routine, and each completion routine initiates the next step in the sequence.


  54.1.10  Write-through to Remote Clients

The write-through mode of a named pipe handle affects the behavior of byte-type pipes when data is transmitted across a network. To enable write-through mode for a named pipe handle, a process specifies the FILE_FLAG_WRITE_THROUGH flag in the CreateNamedPipe function for a server process or in the CreateFile function for a client process. If this flag is not specified, write-through mode is disabled. The write-through mode of a pipe handle cannot be changed after the pipe handle has been created. The write-through mode can be different for server and client handles to the same pipe instance.

If write-through mode is not enabled, the system enhances the efficiency of network operations by buffering data until a minimum number of bytes have accumulated or until a maximum time period has elapsed. This enables multiple write operations to be combined into a single network transmission. This also means that a write operation can be completed successfully when the data is in the outbound buffer but before it is transmitted across the network.

A client process can use the SetNamedPipeHandleState function to control the number of bytes and the time-out period before transmission for a pipe on which write-through mode is disabled.

If write-through mode is enabled, the transmission across the network is not delayed and the write operation is not completed until the data is in the pipe buffer on the remote machine. Write-through mode is useful for applications that require synchronization with every write operation.

The system always performs write operations on message-type pipes as if write-through mode were enabled.


  54.1.11  Pipe Security

A server process uses ImpersonateNamedPipeClient to assume the security token of the client process connected to the specified pipe instance. This can be useful in determining whether to grant the request of a client process. For example, a named pipe server can provide access to a database or file system to which the server process has privileged access. When a client process makes a request from the server, the client typically has some lesser level of security access. By assuming the security token of the client, the server can attempt to access the protected database and the system grants or denies the server's access, based on the security level of the client. When finished, the server uses the RevertToSelf function to restore its original security token.


  54.2  Using Pipes

Pipes are useful in applications that must pass a continuous stream of data between processes. The examples in this section illustrate the following:

•	A parent process that uses an anonymous pipe for redirecting the standard input or output of a child process.

•	A named pipe server process that uses multiple threads and synchronous operations to communicate with multiple client processes.

•	A single-threaded named pipe server process that uses overlapped operations to communicate with multiple client processes.

•	A single-threaded named pipe server process that uses overlapped operations with completion routines to communicate with multiple client processes.

•	A client process that connects to and uses a message-type named pipe.

•	A client process that uses named pipe transaction operations.


  54.2.1  Using Anonymous Pipes

A typical use of anonymous pipes is to create a channel for communication between a parent process and its child process by redirecting the standard input or standard output handles of the child process. To redirect the standard output handle of a child process, the parent process does the following:

1.	Calls the GetStdHandle function to get the current standard output handle, which it saves for later use.

2.	Calls the CreatePipe function to create an anonymous pipe. This function returns handles to the read and write ends of the pipe.

3.	Calls the SetStdHandle function to set its standard output to be the write handle of the pipe.

4.	Calls the CreateProcess function to create the child process. The child process inherits the inheritable handles of the parent process. It also inherits the values of the standard handles of its parent process, which it can retrieve using the GetStdHandle function.

5.	Calls the CloseHandle function to close the parent's handle to the write end of the pipe. After the child process inherits this handle, the parent process no longer needs its copy of the handle.

6.	Calls the ReadFile function to read from the pipe. This operation enables the parent process to read the data written to standard output by the child process.

The child process uses the GetStdHandle function to get its standard output handle, which is actually a handle to the write end of the pipe. The child process then uses the WriteFile function to write its output to the pipe.

Data is written to an anonymous pipe as a stream of bytes. This means that a process reading from a pipe cannot distinguish between the bytes written in separate write operations, unless both reading and writing processes use some protocol that lets the reader know how many bytes to read. Typically, there is no protocol, so the reading process reads from the pipe until all write handles to the pipe are closed, which causes the ReadFile function to return FALSE. When a child process's standard output is redirected, this occurs when the child process calls CloseHandle or terminates (which automatically closes the handle). Note that it is important for the parent process to close its handle to the write end of the pipe before trying to read from the pipe. Otherwise, its ReadFile operation cannot return FALSE because there is still an open handle to the write end of the pipe.

The procedure for redirecting standard input is similar to that for redirecting standard output, except that the pipe's read handle is used for the child's standard input. In this case, the parent process must ensure that the child process does not inherit the pipe's write handle. Otherwise, the ReadFile operation of the child process cannot return FALSE because the child process has an open handle to the write end of the pipe.

The parent process typically creates the read and write handles to the pipe so that they can be inherited by a child process. It does this through CreatePipe, by specifying a SECURITY_ATTRIBUTES structure with its bInheritHandle member set to TRUE. When redirecting a child's standard input, you do not want the child process to inherit the pipe's write handle. The parent process accomplishes this by using the DuplicateHandle function to create a noninheritable duplicate of the handle, and then using CloseHandle to close the inheritable handle.

For an example program that uses anonymous pipes to redirect the standard handles of a child process, see Chapter 43, »Processes and Threads«.


  54.2.2  Example: A Multithreaded Server

This example of a multithreaded server process has a main thread that loops continuously, creating a pipe instance and waiting for a client process to connect. When a client process connects, the server process creates a thread to service that client and the loop starts over. It is possible for a client process to connect successfully to the pipe instance in the interval between the CreateNamedPipe and ConnectNamedPipe function calls. If this happens, ConnectNamedPipe returns FALSE, with GetLastError returning ERROR_PIPE_CONNECTED.

The thread created to service each pipe instance reads requests from the pipe and writes replies to the pipe until the client process closes its handle. When this happens, the thread flushes the pipe, disconnects, closes its pipe handle, and terminates.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <windows.h>

VOID InstanceThread(LPVOID);

VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

int xx = 0;

DWORD main(VOID) {

  BOOL fConnected;

  DWORD dwThreadId;

  HANDLE hPipe, hThread;

  LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

  /*

   * Main loop creates an instance of the named pipe, and

   * then waits for a client to connect to it. When the client

   * connects, a thread is created to handle communications

   * with that client, and the loop is repeated.

   */

  for (;;) {

      hPipe = CreateNamedPipe(

          lpszPipename,             /* pipe name          */

          PIPE_ACCESS_DUPLEX,       /* read/write access  */

          PIPE_TYPE_MESSAGE |       /* message type pipe  */

          PIPE_READMODE_MESSAGE |   /* message-read mode  */

          PIPE_WAIT,                /* blocking mode      */

          PIPE_UNLIMITED_INSTANCES, /* max. instances     */

          BUFSIZE,                  /* output buffer size */

          BUFSIZE,                  /* input buffer size  */

          PIPE_TIMEOUT,             /* client time-out    */

          NULL);                    /* no security attr.  */

      if (hPipe == INVALID_HANDLE_VALUE)

          MyErrExit("CreatePipe");

      /*

       * Wait for the client to connect; if it succeeds

       * the function returns TRUE. If the function returns FALSE,

       * GetLastError returns ERROR_PIPE_CONNECTED.

       */

      fConnected = ConnectNamedPipe(hPipe, NULL) ?

                   TRUE :

                   (GetLastError() == ERROR_PIPE_CONNECTED);

      if (fConnected) {

          /* Create a thread for this client. */

          hThread = CreateThread(

              NULL,           /* no security attr.    */

              0,              /* default stack size   */

              (LPTHREAD_START_ROUTINE) InstanceThread,

              (LPVOID) hPipe, /* thread parameter     */

              0,              /* not suspended        */

              &dwThreadId);   /* returns thread ID    */

          if (hThread == INVALID_HANDLE_VALUE)

              MyErrExit("CreateThread");

      } else

         /* The client could not connect, so close the pipe. */

         CloseHandle(hPipe);

  }

  return 1;

}

VOID InstanceThread(LPVOID lpvParam) {

  CHAR chRequest[BUFSIZE];

  CHAR chReply[BUFSIZE];

  DWORD cbBytesRead, cbReplyBytes, cbWritten;

  BOOL fSuccess;

  HANDLE hPipe;

  /* The thread's parameter is a handle to a pipe instance. */

  hPipe = (HANDLE) lpvParam;

  while (1) {

      /* Read client requests from the pipe. */

      fSuccess = ReadFile(

          hPipe,        /* handle to pipe         */

          chRequest,    /* buffer to receive data */

          BUFSIZE,      /* size of buffer         */

          &cbBytesRead, /* number of bytes read   */

          NULL);        /* not overlapped I/O     */

      if (! fSuccess || cbBytesRead == 0)

          break;

      GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);

      /* Write the reply to the pipe. */

      fSuccess = WriteFile(

         hPipe,        /* handle to pipe           */

         chReply,      /* buffer to write from     */

         cbReplyBytes, /* number of bytes to write */

         &cbWritten,   /* number of bytes written  */

         NULL);        /* not overlapped I/O       */

      if (! fSuccess || cbReplyBytes != cbWritten) break;

  }

  /*

   * Flush the pipe to allow the client to read the pipe's contents

   * before disconnecting, then disconnect the pipe and close the handle

   * to this pipe instance.

   */

  FlushFileBuffers(hPipe);

  DisconnectNamedPipe(hPipe);

  CloseHandle(hPipe);

}


  54.2.3  Example: A Server Using Overlapped Input and Output

This example is a single-threaded server process that uses overlapped operations to service simultaneous connections to multiple client processes. The server process creates a fixed number of pipe instances, each of which can be connected to a separate client process. When a client process has finished using its pipe instance, the server disconnects from the client and reuses the pipe instance to connect to a new client.

Associated with each pipe instance is an OVERLAPPED structure containing an event object. This OVERLAPPED structure is specified as a parameter in each ReadFile, WriteFile, and ConnectNamedPipe operation on that pipe instance. Although the example makes simultaneous operations possible on different pipe instances, it is careful to avoid simultaneous operations on a single pipe instance. This is because the same event object is used for read, write, and connect operations for each instance, so with simultaneous operations on the same pipe instance, there would be no way to know which operation's completion caused the event to be set to the signaled state.

The event handles for each pipe instance are also stored in an array used by the WaitForMultipleObjects function. This function waits for one of the events to be signaled, and its return value is the array index of the event that satisfied the wait. The example uses this index to retrieve a structure containing information for this pipe instance. The server uses the fPendingIO member of this structure to keep track of whether the most recent I/O operation on that instance was pending, necessitating a call to the GetOverlappedResult function. It uses the dwState member of the structure to determine the next operation that must be performed for this instance.

Overlapped ReadFile, WriteFile, and ConnectNamedPipe operations may have finished when the function returns, or they may still be pending when the function returns. If the operation is pending, the event object in the specified OVERLAPPED structure is set to the not-signaled state before the function returns. When the pending operation has finished, the system sets the state of the event object to signaled. The state of the event object is not changed if the operation finishes before the function returns.

Because the example uses manual reset event objects, the state of the event objects is not changed to not-signaled by the WaitForMultipleObjects function. This is important, because the example relies on the event objects remaining in the signaled state except when there is a pending operation.

If the operation is already finished when ReadFile, WriteFile, or ConnectNamedPipe returns, the function's return value indicates the result. For read and write operations, the number of bytes transferred is also returned. If the operation is still pending, the ReadFile, WriteFile, or ConnectNamedPipe function returns FALSE and the GetLastError function returns ERROR_IO_PENDING. In this case, the results are retrieved using the GetOverlappedResult function after the operation has finished. GetOverlappedResult returns only the results of operations that were pending, and does not report the results of operations that were completed before the overlapped ReadFile, WriteFile, or ConnectNamedPipe returned.

Before disconnecting from a client, the multithreaded server example in the previous section used FlushFileBuffers to ensure that the client had read everything written to the pipe. This would defeat the purpose of overlapped I/O, because the flush operation would block the execution of the server thread while waiting for the client to empty the pipe. Consequently, it is necessary to wait for a signal from the client that it has finished before disconnecting. In this example, the signal is the error generated by trying to read from the pipe after the client process closes its handle.

#include <windows.h>

#define CONNECTING_STATE 0

#define READING_STATE 1

#define WRITING_STATE 2

#define INSTANCES 4

typedef struct {

  OVERLAPPED oOverlap;

  HANDLE hPipeInst;

  CHAR chBuf[BUFSIZE];

  DWORD cbToWrite;

  DWORD dwState;

  BOOL fPendingIO;

} PIPEINST, *LPPIPEINST;

VOID DisconnectAndReconnect(DWORD);

BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);

VOID GetDataToWriteToClient(LPPIPEINST);

PIPEINST Pipe[INSTANCES];

HANDLE hEvents[INSTANCES];

DWORD main(VOID) {

  DWORD i, dwWait, cbBytes, dwErr;

  BOOL fSuccess;

  LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

  /*

   * The initial loop creates several instances of a named pipe,

   * along with an event object for each instance.  An

   * overlapped ConnectNamedPipe operation is started for

   * each instance.

   */

  for (i = 0; i < INSTANCES; i++) {

      /* Create an event object for this instance. */

      hEvents[i] = CreateEvent(

          NULL,    /* no security attr.        */

          TRUE,    /* manual reset event       */

          TRUE,    /* initial state = signaled */

          NULL);   /* unnamed event object     */

      if (hEvents[i] == NULL)

          MyErrExit("CreateEvent");

      Pipe[i].oOverlap.hEvent = hEvents[i];

      Pipe[i].hPipeInst = CreateNamedPipe(

          lpszPipename,            /* pipe name           */

          PIPE_ACCESS_DUPLEX |     /* read/write access   */

          FILE_FLAG_OVERLAPPED,    /* overlapped mode     */

          PIPE_TYPE_MESSAGE |      /* message-type pipe   */

          PIPE_READMODE_MESSAGE |  /* message-read mode   */

          PIPE_WAIT,               /* blocking mode       */

          INSTANCES,               /* number of instances */

          BUFSIZE,                 /* output buffer size  */

          BUFSIZE,                 /* input buffer size   */

          PIPE_TIMEOUT,            /* client time-out     */

          NULL);                   /* no security attr    */

      if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)

          MyErrExit("CreatePipe");

      /* Call the subroutine to connect to the new client. */

      Pipe[i].fPendingIO = ConnectToNewClient(

          Pipe[i].hPipeInst,

          &Pipe[i].oOverlap);

      Pipe[i].dwState = Pipe[i].fPendingIO ?

          CONNECTING_STATE : /* still connecting   */

          READING_STATE;     /* ready to read      */

  }

  while (1) {

      /*

       * Wait for the event object to be signaled, indicating

       * completion of an overlapped read, write, or

       * connect operation.

       */

      dwWait = WaitForMultipleObjects(

         INSTANCES,    /* number of event objects */

         hEvents,      /* array of event objects  */

         FALSE,        /* does not wait for all   */

         INFINITE);    /* waits indefinitely      */

      /* dwWait shows which pipe had completed operation.  */

      i = dwWait - WAIT_OBJECT_0; /* determines which pipe */

      if (i < 0 || i > (INSTANCES - 1))

          MyErrExit("index out of range");

      /* Get the result if the operation was pending. */

      if (Pipe[i].fPendingIO) {

          fSuccess = GetOverlappedResult(

               Pipe[i].hPipeInst, /* handle to pipe       */

               &Pipe[i].oOverlap, /* OVERLAPPED structure */

               &cbBytes,          /* bytes transferred    */

               FALSE);            /* do not wait          */

          switch (Pipe[i].dwState) {

              /* Pending connect operation */

              case CONNECTING_STATE:

                  if (! fSuccess)

                      MyErrExit("ConnectNamedPipe");

                  Pipe[i].dwState = READING_STATE;

                  break;

              /* Pending read operation */

              case READING_STATE:

                  if (! fSuccess || cbBytes == 0) {

                      DisconnectAndReconnect(i);

                      continue;

                  }

                  Pipe[i].dwState = WRITING_STATE;

                  break;

              /* Pending write operation */

              case WRITING_STATE:

                  if (! fSuccess ||

                          cbBytes != Pipe[i].cbToWrite) {

                      DisconnectAndReconnect(i);

                      continue;

                  }

                  Pipe[i].dwState = READING_STATE;

                  break;

              default:

                  MyErrExit("invalid pipe state");

          }

      }

      /* The pipe state determines which operation to do next. */

      switch (Pipe[i].dwState) {

          /*

           * READING_STATE:

           * The pipe instance is connected to the client

           * and ready to read a request from the client.

           */

          case READING_STATE:

                  fSuccess = ReadFile(

                  Pipe[i].hPipeInst,

                  Pipe[i].chBuf,

                  BUFSIZE,

                  &cbBytes,

                  &Pipe[i].oOverlap);

              /* The read operation was successfully completed. */

              if (fSuccess && cbBytes != 0) {

                  Pipe[i].fPendingIO = FALSE;

                  Pipe[i].dwState = WRITING_STATE;

                  continue;

              }

              /* The read operation is still pending */

              dwErr = GetLastError();

              if (! fSuccess &&

                    (dwErr == ERROR_IO_PENDING)) {

                Pipe[i].fPendingIO = TRUE;

                continue;

              }

              /* An error occurred; disconnect from the client. */

              DisconnectAndReconnect(i);

              break;

          /*

           * WRITING_STATE:

           * The request was successfully read from the client.

           * Get the reply data and write it to the client.

           */

          case WRITING_STATE:

              GetDataToWriteToClient(&Pipe[i]);

              fSuccess = WriteFile(

                  Pipe[i].hPipeInst,

                  Pipe[i].chBuf,

                  Pipe[i].cbToWrite,

                  &cbBytes,

                  &Pipe[i].oOverlap);

              /* Write operation completed successfully */

              if (fSuccess &&

                      cbBytes == Pipe[i].cbToWrite) {

                  Pipe[i].fPendingIO = FALSE;

                  Pipe[i].dwState = READING_STATE;

                  continue;

              }

              /* The write operation is still pending. */

              dwErr = GetLastError();

              if (! fSuccess &&

                      (dwErr == ERROR_IO_PENDING)) {

                  Pipe[i].fPendingIO = TRUE;

                  continue;

              }

              /* An error occurred; disconnect from the client. */

              DisconnectAndReconnect(i);

              break;

          default:

              MyErrExit("invalid pipe state");

      }

  }

  return 0;

}

/*

 * DisconnectAndReconnect(DWORD)

 * This function is called when an error occurs or when the client

 * closes its handle to the pipe. Disconnect from this client, and then

 * call ConnectNamedPipe to wait for another client to connect.

 */

VOID DisconnectAndReconnect(DWORD i) {

  /* Disconnect the pipe instance. */

  if (! DisconnectNamedPipe(Pipe[i].hPipeInst) )

      MyErrExit("DisconnectNamedPipe");

  /* Call a subroutine to connect to the new client. */

  Pipe[i].fPendingIO = ConnectToNewClient(

      Pipe[i].hPipeInst,

      &Pipe[i].oOverlap);

  Pipe[i].dwState = Pipe[i].fPendingIO ?

      CONNECTING_STATE : /* still connecting   */

      READING_STATE;     /* ready to read      */

}

/*

 * ConnectToNewClient(HANDLE, LPOVERLAPPED)

 * This function is called to start an overlapped connect operation. It

 * returns TRUE if an operation is pending or FALSE if the connection

 * has been completed.

 */

BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo) {

  BOOL fConnected, fPendingIO = FALSE;

  /* Start an overlapped connection for this pipe instance. */

  fConnected = ConnectNamedPipe(hPipe, lpo);

  /* Overlapped ConnectNamedPipe should return FALSE */

  if (fConnected)

      MyErrExit("ConnectNamedPipe");

  switch (GetLastError()) {

      /* Overlapped connection in progress */

      case ERROR_IO_PENDING:

          fPendingIO = TRUE;

          break;

      /* Client already connected, so signal an event. */

      case ERROR_PIPE_CONNECTED:

          if (SetEvent(lpo->hEvent))

              break;

      /* If an error occurs during the connection operation... */

      default:

          MyErrExit("ConnectNamedPipe");

  }

  return fPendingIO;

}

The ReadFileEx and WriteFileEx functions provide another form of overlapped I/O. Unlike the overlapped ReadFile and WriteFile functions, which use an event object to signal completion, the extended functions specify a completion routine. A completion routine is a function that is queued for execution when the read or write operation is done. The completion routine is not executed until the thread that called ReadFileEx and WriteFileEx enters an alertable wait by calling one of the extended wait functions: WaitForSingleObjectEx, WaitForMultipleObjectsEx, or SleepEx. These functions are like the other wait functions in that they return when a specified object is in the signaled state or when a time-out interval has elapsed. However, these functions can also perform an alertable wait, which occurs when their fAlertable flag is set to TRUE. In an alertable wait, the functions also return when a ReadFileEx or WriteFileEx completion routine is queued for execution. A server process can use the extended functions to perform a sequence of read and write operations for each client that connects to it. Each read or write operation in the sequence specifies a completion routine, and each completion routine initiates the next step in the sequence.

This example is a single-threaded server process that uses overlapped operations to handle simultaneous connections to multiple client processes. The server process creates a fixed number of pipe instances, each of which can be connected to a separate client process. When a client process has finished using its pipe instance, the server disconnects from the client and reuses the pipe instance to connect to a new client.

Associated with each pipe instance is an OVERLAPPED structure containing an event object. This OVERLAPPED structure is specified as a parameter in each ReadFile, WriteFile, and ConnectNamedPipe operation on that pipe instance.


  54.2.4  Example: A Server Using Completion Routines

Like the previous example, this example is a single-threaded server process that creates a message-type pipe and uses overlapped operations. This server process differs in that it uses the extended functions ReadFileEx and WriteFileEx to perform overlapped I/O. Unlike the overlapped ReadFile and WriteFile functions, which signal an event object upon completion, the extended functions specify a completion routine, which is queued for execution when the operation is finished. The server process uses the WaitForSingleObjectEx function, which performs an alertable wait that returns when a completion routine is ready to execute. The wait function also returns when an event object is signaled, which in this example indicates that the overlapped ConnectNamedPipe operation has finished (a new client has connected).

Initially, the server process creates a single instance of the pipe and starts an overlapped ConnectNamedPipe operation. When a client connects, the server allocates a structure to provide storage for that pipe instance and then calls the ReadFileEx function to launch a sequence of I/O operations to handle communications with the client. Each operation specifies a completion routine that performs the next operation in the sequence. The sequence terminates when the client is disconnected and the pipe instance closed. After starting the sequence of operations for the new client, the server creates another pipe instance and waits for the next client to connect.

The parameters to the ReadFileEx and WriteFileEx functions specify a completion routine and a pointer to an OVERLAPPED structure. This pointer is later passed to the completion routine in its lpOverLap parameter. Because the OVERLAPPED structure points to the first member in the structure allocated for each pipe instance, the completion routine can use its lpOverLap parameter to access the structure for the pipe instance.

To avoid duplication, the listing for the ConnectToNewClient subroutine is not shown; it is identical to the one used by the overlapped server process in the previous section.

#include <windows.h>

typedef struct {

  OVERLAPPED oOverlap;

  HANDLE hPipeInst;

  CHAR chBuf[BUFSIZE];

  DWORD cbToWrite;

} PIPEINST, *LPPIPEINST;

BOOL CreateAndConnectInstance();

BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);

VOID GetDataToWriteToClient(LPPIPEINST);

VOID DisconnectAndClose(LPPIPEINST);

VOID CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED);

VOID CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED);

HANDLE hPipe;

DWORD main(VOID) {

  HANDLE hConnectEvent;

  OVERLAPPED oConnect;

  LPPIPEINST lpPipeInst;

  DWORD dwWait, cbBytes;

  BOOL fSuccess, fPendingIO;

  /* Create one event object for the connection operation */

  hConnectEvent = CreateEvent(

      NULL,    /* no security attr.         */

      TRUE,    /* manual reset event        */

      TRUE,    /* initial state = signaled  */

      NULL);   /* unnamed event object      */

  if (hConnectEvent == NULL)

      MyErrExit("CreateEvent");

  oConnect.hEvent = hConnectEvent;

  /*

   * Call a subroutine to create one instance, and wait for

   * the client to connect.

   */

  fPendingIO = CreateAndConnectInstance(&oConnect);

  while (1) {

   /*

    * Wait for a client to connect, or for a read or write

    * operation to be completed, which causes a completion

    * routine to be queued for execution.

    */

      dwWait = WaitForSingleObjectEx(

          hConnectEvent,  /* event object to wait for */

          INFINITE,       /* waits indefinitely       */

          TRUE);          /* alertable wait enabled   */

      switch (dwWait) {

        /* The wait is satisfied by a completed connection operation. */

          case 0:

              /* If an operation is pending, get the result of the

               * connection operation.

               */

              if (fPendingIO) {

                  fSuccess = GetOverlappedResult(

                      hPipe,     /* pipe handle          */

                      &oConnect, /* OVERLAPPED structure */

                      &cbBytes,  /* bytes transferred    */

                      FALSE);    /* does not wait        */

                  if (! fSuccess)

                      MyErrExit("ConnectNamedPipe");

              }

              /* Allocate storage for this instance. */

              lpPipeInst = (LPPIPEINST) GlobalAlloc(

                  GPTR, sizeof(PIPEINST));

              if (lpPipeInst == NULL)

                  MyErrExit("GlobalAlloc lpPipeInst");

              lpPipeInst->hPipeInst = hPipe;

              /*

               * Start the read operation for this client.

               * Note that this same routine is later used as a

               * completion routine after a write operation.

               */

              lpPipeInst->cbToWrite = 0;

              CompletedWriteRoutine(0, 0,

                  (LPOVERLAPPED) lpPipeInst);

              /* Create new pipe instance for the next client. */

              fPendingIO = CreateAndConnectInstance(

                  &oConnect);

              break;

        /*

         * The wait is satisfied by a completed read or write

         * operation. This allows the system to execute the

         * completion routine.

         */

          case WAIT_IO_COMPLETION:

              break;

        /* An error occurred in the wait function. */

          default:

              MyErrExit("WaitForSingleObjectEx");

      }

  }

  return 0;

}

/*

 * CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED)

 * This routine is called as an I/O completion routine after writing to

 * the pipe, or when a new client has connected to a pipe instance. It

 * starts another read operation.

 */

VOID CompletedWriteRoutine(DWORD dwErr, DWORD cbWritten,

    LPOVERLAPPED lpOverLap) {

  LPPIPEINST lpPipeInst;

  BOOL fRead = FALSE;

  /* lpOverlap points to storage for this instance. */

  lpPipeInst = (LPPIPEINST) lpOverLap;

  /*

   * The write operation has finished, so read the next request (if no

   * errorred).

   */

  if ((dwErr == 0) && (cbWritten == lpPipeInst->cbToWrite))

      fRead = ReadFileEx(

          lpPipeInst->hPipeInst,

          lpPipeInst->chBuf,

          BUFSIZE,

          (LPOVERLAPPED) lpPipeInst,

          (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine);

  /* Disconnect if an error occurred. */

  if (! fRead)

      DisconnectAndClose(lpPipeInst);

}

/*

 * CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED)

 * This routine is called as an I/O completion routine after reading a

 * request from the client. It gets data and writes it to the pipe.

 */

VOID CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead,

    LPOVERLAPPED lpOverLap) {

  LPPIPEINST lpPipeInst;

  BOOL fWrite = FALSE;

  /* lpOverlap points to storage for this instance */

  lpPipeInst = (LPPIPEINST) lpOverLap;

  /*

   * The read operation has finished, so write a response (if no

   * error).

   */

  if ((dwErr == 0) && (cbBytesRead != 0)) {

      GetDataToWriteToClient(lpPipeInst);

      fWrite = WriteFileEx(

          lpPipeInst->hPipeInst,

          lpPipeInst->chBuf,

          lpPipeInst->cbToWrite,

          (LPOVERLAPPED) lpPipeInst,

          (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteRoutine);

  }

  /* Disconnect if an error occurred. */

  if (! fWrite)

      DisconnectAndClose(lpPipeInst);

}

/*

 * DisconnectAndClose(LPPIPEINST)

 * Called when error occurs or when the client closes its handle

 * to the pipe.

 */

VOID DisconnectAndClose(LPPIPEINST lpPipeInst)

{

  /* Disconnect the pipe instance. */

  if (! DisconnectNamedPipe(lpPipeInst->hPipeInst) )

      MyErrExit("DisconnectNamedPipe");

  /* Close the handle to the pipe instance. */

  CloseHandle(lpPipeInst->hPipeInst);

  /* Release the storage for the pipe instance. */

  if (lpPipeInst != NULL)

      GlobalFree(lpPipeInst);

}

/*

 * CreateAndConnectInstance(LPOVERLAPPED)

 * This function creates a pipe instance and connects to the new client.

 * It returns TRUE if the connection operation is pending FALSE if

 * the connection has been completed.

 */

BOOL CreateAndConnectInstance(LPOVERLAPPED lpoOverlap) {

  LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

  hPipe = CreateNamedPipe(

      lpszPipename,             /* pipe name           */

      PIPE_ACCESS_DUPLEX |      /* read/write access   */

      FILE_FLAG_OVERLAPPED,     /* overlapped mode     */

      PIPE_TYPE_MESSAGE |       /* message-type pipe   */

      PIPE_READMODE_MESSAGE |   /* message read mode   */

      PIPE_WAIT,                /* blocking mode       */

      PIPE_UNLIMITED_INSTANCES, /* unlimited instances */

      BUFSIZE,                  /* output buffer size  */

      BUFSIZE,                  /* input buffer size   */

      PIPE_TIMEOUT,             /* client time-out     */

      NULL);                    /* no security attr.   */

  if (hPipe == INVALID_HANDLE_VALUE)

      MyErrExit("CreatePipe");

  /* Call a subroutine to connect to the new client. */

  return ConnectToNewClient(hPipe, lpoOverlap);

}


  54.2.5  The Named Pipe Client Process

A client process uses the CreateFile function to open a handle to a named pipe. If the pipe exists but all of its instances are busy, CreateFile returns FALSE and the GetLastError function returns ERROR_PIPE_BUSY. When this happens, the client process uses the WaitNamedPipe function to wait for an instance of the pipe to be available.

The CreateFile function fails if the access specified is incompatible with the access specified (duplex, outbound, or inbound) when the server created the pipe. For a duplex pipe (read/write), the client can specify read, write, or read/write access; for an outbound pipe (server write only), the client must specify read only; for an inbound pipe (server read only), the client must specify write only.

The handle returned by CreateFile defaults to byte-read mode, blocking-wait mode, overlapped mode disabled, and write-through mode disabled. The client process can use the CreateFile function to enable overlapped mode by specifying FILE_FLAG_OVERLAPPED, or write-through mode by specifying FILE_FLAG_WRITE_THROUGH. The client can use the SetNamedPipeHandleState function to enable nonblocking mode by specifying PIPE_WAIT, or message-read mode by specifying PIPE_READMODE_MESSAGE.

The following example shows a client process that opens a named pipe, sets the pipe handle to message-read mode, uses WriteFile to send a request to the server, and uses ReadFile to read the server's reply. You could use this client process with any of the message-type servers shown in the previous sections. With a byte-type server, however, this client process fails when it calls SetNamedPipeHandleState to change to message-read mode. Because the client is reading from the pipe in message-read mode, it is possible for the ReadFile operation to return FALSE after reading a partial message. This happens when the message is larger than the read buffer. In this situation, GetLastError returns ERROR_MORE_DATA and the remainder of the message is read by additional calls to ReadFile.

#include <windows.h>

 DWORD main(int argc, char *argv[]) {

  HANDLE hPipe;

  LPVOID lpvMessage;

  CHAR chBuf[512];

  BOOL fSuccess;

  DWORD cbRead, cbWritten, dwMode;

  LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

  /* Try to open a named pipe; wait for it, if necessary. */

  while (1) {

      hPipe = CreateFile(

          lpszPipename,   /* pipe name           */

          GENERIC_READ |  /* read/write access   */

          GENERIC_WRITE,

          0,              /* no sharing          */

          NULL,           /* no security attr.   */

          OPEN_EXISTING,  /* opens existing pipe */

          0,              /* default attributes  */

          NULL);          /* no template file    */

      /* Break if the pipe handle is valid. */

      if (hPipe != INVALID_HANDLE_VALUE)

          break;

      /* Exit if an error other than ERROR_PIPE_BUSY occurs */

      if (GetLastError() != ERROR_PIPE_BUSY)

          MyErrExit("Could not open pipe");

      /* All pipe instances are busy, so wait for 20 seconds. */

      if (! WaitNamedPipe(lpszPipename, 20000) )

          MyErrExit("Could not open pipe");

  }

  /* The pipe connected; change to message read mode. */

  dwMode = PIPE_READMODE_MESSAGE;

  fSuccess = SetNamedPipeHandleState(

      hPipe,    /* pipe handle          */

      &dwMode,  /* new pipe mode        */

      NULL,     /* don't set max. bytes */

      NULL);    /* don't set max. time  */

  if (! fSuccess)

      MyErrExit("SetNamedPipeHandleState");

  /* Send a message to the pipe server. */

  lpvMessage = (argc > 1) ? argv[1] : "default message";

  fSuccess = WriteFile(

      hPipe,                  /* pipe handle     */

      lpvMessage,             /* message         */

      strlen(lpvMessage) + 1, /* message length  */

      &cbWritten,             /* bytes written   */

      NULL);                  /* not overlapped  */

  if (! fSuccess)

      MyErrExit("WriteFile");

  do {

      /* Read from the pipe. */

      fSuccess = ReadFile(

          hPipe,    /* pipe handle              */

          chBuf,    /* buffer to receive reply  */

          512,      /* size of buffer           */

          &cbRead,  /* number of bytes read     */

          NULL);    /* not overlapped           */

      if (! fSuccess && GetLastError() != ERROR_MORE_DATA)

          break;

      /* Reply from pipe written to stdout. */

      if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),

              chBuf, cbRead, &cbWritten, NULL))

          break;

  } while (! fSuccess); /* repeat loop if ERROR_MORE_DATA */

  CloseHandle(hPipe);

  return 0;

}


  54.2.6  Transactions on Named Pipes

A named pipe transaction is a client-server communication that combines a write operation and a read operation into a single network operation. A transaction can be used only on a duplex, message-type pipe. Transactions improve the performance of network communications between a client and a remote server. Processes can use the TransactNamedPipe and CallNamedPipe functions to perform named pipe transactions.

The TransactNamedPipe function is typically used by a client process to write a request message to the named pipe server and read the server's response message. The client process must specify GENERIC_READ | GENERIC_WRITE access when it opens its pipe handle by calling the CreateFile function. Then, the client process sets the pipe handle to message-read mode by calling the SetNamedPipeHandleState function. If the read buffer specified in the call to TransactNamedPipe is not large enough to hold the entire message written by the server, the function returns FALSE and GetLastError returns ERROR_MORE_DATA. The client can read the remainder of the message by calling either ReadFile, ReadFileEx, or PeekNamedPipe.

TransactNamedPipe is typically called by client processes, but can also be used by a server process.

The following example shows a client process using TransactNamedPipe. The example presumes the client process has used CreateFile to connect to the pipe and SetNamedPipeHandleState to set the pipe handle's read mode, as shown in the client process example of the previous section.

fSuccess = TransactNamedPipe(

    hPipe,               /* pipe handle             */

    lpszWrite,           /* message to server       */

    strlen(lpszWrite)+1, /* message length          */

    chReadBuf,           /* buffer to receive reply */

    512,                 /* size of read buffer     */

    &cbRead,             /* number of bytes read    */

    NULL);               /* not overlapped          */

/*

 * Exit if an error occurs, unless the error indicates there is more

 * data in the message.

 */

if (! fSuccess && (GetLastError() != ERROR_MORE_DATA))

    MyErrExit("TransactNamedPipe");

while(1) {

    /* Data from the pipe is written to stdout. */

    if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),

            chReadBuf, cbRead, &cbWritten, NULL) )

        break;

    /* Break if successful TransactNamedPipe or ReadFile. */

    if (fSuccess)

        break;

    /* Read from the pipe if there is more data in the message.*/

    fSuccess = ReadFile(

        hPipe,      /* pipe handle              */

        chReadBuf,  /* buffer to receive reply  */

        512,        /* size of buffer           */

        &cbRead,    /* number of bytes read     */

        NULL);      /* not overlapped           */

    /* Exit if an error other than ERROR_MORE_DATA occurs. */

    if (! fSuccess && (GetLastError() != ERROR_MORE_DATA))

        break;

}

A client process uses the CallNamedPipe function to combine the CreateFile, WaitNamedPipe (if necessary), TransactNamedPipe, and CloseHandle operations into a single function. Because the pipe handle is closed before the function returns, any additional bytes in the message are lost if the message is larger than the specified size of the read buffer.

The following example shows the use of CallNamedPipe.

/* Combines connect, wait, write, read, and close */

fSuccess = CallNamedPipe(

    lpszPipename,        /* pipe name               */

    lpszWrite,           /* message to server       */

    strlen(lpszWrite)+1, /* message length          */

    chReadBuf,           /* buffer to receive reply */

    512,                 /* size of read buffer     */

    &cbRead,             /* number of bytes read    */

    20000);              /* waits for 20 seconds    */

if (fSuccess || GetLastError() == ERROR_MORE_DATA) {

    /* Data from the pipe is written to stdout. */

    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),

        chReadBuf, cbRead, &cbWritten, NULL);

    /*

     * The pipe is closed; so no more bytes can be read from the

     * message.

     */

    if (! fSuccess)

        printf("\n...extra data in message was lost\n");

}


  54.3  Functions

Following are the functions used with pipes.

CallNamedPipe
ConnectNamedPipe
CreateNamedPipe
CreatePipe
DisconnectNamedPipe
GetNamedPipeHandleState
GetNamedPipeInfo
PeekNamedPipe
SetNamedPipeHandleState
TransactNamedPipe
WaitNamedPipe


Mailslots
  Chapter 55    Mailslots

55.1  About Mailslots

A mailslot is a mechanism for one-way interprocess communications. An application written for Microsoft Windows can store messages in a mailslot. The owner of the mailslot can retrieve messages that are stored there. Mailslot messages are typically sent over a network to either a specified computer or to all computers in a specified domain. A domain is a group of workstations and servers that share a group name.

A mailslot is a pseudofile; it resides in memory, and standard Windows file functions write to it. Unlike disk files, however, mailslots are temporary. When every handle of a mailslot is closed, the mailslot and all the data it contains are deleted. The data in a mailslot message can be in any form.

A mailslot server is a process that creates and owns a mailslot. When the server creates a mailslot, it receives a mailslot handle. This handle must be used when a process reads messages from the mailslot. Only the process that creates a mailslot (or has obtained the handle by some other mechanism, such as inheritance) can read from the mailslot. A mailslot exists until all server handles to it have been closed or all server processes have exited. All mailslots are local to the process that creates them; a process cannot create a remote mailslot.

A mailslot client is a process that writes a message to a mailslot. Any process that has the name of a mailslot can put a message there. New messages follow preexisting messages in the mailslot.

Mailslots can broadcast messages within a domain. If several processes in a domain each create a mailslot using the same name, every message that is addressed to that mailslot and sent to the domain is received by the participating processes. Because one process can control both a server mailslot handle and the client handle retrieved when the mailslot is opened for a write operation, applications can easily implement a simple message-passing facility within a domain.

Some developers choose to use named pipes instead of mailslots for interprocess communications (IPC). Named pipes are a simple way for two processes to exchange messages. Mailslots, on the other hand, are a simple way for a process to broadcast messages to many other processes. For more information about named pipes, see Chapter 54, »Pipes«.

There is another issue involved in the choice between mailslots and named pipes. Mailslots use datagrams, and named pipes do not. A datagram is a small packet of information that the network sends along the wire. Like a radio or television broadcast, a datagram offers no confirmation of receipt; there is no  way to guarantee that a datagram has been received. Just as mountains, large buildings, or interfering signals might cause a radio or television signal to get lost, there are things the sender has no knowledge of that can prevent a datagram from reaching a particular destination. Named pipes are more like simple one-to-one telephone calls: you can only talk to one party, but you know that the conversation is occurring. So, if an application needs guaranteed reception, it  should use a named pipe; but named pipes cannot broadcast. Mailslots do not guarantee reception, but they can broadcast.


  55.1.1  Mailslot Names

When a process creates a mailslot, the mailslot name must have the following form.

\\.\mailslot\[path]name

A mailslot name requires the following elements: two backslashes to begin the name, a period, a backslash following the period, the word mailslot, and a trailing backslash. Case, however, is not important. A mailslot name can be preceded by a path consisting of the names of one or more pseudodirectories; separated by backslashes. For example, if a user expects messages on the subject of taxes from Bob, Pete, and Sue; the user's mailslot application might allow the user to create individual mailslots for each sender.

\\.\mailslot\taxes\bobs_comments
\\.\mailslot\taxes\petes_comments
\\.\mailslot\taxes\sues_comments

To put a message into a mailslot, a process opens a mailslot whose name is in one of several forms. To write to a mailslot on the local computer, a process can use a mailslot name using the same form required for creating a mailslot. This situation, however, is relatively uncommon. More frequently, a process uses the following form to write to a mailslot on a specific remote computer.

\\computername\mailslot\[path]name

The following form allows a process to put a message into every mailslot in the specified domain that has the given name.

\\domainname\mailslot\[path]name

To put a message into every mailslot with a given name in the system's primary domain, a process uses the following form.

\\*\mailslot\[path]name


  55.1.2  Mailslots and Microsoft LAN Manager 2.x

Windows uses mailslots similar to those developed for Microsoft LAN Manager version 2.0. An application that uses LAN Manager 2.x mailslots can interact easily with mailslots created by Windows. There are significant differences, however, between Windows-based mailslots and LAN Manager mailslots:

•	Windows-based mailslots all have the same class — there are no "first class" and "second class" mailslots.

•	All Windows-based mailslot messages have equal priority and are always appended to the mailslot buffer. When a Windows-based mailslot message is written to a mailslot on a computer that requires message priority, the system sets the priority to the lowest value (0).

•	Write operations to Windows-based mailslots on local computers return an error value if an error occurs. Write operations to remote Windows-based mailslots do not return an error value when they fail. (Because there is no built-in limit to the size of the mailslot buffer failure is unlikely.)

•	Write operations to Windows-based mailslots fail immediately if the message cannot be appended to the mailslot buffer (if the buffer is too small, for example). Immediate failure makes write time-outs irrelevant; contrary to LAN Manager mailslots, there are no write time-outs for Windows-based mailslots.

•	A process that creates a Windows-based mailslot can specify that the mailslot handle be inherited by its child processes. (Mailslot handles in LAN Manager cannot be inherited.)

A process writes messages to a Windows-based mailslot by using standard file input and output functions. The following table shows LAN Manager mailslot functions and their corresponding Windows functions.

LAN Manager functions	Windows functions
DosDeleteMailslot	CloseHandle
DosMailslotInfo	GetMailslotInfo
DosMakeMailslot	CreateMailslot
DosReadMailslot	ReadFile
DosWriteMailslot	WriteFile


  55.1.3  Server and Client Functions

Clients and servers when working with mailslots should use only the functions discussed in this section. Other Windows functions should not be used, even if they accept file handles or filenames as arguments.


  55.1.3.1  Server Functions

Mailslot servers have exclusive use of three functions, as shown in the following table.

Function	Description
CreateMailslot	Creates a mailslot and returns a mailslot handle.
GetMailslotInfo	Retrieves the maximum message size, the mailslot size, the size of the next message in the mailslot, the number of messages in the mailslot, and the amount of time a read operation can wait for a message.
SetMailslotInfo	Changes the read time-out for a mailslot.
The following functions are also used by mailslot servers.

Function	Description
DuplicateHandle	Duplicates the mailslot handle.
ReadFile	Retrieves messages from a mailslot.
GetFileTime	Retrieves the date and time a mailslot was created.
SetFileTime	Sets the date and time a mailslot was created.


  55.1.3.2  Client Functions

A client process uses the following functions when interacting with a mailslot.

Function	Description
CloseHandle	Closes a mailslot handle for a client process.
CreateFile	Creates a mailslot handle for a client process.
DuplicateHandle	Duplicates a mailslot handle.
WriteFile	Writes data to a mailslot.


  55.2  Using Mailslots

This section explains how to perform the following tasks:

•	Create a mailslot.

•	Write to a mailslot.

•	Read messages from a mailslot.


  55.2.1  Creating a Mailslot

Mailslots in Windows are supported by three specialized functions: CreateMailslot, GetMailslotInfo, and SetMailslotInfo. These functions are used by the mailslot server.

The following code sample uses the CreateMailslot function to retrieve the handle of a mailslot named sample_mailslot.

BOOL FAR PASCAL Makeslot(HWND hwnd, HDC hdc)

{

    LPSTR lpszSlotName = "\\\\.\\mailslot\\sample_mailslot";

    /* The mailslot handle "hSlot1" is declared globally. */

    hSlot1 = CreateMailslot(lpszSlotName,

        0,                         /* no maximum message size         */

        MAILSLOT_WAIT_FOREVER,     /* no time-out for read operations */

        (LPSECURITY_ATTRIBUTES) NULL); /* no security attributes      */

    if (hSlot1 == INVALID_HANDLE_VALUE) {

        ErrorHandler(hwnd, "CreateMailslot"); /* local error handler */

        return FALSE;

    }

    TextOut(hdc, 10, 10, "CreateMailslot successful.", 26);

    return TRUE;

}

To create a mailslot inherited by child processes, an application should change the SECURITY_ATTRIBUTES structure passed as the last parameter of CreateMailslot. To do this, the application sets the bInheritHandle member of this structure to TRUE (the default setting is FALSE).


  55.2.2  Writing to a Mailslot

Writing to a mailslot is similar to writing to a standard disk file. The following code uses the CreateFile, WriteFile, and CloseHandle functions to put a short message in a mailslot. The message is broadcast to every computer in the primary domain of the system.

LPSTR lpszMessage = "Message for sample_mailslot in primary domain.";

BOOL fResult;

HANDLE hFile;

DWORD cbWritten;

hFile = CreateFile("\\\\*\\mailslot\\sample_mailslot",

    GENERIC_WRITE,

    FILE_SHARE_READ, /* required to write to a mailslot */

    (LPSECURITY_ATTRIBUTES) NULL,

    OPEN_EXISTING,

    FILE_ATTRIBUTE_NORMAL,

    (HANDLE) NULL);

if (hFile == INVALID_HANDLE_VALUE) {

    ErrorHandler(hwnd, "Primary domain"); /* local error handler */

    return FALSE;

}

fResult = WriteFile(hFile,

    lpszMessage,

    (DWORD) lstrlen(lpszMessage) + 1, /* include terminating null

                                         character */

    &cbWritten,

    (LPOVERLAPPED) NULL);

if (!fResult) {

    ErrorHandler(hwnd, "WriteFile");

    return FALSE;

}

TextOut(hdc, 10, 10, "WriteFile successful.", 21);

fResult = CloseHandle(hFile);

if (!fResult) {

    ErrorHandler(hwnd, "CloseHandle");

    return FALSE;

}

TextOut(hdc, 10, 30, "CloseHandle successful.", 23);

return TRUE;

Messages that are broadcast to a domain must be no more than 400 bytes in length. Messages that are not broadcast should be smaller than 64 kilobytes. The number of messages that can be sent to a mailslot is not limited.


  55.2.3  Reading from a Mailslot

The process that creates a mailslot can read messages from it by using the mailslot handle in a call to the ReadFile function. The code in the following example calls the GetMailslotInfo function to determine whether there are messages in the mailslot. If messages are waiting, each is displayed in a message box along with the number of messages remaining to be read.

BOOL FAR PASCAL Readslot(HWND hwnd, HDC hdc)

{

    DWORD cbMessage, cMessage, cbRead;

    BOOL fResult;

    LPSTR lpszBuffer;

    CHAR achID[80];

        DWORD cAllMessages;

    cbMessage = cMessage = cbRead = 0;

    /* Mailslot handle "hSlot1" is declared globally. */

    fResult = GetMailslotInfo(hSlot1, /* mailslot handle         */

        (LPDWORD) NULL,               /* no maximum message size */

        &cbMessage,                   /* size of next message    */

        &cMessage,                    /* number of messages      */

        (LPDWORD) NULL);              /* no read time-out        */

    if (!fResult) {

        ErrorHandler(hwnd, "GetMailslotInfo");

        return FALSE;

    }

    if (cbMessage == MAILSLOT_NO_MESSAGE) {

        TextOut(hdc, 10, 10, "No waiting messages.", 20);

        return TRUE;

    }

    cAllMessages = cMessage;

    while (cMessage != 0) {              /* retrieves each message  */

        /* Create a message-number string. */

        wsprintf((LPSTR) achID,

            "\nMessage #%d of %d\n", cAllMessages - cMessage + 1,

            cAllMessages);

        /* Allocate memory for the message. */

        lpszBuffer = (LPSTR) GlobalAlloc(GPTR,

            lstrlen((LPSTR) achID) + cbMessage);

        lpszBuffer[0] = '\0';

        fResult = ReadFile(hSlot1,

            lpszBuffer,

            cbMessage,

            &cbRead,

            (LPOVERLAPPED) NULL);

        if (!fResult) {

            ErrorHandler(hwnd, "ReadFile");

            GlobalFree((HGLOBAL) lpszBuffer);

            return FALSE;

        }

        /* Concatenate the message and the message-number string. */

        lstrcat(lpszBuffer, (LPSTR) achID);

        /* Display the message. */

        MessageBox(hwnd,

            lpszBuffer,

            "Contents of Mailslot",

            MB_OK);

        GlobalFree((HGLOBAL) lpszBuffer);

        fResult = GetMailslotInfo(hSlot1, /* mailslot handle         */

            (LPDWORD) NULL,               /* no maximum message size */

            &cbMessage,                   /* size of next message    */

            &cMessage,                    /* number of messages      */

            (LPDWORD) NULL);              /* no read time-out        */

        if (!fResult) {

            ErrorHandler(hwnd, "GetMailslotInfo");

            return FALSE;

        }

    }

    return TRUE;

}

A mailslot exists until the CloseHandle function is called for all open server handles or until all server processes that own a mailslot handle exit. In both cases, any unread messages are deleted from the mailslot, all client handles to the mailslot are closed, and the mailslot itself is deleted from memory.


  55.3  Functions

The following functions can be used with mailslots.

CreateMailslot
GetMailslotInfo
SetMailslotInfo


Networks
  Chapter 56    Networks

56.1  About Networks

An application written for Microsoft Windows NT can use the network functions in the Microsoft Win32 application programming interface (API) to implement networking capabilities without making allowances for a particular network provider or physical network implementation. In other words, these functions are network-independent. Applications can use these functions to add and cancel network connections and to retrieve information about the current configuration of the network. In addition, the Win32 API implements a version of the IBM NetBIOS network interface for applications that require it.

In addition to using the network functions, processes can also use the Win32 API implementations of mailslots and named pipes to communicate with one another. For more information about these subjects, see Chapter 55, »Mailslots« and Chapter 54, »Pipes«.

»This figure« shows the structure of a typical network:

In the preceding figure, the hierarchy for Microsoft Advanced Server resources is given in detail as Network provider #1. Network resources from other providers have different hierarchical systems. An application does not need information about the hierarchy before it begins to work with a network. It can proceed from the network root (that is, the topmost container resource) and retrieve information about the network resources as the information is required.

Network resources that contain other resources are called containers. Container resources are in boxes in the preceding figure. Resources that do not contain other resources are objects. Sharepoint #1 and Sharepoint #2 in the figure are objects.

A sharepoint is an object that is accessible across the network, such as a printer or a shared directory.


  56.1.1  Network-Independent Functions

Windows version 3.1 included the following network-independent network functions:

WNetAddConnection
WNetCancelConnection
WNetGetConnection

The Win32 API supports these functions and adds the following new network and network-enumeration functions:

WNetAddConnection2	WNetEnumResource
WNetCancelConnection2	WNetGetLastError
WNetCloseEnum	WNetGetUser
WNetConnectionDialog	WNetOpenEnum
WNetDisconnectDialog
Many of these functions use a NETRESOURCE structure, which is also new for the Win32 API. WNetAddConnection and WNetCancelConnection are supported for compatibility with earlier versions of Windows. However, new applications typically use WNetAddConnection2 and WNetCancelConnection2 instead.

An application can use the network functions to browse, add, or cancel network connections anywhere in the hierarchy. By starting at the network root, the resources from all network providers can be enumerated.

A persistent connection is a network connection that Windows automatically restores when the user logs on. With the WNetAddConnection2 and WNetCancelConnection2 functions, an application can control whether a network connection is persistent from one session to the next.


  56.1.2  The Netbios Function

The Netbios function is provided primarily for applications that were written for the IBM NetBIOS system and need to be ported to Windows. Applications not requiring compatibility with IBM NetBIOS can usually use other interfaces, such as mailslots and named pipes, to accomplish tasks similar to those supported by Netbios.

The Netbios function in the Win32 API takes one parameter: a pointer to a network-control block (NCB) structure. This structure contains information about the network environment and a pointer to a buffer that is used for messages or for further data about the network.


  56.1.2.1  Windows NetBios Enhancements

The Win32 implementation of the Netbios function includes the following enhancements that are not part of the IBM NetBIOS 3.0 specification:

•	POST routines can be called from the C programming language by means of the ncb_post member of the NCB structure.

•	Each asynchronous network-control block can supply an event (in the ncb_event member of the NCB structure) set to the signalled state when the NCB completes.

•	An application can enumerate all available LAN adapters by using the NCBENUM command in the ncb_command member of the NCB structure.


  56.1.2.2  Differences Between Windows and IBM NetBIOS

In addition to the enhancements listed in the preceding section, the following differences exist between the Win32 implementation of the Netbios function and the IBM NetBIOS 3.0 specification:

•	The system does not monitor the number of outstanding NCB commands specified when the NCBRESET command is issued. The memory quota limits for Windows NT are used to limit the total resources an application can use.

•	Asynchronous commands on invalid sessions are rejected when they are submitted.

•	The numbers of the network names (the ncb_num member of the NCB structure) are assigned on a per-process basis.

•	Requests for the status of the local adapter retrieve only the names that were added by the process making the request.

•	The value 1 for the ncb_lana_num member of the NCB structure is not exclusive when the NCBRESET command is issued. All MS-DOS and 16-bit Windows-based applications also share access to name number 1.


56.2  Using Networks_network
  56.2  Using Networks

The Windows network functions enable your application to query and control network connections directly or to give direct control of the network connections to the user. To use these functions, you must link to the multiple-provider router library (MPR.LIB). This section discusses how to use the network functions in your application.


  56.2.1  Using the Connections Dialog Box

The WNetConnectionDialog function creates a dialog box that allows the user to browse and connect to network resources.

Conversely, the WNetDisconnectDialog function creates a dialog box that allows the user to disconnect from network resources.

The following example shows how to use the WNetConnectionDialog function to create a dialog box that displays disk resources:

DWORD dwResult;

dwResult = WNetConnectionDialog(hwnd,

    RESOURCETYPE_DISK);

if(dwResult != NO_ERROR) {

    /*

     * An application-defined error handler is demonstrated in the

     * section titled "Retrieving Network Errors" later in

     * this chapter.

     */

    NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetConnectionDialog");

    return FALSE;

}


  56.2.2  Enumerating Network Resources

To enumerate a network container resource, your application should pass the address of a NETRESOURCE structure to the WNetOpenEnum function. WNetOpenEnum creates a handle to the resource described by the NETRESOURCE structure. The application then passes this handle to the WNetEnumResource function, which returns information about the resource in the form of an array of NETRESOURCE structures. When the handle is no longer needed, close it by calling the WNetCloseEnum function.

Your application can continue enumerating any container resource described in the array of NETRESOURCE structures retrieved by WNetEnumResource. If the dwUsage member of the NETRESOURCE structure is RESOURCEUSAGE_CONTAINER, the application can pass the address of that structure to WNetOpenEnum to open the container and continue the enumeration. If dwUsage is RESOURCEUSAGE_CONNECTABLE, the application can pass the structure's address to the WNetAddConnection2 function.

The following example illustrates an application-defined function (EnumerateFunc) that enumerates all the resources on a network. When calling this function, specify NULL for the pointer to the NETRESOURCE structure; when WNetOpenEnum receives the NULL pointer, it retrieves a handle to the root of the network. Whenever a NETRESOURCE structure retrieved by WNetEnumResource is RESOURCEUSAGE_CONTAINER, the EnumerateFunc function calls itself and uses a pointer to that structure in the call to WNetOpenEnum.

BOOL FAR PASCAL EnumerateFunc(hwnd, hdc, lpnr)

HWND hwnd;

HDC hdc;

LPNETRESOURCE lpnr;

{

    DWORD dwResult, dwResultEnum;

    HANDLE hEnum;

    DWORD cbBuffer = 16384; /* 16K is reasonable size for Windows NT  */

    DWORD cEntries = 0xFFFFFFFF; /* enumerate all possible entries    */

    LPNETRESOURCE lpnrLocal;     /* pointer to enumerated structures  */

    DWORD i;

    dwResult = WNetOpenEnum(RESOURCE_GLOBALNET,

        RESOURCETYPE_ANY,

        0,                 /* enumerate all resources                 */

        lpnr,              /* NULL first time this function is called */

        &hEnum);           /* handle to resource                      */

    if (dwResult != NO_ERROR) {

        /*

         * An application-defined error handler is demonstrated in the

         * section titled "Retrieving Network Errors."

         */

        NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum");

        return FALSE;

    }

    do {

        /* Allocate memory for NETRESOURCE structures. */

        lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);

        dwResultEnum = WNetEnumResource(hEnum, /* resource handle     */

            &cEntries,               /* defined locally as 0xFFFFFFFF */

            lpnrLocal,               /* LPNETRESOURCE                 */

            &cbBuffer);              /* buffer size                   */

        if (dwResultEnum == NO_ERROR) {

            for(i = 0; i < cEntries; i++) {

                /*

                 * The following is an application-defined function for

                 * displaying contents of NETRESOURCE structures.

                 */

                DisplayStruct(hdc, &lpnrLocal[i]);

                /*

                 * If this NETRESOURCE is a container, call the function

                 * recursively.

                 */

                if(RESOURCEUSAGE_CONTAINER ==

                       (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER))

                    if(!EnumerateFunc(hwnd, hdc, &lpnrLocal[i]))

                       TextOut(hdc, 10, 10,

                            "EnumerateFunc returned FALSE.", 29);

            }

      }

      else if (dwResultEnum != ERROR_NO_MORE_ITEMS) {

         NetErrorHandler(hwnd, dwResultEnum, (LPSTR)"WNetEnumResource");

         break;

      }

   }

   while(dwResultEnum != ERROR_NO_MORE_ITEMS);

   GlobalFree((HGLOBAL) lpnrLocal);

   dwResult = WNetCloseEnum(hEnum);

   if(dwResult != NO_ERROR) {

       NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum");

       return FALSE;

   }

   return TRUE;

}


  56.2.3  Adding a Network Connection

To make a connection to a network resource described by a NETRESOURCE structure, an application can call the WNetAddConnection2 function, as shown in the following example.

DWORD dwResult;

NETRESOURCE nr;

dwResult = WNetAddConnection2(&nr, /* NETRESOURCE from enumeration */

    (LPSTR) NULL,             /* no password                       */

    (LPSTR) NULL,             /* logged-in user                    */

    CONNECT_UPDATE_PROFILE);  /* update profile with connect info  */

if (dwResult == ERROR_ALREADY_ASSIGNED) {

    TextOut(hdc, 10, 10, "Already connected to specified resource.", 40);

    return FALSE;

}

else if (dwResult == ERROR_DEVICE_ALREADY_REMEMBERED) {

    TextOut(hdc, 10, 10,

        "Attempted reassignment of remembered device.", 44);

    return FALSE;

}

else if(dwResult != NO_ERROR) {

    /*

     * An application-defined error handler is demonstrated in the

     * section titled "Retrieving Network Errors."

     */

    NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetAddConnection2");

    return FALSE;

}

TextOut(hdc, 10, 10, "Connected to specified resource.", 32);

return TRUE;

The WNetAddConnection function is supported for compatibility with earlier versions of Windows. For new applications, use WNetAddConnection2.


  56.2.4  Retrieving the Connection Name

To retrieve the name of the network resource associated with a local device, an application can use the WNetGetConnection function, as shown in the following example.

CHAR szDeviceName[80];

DWORD dwResult, cchBuff = sizeof(szDeviceName);

dwResult = WNetGetConnection("z:",

    (LPSTR) szDeviceName,

    &cchBuff);

switch (dwResult) {

    case NO_ERROR:

        TextOut(hdc, 10, 10, (LPSTR) szDeviceName,

            lstrlen((LPSTR) szDeviceName));

        break;

    case ERROR_NOT_CONNECTED:

        TextOut(hdc, 10, 10, "Device z: not connected.", 24);

    case ERROR_CONNECTION_UNAVAIL:

        /* A connection is remembered but not connected. */

        TextOut(hdc, 10, 10, "Connection unavailable.", 23);

    default:

        /*

         * An application-defined error handler is demonstrated in the

         * section titled "Retrieving Network Errors."

         */

        NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetGetConnection");

        return FALSE;

}


  56.2.5  Retrieving the User Name

To retrieve the name of the user associated with either a local device connected to a network resource or with the name of a network, an application can call the WNetGetUser function. The following example uses the device name to retrieve the name of the user.

CHAR szUserName[80];

DWORD dwResult, cchBuff = 80;

dwResult = WNetGetUser("z:",

    (LPSTR) szUserName,

    &cchBuff);

if(dwResult == NO_ERROR)

    TextOut(hdc, 10, 10,

        (LPSTR) szUserName,

        lstrlen((LPSTR) szUserName));

else {

    /*

     * An application-defined error handler is demonstrated in the

     * section titled "Retrieving Network Errors."

     */

    NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetGetUser");

    return FALSE;

}


  56.2.6  Canceling a Network Connection

To cancel a connection to a network resource, an application can call the WNetCancelConnection2 function, as shown in the following example.

DWORD dwResult;

dwResult = WNetCancelConnection2("z:",

    CONNECT_UPDATE_PROFILE, /* remove connection from profile */

    FALSE);               /* fail if open files or jobs       */

if (dwResult == ERROR_NOT_CONNECTED) {

    TextOut(hdc, 10, 10, "Drive z: not connected.", 23);

    return FALSE;

}

else if(dwResult != NO_ERROR) {

    /*

     * An application-defined error handler is demonstrated in the

     * section titled "Retrieving Network Errors."

     */

    NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCancelConnection2");

    return FALSE;

}

TextOut(hdc, 10, 10, "Connection closed for z:.", 25);

The WNetCancelConnection function is supported for compatibility with earlier versions of Windows. For new applications, use WNetCancelConnection2.


  56.2.7  Retrieving Network Errors

When one of the Windows network functions returns WN_EXTENDED_ERROR, an application can call the WNetGetLastError function to retrieve more information about the error that occurred. Usually, this information is specific to the network provider.

The following example illustrates an application-defined error-handling function (NetErrorHandler) that takes three arguments: a window handle, the error code returned by one of the Windows network functions, and the name of the function that produced the error. If the error code is WN_EXTENDED_ERROR, Net Error Handler calls WNetGetLastError to retrieve extended error information.

BOOL WINAPI NetErrorHandler(hwnd, dwErrorCode, lpszFunction)

HWND  hwnd;

DWORD dwErrorCode;

LPSTR lpszFunction;

{

    DWORD dwWNetResult, dwLastError;

    CHAR szError[256];

    CHAR szCaption[256];

    CHAR szDescription[256];

    CHAR szProvider[256];

    /* The following performs standard error-handling. */

    if (dwErrorCode != ERROR_EXTENDED_ERROR) {

        wsprintf((LPSTR) szError, "%s failed; \nResult is %ld",

            lpszFunction, dwErrorCode);

        wsprintf((LPSTR) szCaption, "%s error", lpszFunction);

        MessageBox(hwnd, (LPSTR) szError, (LPSTR) szCaption, MB_OK);

        return TRUE;

    }

    /*

     * The following performs error-handling when the

     * ERROR_EXTENDED_ERROR return value indicates that WNetGetLastError

     * can retrieve additional information.

     */

    else {

        dwWNetResult = WNetGetLastError(&dwLastError,

            (LPSTR) szDescription,  /* buffer for error description  */

            sizeof(szDescription),

            (LPSTR) szProvider,     /* buffer for provider name      */

            sizeof(szProvider));

        if(dwWNetResult != NO_ERROR) {

            wsprintf((LPSTR) szError,

                "WNetGetLastError failed; error %ld", dwWNetResult);

            MessageBox(hwnd, (LPSTR) szError,

                "WNetGetLastError", MB_OK);

            return FALSE;

        }

        wsprintf((LPSTR) szError,

            "%s failed with code %ld;\n%s",

            (LPSTR) szProvider, dwLastError, (LPSTR) szDescription);

        wsprintf((LPSTR) szCaption, "%s error", lpszFunction);

        MessageBox(hwnd, (LPSTR) szError, (LPSTR) szCaption, MB_OK);

        return TRUE;

    }

}


  56.3  Functions

Following are the functions used with networks:

NetBios
WNetAddConnection
WNetAddConnection2
WNetCancelConnection
WNetCancelConnection2
WNetCloseEnum
WNetConnectionDialog
WNetDisconnectDialog
WNetEnumResource
WNetGetConnection
WNetGetLastError
WNetGetUser
WNetOpenEnum


Consoles and Character-Mode Support
  Chapter 57    Consoles and Character-Mode Support

57.1  About Character-Mode Support

The Microsoft Win32 application programming interface (API) provides consoles that manage input and output (I/O) for character-mode applications (applications that do not provide their own graphical user interface). Consoles provide high-level support for simple character-mode applications that interact with the user by using functions that read from standard input and write to standard output or standard error. Consoles also provide sophisticated low-level support that gives direct access to a console's screen buffer and that enables applications to receive extended input information (such as mouse input).

This chapter describes Win32 support for character-mode applications.


  57.1.1  Consoles

A console is an interface that provides input and output (I/O) to character-mode applications. This processor-independent mechanism makes it easy to port existing character-mode applications or to create new character-mode tools and applications.

A console consists of an input buffer and one or more screen buffers. The input buffer contains a queue of input records, each of which contains information about an input event. The input queue always includes key-press and key-release events. It can also include mouse events (pointer movements and button presses and releases) and events in which user actions affect the size of the active screen buffer. A screen buffer is a two-dimensional array of character and color data for output in a console window.

The Win32 API functions enable different levels of access to a console. The high-level console I/O functions enable an application to read from standard input to retrieve keyboard input stored in a console's input buffer. The functions also enable an application to write to standard output or standard error to display text in the console's screen buffer. The high-level functions also support redirection of standard handles and control of console modes for different I/O functionality. The low-level console I/O functions enable applications to receive detailed input about keyboard and mouse events, as well as events involving user interactions with the console window. The low-level functions also enable greater control of output to the screen.


  57.1.1.1  Creation of a Console

Windows Program Manager creates a new console when it starts a console process, a character-mode process whose entry point is the main function. For example, Program Manager creates a new console when it starts the Microsoft Windows command processor (CMD.EXE). When the command processor starts a new console process, the user can specify whether the system creates a new console for the new process or whether it inherits the command processor's console. A process can create a console by using one of the following methods:

•	A graphical user interface (GUI) or console process that is not currently attached to a console can use the AllocConsole function to create a new console.

•	A GUI or console process can use the CreateProcess function to create a new console process and specify a flag to tell the system to create a new console.

Typically, a process uses AllocConsole to create a console when an error occurs requiring interaction with the user. For example, a GUI process can create a console when an error occurs that prevents it from using its normal graphical interface, or a console process that does not normally interact with the user can create a console when an error makes it necessary. The process that calls AllocConsole must not be attached to an existing console. GUI processes are not attached to any console when they are created. A console process is not attached to a console if the DETACHED_PROCESS flag was specified in a call to CreateProcess when the process was created. A process can use the FreeConsole function to detach itself from an inherited console or from a console created by AllocConsole.

A process can also create a console by specifying the CREATE_NEW_CONSOLE flag in a call to CreateProcess. This method creates a new console that is accessible to the child process but not to the parent process. Separate consoles enable both parent and child processes to interact with the user without conflict. If this flag is not specified when a console process is created, both processes are attached to the same console, and there is no guarantee that the correct process will receive the input intended for it. Applications can prevent confusion by creating child processes that do not inherit handles of the input buffer, or by enabling only one child process at a time to inherit an input buffer handle while preventing the parent process from reading console input until the child has finished.

Creating a new console results in a new console window, as well as separate I/O screen buffers. The process associated with the new console uses the GetStdHandle function to get the handles of the new console's input and screen buffers. These handles enable the process to access the console.

When a process uses CreateProcess, it can specify a STARTUPINFO structure, whose members control the characteristics of the first new console (if any) created for the child process. The STARTUPINFO structure specified in the call to CreateProcess affects a console created if the CREATE_NEW_CONSOLE flag is specified. It also affects a console created if the child process subsequently uses AllocConsole. The following console characteristics can be specified:

•	The size, in character cells, and the location, in screen pixel coordinates, of the new console window.

•	The size, in character cells, of the new console's screen buffer.

•	The text and background color attributes of the new console's screen buffer.

•	The name appearing in the title bar of the new console's window.

The system uses default values if the STARTUPINFO values are not specified. A child process can use the GetStartupInfo function to determine the values in its STARTUPINFO structure.

A process cannot change the location of its console window on the screen, but the following console functions are available to set or query the other properties specified in the STARTUPINFO structure.

Function	Description
GetConsoleScreenBufferInfo	Queries window size, screen buffer size, and color attributes
SetConsoleWindowInfo	Changes the size of the console window
SetConsoleScreenBufferSize	Changes the size of the screen buffer
SetConsoleTextAttribute	Sets the color attributes
SetConsoleTitle	Sets the console window title
GetConsoleTitle	Queries the console window title


  57.1.1.2  Closing a Console

A process can use FreeConsole to detach itself from its console. If other processes share the console, the console is not destroyed, but the process that called FreeConsole cannot reference it. After calling FreeConsole, the process can use AllocConsole to create a new console.

A console is closed when the last process attached to it terminates or calls FreeConsole.


  57.1.1.3  Console Handles

A console process uses handles to access the input and screen buffers of its console. A process can use the GetStdHandle, CreateFile, or CreateConsoleScreenBuffer function to open one of these handles.

The GetStdHandle function provides a mechanism for retrieving the standard input (STDIN), standard output (STDOUT), and standard error (STDERR) handles associated with a process. During console creation, the system creates these handles. Initially, STDIN is a handle of the console's input buffer; STDOUT and STDERR are handles of the console's active screen buffer. However, the SetStdHandle function can redirect the standard handles by changing the handle associated with STDIN, STDOUT, or STDERR. Subsequent calls to GetStdHandle return the redirected handle, and the parent's standard handles are inherited by any child processes. This means that a handle returned by GetStdHandle may refer to something other than console I/O. For example, before creating a child process, a parent process can use SetStdHandle to set a pipe handle to be the STDIN handle that is inherited by the child process. When the child process calls GetStdHandle, it gets the pipe handle. This means that the parent process can control the standard handles of the child process. The handles returned by GetStdHandle have GENERIC_READ | GENERIC_WRITE access unless SetStdHandle has been used to set the standard handle to have lesser access.

The value of the handles returned by GetStdHandle will not be 0, 1, and 2, so the standard predefined stream constants in the STDIO.H header file (STDIN, STDOUT, and STDERR) cannot be used in the functions that require a console handle.

The CreateFile function enables a process to get a handle of its console's input buffer and active screen buffer, even if STDIN and STDOUT have been redirected. To open a handle of a console's input buffer, specify "CONIN$" in a call to CreateFile. Specify "CONOUT$" in a call to CreateFile to open a handle of a console's active screen buffer. CreateFile enables you to specify the read-write access of the handle that it returns.

The CreateConsoleScreenBuffer function creates a new screen buffer and returns a handle, which can be used in any function that accepts a handle of console output. The new screen buffer is not active until its handle is specified in a call to the SetConsoleActiveScreenBuffer function. Note that changing the active screen buffer does not affect the handle returned by GetStdHandle. Similarly, using SetStdHandle to change the STDOUT handle does not affect the active screen buffer.

Console handles returned by CreateFile and CreateConsoleScreenBuffer can be used in any of the console functions that require a handle of a console's input buffer or of a console screen buffer. Handles returned by GetStdHandle can be used by the console functions if they have not been redirected to refer to something other than console I/O. If a standard handle has been redirected to refer to a file or a pipe, however, the handle can only be used by the ReadFile and WriteFile functions.

A process can use the DuplicateHandle function to create a duplicate console handle that has different access or inheritability from the original handle. Note, however, that a process can create a duplicate console handle only for its own use. This differs from other handle types (such as file, pipe, or mutex objects), for which DuplicateHandle can create a duplicate that is valid for a different process.

To close a console handle, a process can use the CloseHandle function.


  57.1.1.4  Console Input Buffer

Each console has an input buffer that contains a queue of input event records. When a console's window has the keyboard focus, a console formats each input event (such as a single keystroke, a movement of the mouse, or a mouse-button click) as an input record that it places in the console's input buffer.

Applications can access a console's input buffer indirectly by using the high-level console I/O functions, or directly by using the low-level console I/O functions. The high-level input functions filter and process the data in the input buffer, returning only a stream of input characters. The low-level input functions enable applications to read input records directly from a console's input buffer, or to place input records into the input buffer.

An input record is a structure containing information about the type of event that occurred (keyboard, mouse, window resizing, focus, or menu event) as well as specific details about the event. The EventType member in an INPUT_RECORD structure indicates which type of event is contained in the record.

Focus and menu events are placed in a console's input buffer for internal use by the system and should be ignored by applications.


  Keyboard Events

Keyboard events are generated when any key is pressed or released; this includes control keys. However, the ALT key has special meaning to Windows when pressed and released without being combined with another character, and it is not passed through to the application. Also, the CTRL+C key combination is not passed through if the input handle is in processed mode.

If the input event is a keystroke, the Event member in INPUT_RECORD is a KEY_EVENT_RECORD structure containing the following information:

•	A Boolean value indicating whether the key was pressed or released.

•	A repeat count that can be greater than one when a key is held down.

•	The virtual-key code, identifying the given key in a device-independent manner.

•	The virtual-scan code, indicating the device-dependent value generated by the keyboard hardware.

•	The translated Unicode or ANSI character.

•	A flag indicating the state of the control keys (the ALT, CTRL, SHIFT, NUM LOCK, SCROLL LOCK, and CAPS LOCK keys), and whether an enhanced key was pressed. Enhanced keys for the IBM 101-key and 102-key keyboards are the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad and the divide (/) and ENTER keys in the numeric keypad.


  Mouse Events

Mouse events are generated whenever the user moves the mouse or presses or releases one of the mouse buttons. Mouse events are placed in the input buffer only if the following conditions are met:

•	The console input mode is set to ENABLE_MOUSE_INPUT (the default).

•	The console window has the keyboard focus.

•	The mouse pointer is within the borders of the console's window.

If the input event is a mouse event, the Event member in INPUT_RECORD is a MOUSE_EVENT_RECORD structure containing the following information:

•	The coordinates of the mouse pointer in terms of the character cell row and column in the screen buffer's coordinate system.

•	A flag variable indicating the state of the mouse buttons.

•	A flag variable indicating the state of the control keys (ALT, CTRL, SHIFT, NUM LOCK, SCROLL LOCK, and CAPS LOCK), and whether an enhanced key was pressed. Enhanced keys for the IBM 101-key and 102-key keyboards are the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad and the divide (/) and ENTER keys in the numeric keypad.

•	A flag variable indicating whether the event was a normal button-press or button-release event, a mouse movement event, or the second click of a double-click event.

Note that the mouse position coordinates are in terms of the screen buffer, not the console window. The screen buffer may have been scrolled with respect to the window, so the upper left corner of the window is not necessarily the (0,0) coordinate of the screen buffer. To determine the coordinates of the mouse relative to the coordinate system of the window, subtract the window origin coordinates from the mouse position coordinates. Use the GetConsoleScreenBufferInfo function to determine the window origin coordinates.

The dwButtonState member of the MOUSE_EVENT_RECORD structure has a bit corresponding to each mouse button. The bit is 1 if the button is down and 0 if the button is up. A button-release event is detected by a 0 value for the dwEventFlags member of MOUSE_EVENT_RECORD and a change in a button's bit from 1 to 0. The GetNumberOfConsoleMouseButtons function retrieves the number of buttons on the mouse.


  Buffer-Resizing Events

A console window's menu enables the user to change the size of the active screen buffer; this change generates a buffer-resizing event. Buffer-resizing events are placed in the input buffer if the console's input mode is set to ENABLE_WINDOW_INPUT (that is, the default is disabled).

If the input event is a buffer-resizing event, the Event member in INPUT_RECORD is a WINDOW_BUFFER_SIZE_RECORD structure containing the new size of the screen buffer, expressed in character cell columns and rows.

If the user reduces the size of the screen buffer, any data in the discarded portion of the buffer is lost.

Changes to the screen buffer size as a result of application calls to the SetConsoleScreenBufferSize function do not generate as buffer-resizing events.


  57.1.1.5  Console Screen Buffers

A screen buffer is a two-dimensional array of character and color data for output in a console window. A console can have multiple screen buffers. The active screen buffer is the one that is displayed on the screen.

The system creates a screen buffer whenever it creates a new console. A process can use the CreateConsoleScreenBuffer function to create additional screen buffers for its console. A new screen buffer is not active until its handle is specified in a call to the SetConsoleActiveScreenBuffer function. However, screen buffers can be accessed for reading and writing whether they are active or inactive.

Each screen buffer has its own two-dimensional array of character information records. The data for each character is stored in a CHAR_INFO structure that specifies the Unicode or ANSI character and the foreground and background colors in which that character is displayed.

A number of properties associated with a screen buffer can be set independently for each screen buffer. This means that changing the active screen buffer can have a dramatic effect on the appearance of the console window. The properties associated with a screen buffer include:

•	Screen buffer size, in character rows and columns.

•	Text attributes (foreground and background colors for displaying text to be written by the WriteFile or WriteConsole function).

•	Window size and location (the rectangular region of the screen buffer that is displayed in the console window).

•	Cursor position, appearance, and visibility.

•	Output modes (ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT). For more information about console output modes, see Section 57.1.2.3, »High-Level Console Modes«.

When a screen buffer is created, it contains blanks. Its cursor is visible and positioned at the buffer's origin (0,0), and the window is positioned with its upper left corner at the buffer's origin. The size of the screen buffer, the window size, the text attributes, and the appearance of the cursor are determined by the user or by the system defaults. To determine the current values of the various properties associated with the screen buffer, use the GetConsoleScreenBufferInfo, GetConsoleCursorInfo, and GetConsoleMode functions.

Applications that change any of the screen buffer properties should either create their own screen buffer or save the state of the inherited screen buffer during startup and restore it at exit.


  57.1.1.6  Window and Screen Buffer Size

The size of a screen buffer is expressed in terms of a coordinate grid based on character cells. The width is the number of character cells in each row, and the height is the number of rows. Associated with each screen buffer is a window that determines the size and location of the rectangular portion of the screen buffer displayed in the console window. A screen buffer's window is defined by specifying the character cell coordinates of the upper left and lower right cells of the window's rectangle.

A screen buffer can be any size, limited only by available memory. The dimensions of a screen buffer's window cannot exceed the corresponding dimensions of either the screen buffer or the maximum window that can fit on the screen based on the current font size (controlled exclusively by the user).

The GetConsoleScreenBufferInfo function returns the following information about a screen buffer and its window:

•	The current size of the screen buffer

•	The current location of the window

•	The maximum size of the window given the current screen buffer size, the current font size, and the screen size

The GetLargestConsoleWindowSize function returns the maximum size of a console's window based on the current font and screen sizes. This size differs from the maximum window size returned by GetConsoleScreenBufferInfo in that the screen buffer size is ignored.

To change a screen buffer's size, use the SetConsoleScreenBufferSize function. This function fails if either dimension of the specified size is less than the corresponding dimension of the console's window.

To change the size or location of a screen buffer's window, use the SetConsoleWindowInfo function. This function fails if the specified window-corner coordinates exceed the limits of the screen buffer or the screen. Changing the window size of the active screen buffer changes the size of the console window displayed on the screen.

A process can change its console's input mode to enable window input so that the process is able to receive input when the user changes the screen buffer size. If an application does not enable window input, it must either use the inherited window and screen buffer sizes, or set them to the desired size during startup and restore the inherited sizes at exit. If an application enables window input, it can use GetConsoleScreenBufferInfo to query window and screen buffer size at startup. This information can then be used to determine the way data is displayed in the window. If the user changes the screen buffer size, the application can respond by changing the way data is displayed. For example, an application can adjust the way text wraps at the end of the line if the number of characters per row changes. For additional information about window input mode, see Section 57.1.2.6, »Low-Level Console Modes«.


  57.1.1.7  Scrolling the Screen Buffer

The console window displays a portion of the active screen buffer. Each screen buffer maintains its own current window rectangle that specifies the coordinates of the upper left and lower right character cells to be displayed in the console window. To determine the current window rectangle of a screen buffer, use GetConsoleScreenBufferInfo. When a screen buffer is created, the upper-left corner of its window is at the upper left corner of the screen buffer at (0,0).

The window rectangle can change to display different parts of the screen buffer. The window rectangle of a screen buffer can change in the following situations:

•	When SetConsoleWindowInfo is called to specify a new window rectangle, it scrolls the view of the screen buffers by changing the position of the window rectangle without changing the size of the window. For examples of scrolling the window's contents, see Section 57.2.5, »Scrolling a Screen Buffer's Window«. »This illustration« shows the scolling of the screen buffer.

•	When using the WriteFile function to write to a screen buffer with wrap at end-of-line (EOL) output mode enabled, the window rectangle shifts automatically, so the cursor is always displayed.

•	When the SetConsoleCursorPosition function specifies a new cursor position that is outside the boundaries of the current window rectangle, the window rectangle shifts automatically to display the cursor.

•	When the user changes the size of the console window or uses the window's scroll bars, the window rectangle of the active screen buffer can change. This change is not reported as a window resizing event in the input buffer.

In each of these situations, the window rectangle shifts to display a different part of the screen buffer, but the contents of the screen buffer remain in the same position. The following situations can cause the screen buffer's contents to shift:

•	When the ScrollConsoleScreenBuffer function is called, a rectangular block is copied from one part of a screen buffer to another.

•	When using WriteFile to write to a screen buffer with wrap at end-of-line (EOL) output mode enabled, the screen buffer's contents scroll automatically when the end of the screen buffer is encountered. This scrolling discards the top line of the screen buffer.

ScrollConsoleScreenBuffer specifies the screen buffer rectangle that is moved and the new upper left coordinates to which the rectangle is copied. This function can scroll a portion or the entire contents of the screen buffer. The effects of ScrollConsoleScreenBuffer can be limited by specifying an optional clipping rectangle so that the contents of the screen buffer outside the clipping rectangle are unchanged. The effect of clipping is to create a subwindow (the clipping rectangle) whose contents are scrolled without affecting the rest of the screen buffer. For an example that uses ScrollConsoleScreenBuffer, see Section 57.2.6, »Scrolling a Screen Buffer's Contents«.

»This illustration« shows a ScrollConsoleScreenBuffer operation that scrolls the entire contents of the screen buffer up by several rows. The contents of the top rows are discarded, and the bottom rows are filled with a specified character and color.

Cursor Appearance and Position

A screen buffer's cursor can be visible or hidden. When it is visible, its appearance can vary, ranging from from completely filling a character cell to appearing as a horizontal line at the bottom of the cell. To query the appearance and visibility of the cursor, use the GetConsoleCursorInfo function. This function reports whether the cursor is visible and describes the appearance of the cursor as the percentage of a character cell that it fills. To set the appearance and visibility of the cursor, use the SetConsoleCursorInfo function.

Characters written by the high-level console I/O functions are written at the current cursor location, advancing the cursor to the next location. To determine the current cursor position in the coordinate system of a screen buffer, use the GetConsoleScreenBufferInfo function. You can use SetConsoleCursorPosition to set the cursor position and thereby control the placement of text that is written or echoed by the high-level I/O functions. If you move the cursor, text at the new cursor location is overwritten.

The position, appearance, and visibility of the cursor are set independently for each screen buffer.


  Screen Buffer Color Attributes

Each screen buffer character cell stores the color attributes for the colors used in drawing the text and background of that cell. An application can set the color data for each character cell individually, storing the data in the Attributes member of the CHAR_INFO structure for each cell.

The current text attributes of each screen buffer determine the text (foreground) and background colors of characters subsequently written or echoed by the high-level functions. An application can use GetConsoleScreenBufferInfo to determine the current text attributes of a screen buffer and the SetConsoleTextAttribute function to set the text attributes. Changing a screen buffer's text attributes does not affect the display of characters previously written. These text attributes do not affect characters written by the low-level console I/O functions (such as the WriteConsoleOutput or WriteConsoleOutputCharacter function) which either explicitly specify the attributes for each cell that is written or leave the attributes unchanged at the written positions.

The following attribute constants are defined in the WINCON.H file:

•	FOREGROUND_BLUE

•	FOREGROUND_GREEN

•	FOREGROUND_RED

•	FOREGROUND_INTENSITY

•	BACKGROUND_BLUE

•	BACKGROUND_GREEN

•	BACKGROUND_RED

•	BACKGROUND_INTENSITY

The foreground attributes specify the text color, and the background attributes specify the color used to fill the cell's background. An application can combine the constants to achieve different colors. For example, the following combination results in bright cyan text on a blue background.

FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE

If no background constant is specified, the background is black, and if no foreground constant is specified, the text is black. For example, the following combination produces black text on a white background.

BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED


  57.1.2  Input and Output Methods

The Win32 API provides two very different approaches to console I/O, the choice of which depends on how much flexibility and control your application needs. The high-level approach enables simple character stream I/O, but it limits access to a console's input and screen buffers. The low-level approach requires that developers write more code and choose among a greater range of functions, but it also gives the application more flexibility.

An application can use the file I/O functions, ReadFile and WriteFile, and the console functions, ReadConsole and WriteConsole, for high-level I/O that provides indirect access to a console's input and screen buffers. The high-level input functions filter and process the data in a console's input buffer to return input as a stream of characters, discarding mouse and buffer-resizing input. Similarly, the high-level output functions write a stream of characters that are displayed at the current cursor location in a screen buffer. An application controls the way these functions work by setting a console's I/O modes.

The low-level I/O functions provide direct access to a console's input and screen buffers, enabling your application to access mouse and buffer-resizing input events and extended information for keyboard events. Low-level output functions enable an application to read from or write to consecutive character cells in a screen buffer, or to read or write rectangular blocks of character cells of a size and at a specified location. A console's input modes affect low-level input by enabling the application to determine whether mouse and buffer-resizing events are placed in the input buffer. A console's output modes have no effect on low-level output.

The high-level and low-level I/O methods are not mutually exclusive, and an application can use any combination of these functions. Typically, however, an application uses one approach or the other exclusively.

The sections that follow describe in detail the console modes and the high-level and low-level I/O functions.


  57.1.2.1  Console Modes

Associated with each console input buffer are a set of input modes that affects input operations. Similarly, each console screen buffer has a set of output modes that affects output operations. The input modes can be divided into two groups: those that affect the high-level input functions, and those that affect the low-level input functions. The output modes affect only applications that use the high-level output functions.

The GetConsoleMode function reports the current input mode of a console's input buffer or the current output mode of a screen buffer. The SetConsoleMode function sets the current mode of either a console input buffer or a screen buffer. If a console has multiple screen buffers, the output modes of each can be different. An application can change I/O modes at any time. For more information about the console modes that affect high-level and low-level I/O operations, see Section 57.1.2.3, »High-Level Console Modes«, and Section 57.1.2.6, »Low-Level Console Modes«.


  57.1.2.2  High-Level Console I/O

The high-level I/O functions provide a simple way to read a stream of characters from console input or to write a stream of characters to console output. A high-level read operation gets input characters from a console's input buffer and stores them in a specified buffer. A high-level write operation takes characters from a specified buffer and writes them to a screen buffer at the current cursor location, advancing the cursor as each character is written.

High-level I/O gives you a choice between the ReadFile and WriteFile functions and the ReadConsole and WriteConsole functions. They are identical, except for two important differences. The console functions support the use of either Unicode characters or the ANSI character set; the file I/O functions do not support Unicode. Also, the file I/O functions can be used to access files, pipes, and serial communications devices; the console functions can only be used with console handles. This distinction is important if an application relies on standard handles that may have been redirected.

When using either set of high-level functions, an application can control the text and background colors used to display characters subsequently written to a screen buffer. An application can also use the console modes that affect high-level console I/O to enable or disable the following properties:

•	Echoing keyboard input to the active screen buffer

•	Line input, in which a read operation does not return until the ENTER key is pressed

•	Automatic processing of keyboard input to handle carriage returns, CTRL+C, and other input details

•	Automatic processing of output to handle line wrapping, carriage returns, backspaces, and other output details


  57.1.2.3  High-Level Console Modes

The behavior of the high-level console functions is affected by the console input and output modes. All of the following console input modes are enabled for a console's input buffer when a console is created:

•	Line input mode

•	Processed input mode

•	Echo input mode

Both of the following console output modes are enabled for a console screen buffer when it is created:

•	Processed output mode

•	Wrapping at end-of-line (EOL) output mode

All three input modes, along with processed output mode, are designed to work together. It is best to either enable or disable all of these modes as a group. When all are enabled, the application is said to be in "cooked" mode, in which most of the processing is handled for the application. When all are disabled, the application is in "raw" mode, in which input is unfiltered and any processing is left to the application.

An application can use the GetConsoleMode function to determine the current mode of a console's input buffer or screen buffer. You can enable or disable any of these modes by using the following flags in the SetConsoleMode function. Note that setting the output mode of one screen buffer does not affect the output mode of other screen buffers.

Flag	Description
ENABLE_PROCESSED_INPUT
	Used with a console input handle to cause the system to process any system editing or control key input, rather than returning it as input in the read operation's buffer. If line input is also enabled, backspaces and carriage returns are handled correctly. A backspace causes the cursor to move back one space without affecting the character at the cursor position. A carriage return is converted to carriage return−linefeed character combination. If echo input mode is enabled and the output should reflect the system editing, processed output must be enabled for the active screen buffer. If processed input is enabled, the CTRL+C key combination is passed on to the appropriate handler regardless of whether line input is enabled. For more information about control handlers, see Section 57.1.4, »Console Control Handlers«.
ENABLE_LINE_INPUT
	Used with a console input handle to cause the ReadFile and ReadConsole functions to return when the ENTER key is pressed. If line input mode is disabled, the functions return when one or more characters are available in the input buffer.
ENABLE_ECHO_INPUT
	Used with a console input handle to cause keyboard input read by the ReadFile or ReadConsole function to be echoed to the active screen buffer. Characters are echoed only if the process that calls ReadFile or ReadConsole has an open handle of the active screen buffer. Echo mode cannot be enabled unless line input is also enabled. The output mode of the active screen buffer affects the way echoed input is displayed.
ENABLE_PROCESSED_OUTPUT
	Used with a console screen buffer handle to cause the system to perform the appropriate action for ANSI control characters that are written to a screen buffer. The BACKSPACE, TAB, bell, carriage return, and linefeed characters are processed. A TAB character moves the cursor to the next tab stop, which occurs every eight characters. A bell character sounds a short tone.
ENABLE_WRAP_AT_EOL_OUTPUT
	Used with a console screen buffer handle to cause the current output position (cursor position) to move to the first column in the next row when the end of the current row is reached. If the bottom of the window region is reached, the window origin is moved down one row. This movement has the effect of scrolling the contents of the window up one row. If the bottom of the screen buffer is reached, the contents of the screen buffer are scrolled up one row, and the top row of the screen buffer is discarded. If wrap at EOL output mode is disabled, the last character in the row is overwritten with any subsequent characters.


  57.1.2.4  High-Level Console Input and Output Functions

The ReadFile and WriteFile functions, or the ReadConsole and WriteConsole functions, enable an application to read console input and write console output as a stream of characters. ReadConsole and WriteConsole behave exactly like ReadFile and WriteFile except that they can be used either as wide-character functions (in which text arguments must use Unicode) or as ANSI functions (in which text arguments must use characters from the Windows 3.x character set). Applications that need to maintain a single set of sources to support either Unicode or the ANSI character set should use ReadConsole and WriteConsole.

ReadConsole and WriteConsole can only be used with console handles; ReadFile and WriteFile can be used with other handles (such as files or pipes). This means that ReadConsole and WriteConsole fail if used with a standard handle that has been redirected and is no longer a console handle.

To get keyboard input, a process can use ReadFile or ReadConsole with a handle of the console's input buffer, or it can use ReadFile to read input from a file or a pipe if STDIN has been redirected. These functions only return keyboard events that can be translated into ANSI characters (or Unicode characters, in the case of ReadConsole). The input that can be returned includes control key combinations. The functions do not return keyboard events involving the function keys or arrow keys. Input events generated by mouse, window, focus, or menu input are discarded.

If line input mode is enabled (the default), ReadFile and ReadConsole do not return to the calling application until the ENTER key is pressed. If line input mode is disabled, the functions do not return until at least one character is available. In either mode, all available characters are read until either no more keys are available or the specified number of characters has been read. Unread characters are buffered until the next read operation. The functions report the total number of characters actually read. If echo input mode is enabled, characters read by these functions are written to the active screen buffer at the current cursor position.

A process can use WriteFile or WriteConsole to write to either an active or inactive screen buffer, or it can use WriteFile to write to a file or a pipe if STDOUT has been redirected. Processed output mode and wrap at EOL output mode control the way characters are written or echoed to a screen buffer.

Characters written by WriteFile or WriteConsole, or echoed by ReadFile or ReadConsole, are inserted in a screen buffer at the current cursor position. As each character is written, the cursor position advances to the next character cell, except that the behavior at the end of a line depends on the screen buffer's wrap at EOL output mode. An application can use the GetConsoleScreenBufferInfo function to determine the current cursor position and the SetConsoleCursorPosition function to set the cursor position.

For an example that uses the high-level console I/O functions, see Section 57.2.1, »Using the High-Level Input and Output Functions«.


  57.1.2.5  Low-Level Console I/O

The low-level console I/O functions expand an application's control over console I/O by enabling direct access to a console's input and screen buffers. These functions enable an application to peform the following tasks:

•	Receive input about mouse and buffer-resizing events

•	Receive extended information about keyboard input events

•	Write input records to the input buffer

•	Read input records without removing them from the input buffer

•	Determine the number of pending events in the input buffer

•	Flush the input buffer

•	Read and write strings of Unicode or ANSI characters at a specified location in a screen buffer

•	Read and write strings of text and background color attributes at a specified screen buffer location

•	Read and write rectangular blocks of character and color data at a specified screen buffer location

•	Write a single Unicode or ANSI character, or a text and background color attribute combination, to a specified number of consecutive cells beginning at a specified screen buffer location


  57.1.2.6  Low-Level Console Modes

The types of input events reported in a console's input buffer depend on the console's mouse and window input modes. The console's processed input mode determines how the system handles the CTRL+C key combination. To set or query the state of a console's input modes, an apllication can specify a console input buffer handle in a call to the SetConsoleMode or GetConsoleMode function.

Following are the flags used with console input handles:

Flag	Description
ENABLE_MOUSE_INPUT
	Controls whether mouse events are reported in the input buffer. By default, mouse input is enabled and window input is disabled. Changing either of these modes affects only input that occurs after the mode is set; pending mouse or window events in the input buffer are not flushed. The mouse pointer is displayed regardless of the mouse mode.
ENABLE_WINDOW_INPUT
	Controls whether buffer-resizing events are reported in the input buffer. By default, mouse input is enabled and window input is disabled. Changing either of these modes affects only input that occurs after the mode is set; pending mouse or window events in the input buffer are not flushed. The mouse pointer is displayed regardless of the mouse mode.
ENABLE_PROCESSED_INPUT
	Controls the processing of input for applications using the high-level console I/O functions. However, if processed input mode is enabled, the CTRL+C key combination is not reported in the console's input buffer. Instead, it is passed on to the appropriate control handler function. For more information about control handlers, see Section 57.1.4, »Console Control Handlers«.
The output modes of a screen buffer do not affect the behavior of the low-level output functions.


  57.1.2.7  Low-Level Console Input Functions

A console's input buffer contains input records that can include information about keyboard, mouse, buffer-resizing, focus, and menu events. The low-level functions provide direct access to the input buffer, unlike the high-level functions that filter and process the input buffer's data, discarding all but keyboard input.

The Win32 API provides five low-level functions for accessing a console's input buffer:

•	ReadConsoleInput

•	PeekConsoleInput

•	GetNumberOfConsoleInputEvents

•	WriteConsoleInput

•	FlushConsoleInputBuffer

The ReadConsoleInput, PeekConsoleInput, and WriteConsoleInput functions use the INPUT_RECORD structure to read from or write to an input buffer.

Following are descriptions of the low-level console input functions.

Function	Description
ReadConsoleInput	Reads and removes input records from an input buffer. The function does not return until at least one record is available to be read. Then all available records are transferred to the buffer of the calling process until either no more records are available or the specified number of records has been read. Unread records remain in the input buffer for the next read operation. The total number of records read is indicated. For an example that uses ReadConsoleInput, see Section 57.2.4, »Reading Input Buffer Events«.
PeekConsoleInput	Reads without removing the pending input records in an input buffer. All available records up to the specified number are copied into the buffer of the calling process. If no records are available, the function returns immediately. The total number of records read is indicated.
GetNumberOfConsoleInputEvents	Determines the number of unread input records in an input buffer.
WriteConsoleInput	Places input records into the input buffer behind any pending records in the buffer. The input buffer grows dynamically, if necessary, to hold as many records as are written. To use this function, the specified input buffer handle must have GENERIC_WRITE access.
FlushConsoleInputBuffer	Discards all unread events in the input buffer. To use this function, the specified input buffer handle must have GENERIC_WRITE access.
A thread of an application's process can perform a wait operation to wait for input to be available in an input buffer. To initiate a wait operation, specify a handle of the input buffer in a call to any of the wait functions (WaitForSingleObject, WaitForMultipleObjects, MsgWaitForMultipleObjects, WaitForSingleObjectEx, or WaitForMultipleObjectsEx). These functions can return when the state of one or more objects is signaled. The state of a console input handle becomes signaled when there are unread records in its input buffer. The state is reset to nonsignaled when the input buffer becomes empty. If there is no input available, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the conditions of the wait operation to be satisfied.


  57.1.2.8  Low-Level Console Output Functions

The low-level console output functions provide direct access to the character cells of a screen buffer. One set of functions reads from or writes to consecutive cells beginning at any location in the screen buffer. Another set of functions reads from or writes to rectangular blocks of cells.

The following functions read from or write to a specified number of consecutive character cells in a screen buffer, beginning with a specified cell:

Function	Description
ReadConsoleOutputCharacter
	Copies a string of Unicode or ANSI characters from a screen buffer.
WriteConsoleOutputCharacter
	Writes a string of Unicode or ANSI characters to a screen buffer.
ReadConsoleOutputAttribute
	Copies a string of text and background color attributes from a screen buffer.
WriteConsoleOutputAttribute
	Writes a string of text and background color attributes to a screen buffer.
FillConsoleOutputCharacter
	Writes a single Unicode or ANSI character to a specified number of consecutive cells in a screen buffer.
FillConsoleOutputAttribute
	Writes a text and background color attribute combination to a specified number of consecutive cells in a screen buffer.
For all of these functions, when the last cell of a row is encountered, reading or writing wraps around to the first cell of the next row. When the end of the last row of the screen buffer is encountered, the write functions discard all unwritten characters or attributes, and the read functions return with the number of characters or attributes actually written. For examples that illustrate the use of these functions, see Section 57.2.2, »Writing Characters or Colors to Consecutive Cells«.

The following functions read from or write to rectangular blocks of character cells at a specified location in a screen buffer:

Function	Description
ReadConsoleOutput
	Copies character and color data from a specified block of screen buffer cells into a given block in a destination buffer.
WriteConsoleOutput
	Writes character and color data to a specified block of screen buffer cells from a given block in a source buffer.
These functions treat screen buffers and source or destination buffers as two-dimensional arrays of CHAR_INFO structures (containing character and color attribute data for each cell). The functions specify the width and height, in character cells, of the source or destination buffer, and the pointer to the buffer is treated as a pointer to the origin cell (0,0) of the two-dimensional array. The functions use a SMALL_RECT structure to specify which rectangle to access in the screen buffer, and the coordinates of the upper left cell in the source or destination buffer determine the location of the corresponding rectangle in that buffer.

The functions automatically clip the specified screen buffer rectangle to fit within the boundaries of the screen buffer. For example, if the rectangle specifies lower right coordinates that are (column 100, row 50) and the screen buffer is only 80 columns wide, the coordinates are clipped so that they are (column 79, row 50). Similarly, this adjusted rectangle is again clipped to fit within the boundaries of the source or destination buffer. The screen buffer coordinates of the actual rectangle that was read from or written to are specified. For an example that uses these functions, see Section 57.2.3, »Reading and Writing Blocks of Characters and Attributes«.

»This illustration« shows a ReadConsoleOutput operation where clipping occurs when the block is read from the screen buffer, and again when the block is copied into the destination buffer. The function reports the actual screen buffer rectangle that was copied from.


  57.1.3  Console Code Pages

A code page is a mapping of 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

Associated with each console are two code pages: one for input and one for output. A console uses its input code page to translate keyboard input into the corresponding character value. It uses its output code page to translate the character values written by the various output functions into the images displayed in the console window. An application can use the SetConsoleCP and GetConsoleCP functions to set and query a console's input code pages and the SetConsoleOutputCP and GetConsoleOutputCP functions to set and query its output code pages.

The identifiers of the code pages available on the local computer are stored in the registry under the following key.

%HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage%

For information about using the registry functions to determine the available code pages, see Chapter 52, »Registry and Initialization Files«.

For more information about code pages, see Chapter 53, »String Manipulation and Unicode«.


  57.1.4  Console Control Handlers

Each console process has its own list of control handler functions that are called by the system when the process receives a CTRL+C, CTRL+BREAK, or CTRL+CLOSE signal. Initially, the list of control handlers for each process contains only a default handler function that calls the ExitProcess function. A console process can add or remove additional handler functions by calling the SetConsoleCtrlHandler function. This function does not affect the lists of control handlers for other processes. When a console process receives any of the control signals, it calls the handler functions on a last-registered, first-called basis until one of the handlers returns TRUE. If none of the handlers returns TRUE, the default handler is called.

The following typedef declaration illustrates the format of a control handler function.

typedef BOOL (*PHANDLER_ROUTINE)(DWORD dwCtrlType);

The function's argument identifies which control signal was received, and the return value indicates whether the signal was handled.

For an example of a control handler function, see Section 57.2.7, »Registering a Control Handler Function«.


  57.1.4.1  CTRL+C and CTRL+BREAK Signals

The CTRL+C and CTRL+BREAK key combinations receive special handling by console processes. By default, when a console window has the keyboard focus, CTRL+C or CTRL+BREAK is treated as a signal (SIGINT or SIGBREAK) and not as keyboard input. By default, these signals are passed to all console processes that are attached to the console. This causes the system to call the control handler function or functions associated with these processes. Detached processes (GUI processes or console processes started with the DETACHED_PROCESS or CREATE_NEW_CONSOLE flags set) are not affected.

CTRL+BREAK is always treated as a signal, but an application can change the default CTRL+C behavior in two ways that prevent the handler functions from being called.

•	The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT input mode for a console's input buffer, so CTRL+C is reported as keyboard input rather than as a signal.

•	When SetConsoleCtrlHandler is called with the NULL and TRUE arguments, the calling process ignores CTRL+C signals. Normal CTRL+C processing is restored by calling SetConsoleCtrlHandler with the NULL and FALSE arguments. This attribute of ignoring or not ignoring CTRL+C signals is inherited by child processes, but it can be enabled or disabled by any process without affecting existing processes.


  57.1.4.2  CTRL+CLOSE Signal

The system generates a CTRL+CLOSE signal when the user closes a console. All processes attached to the console receive the signal, giving each process an opportunity to clean up before termination. When a process receives this signal, the handler function can take one of the following actions after performing any cleanup operations:

•	Call ExitProcess to terminate the process.

•	Return FALSE. If none of the registered handler functions returns TRUE, the default handler terminates the process.

•	Return TRUE. In this case, no other handler functions are called, and a pop-up dialog box asks the user whether to terminate the process. If the user chooses not to terminate the process, the system does not close the console until the process finally terminates.


  57.1.4.3  Console Process Groups

When a process uses the CreateProcess function to create a new console process, it can specify the CREATE_NEW_PROCESS_GROUP flag to make the new process the root process of a console process group. The process group includes all processes that are descendants of this root process.

A process can use the GenerateConsoleCtrlEvent function to send a CTRL+C or CTRL+BREAK signal to all processes in a console process group. The signal is only received by those processes in the group that are attached to the same console as the process that called GenerateConsoleCtrlEvent.


  57.2  Using the Console

The examples in this section illustrate how to perform the following console tasks:

•	Using the high-level I/O functions

•	Writing character and color attribute strings to a specified location in a screen buffer

•	Filling consecutive screen buffer cells with a specified character or color attribute

•	Copying a rectangular block of cells from one screen buffer to another

•	Reading input events from an input buffer

•	Scrolling a screen buffer's window

•	Scrolling a screen buffer's contents

•	Registering a control handler function


  57.2.1  Using the High-Level Input and Output Functions

The following example uses the high-level console I/O functions for console I/O. For more information about the high-level console I/O functions, see Section 57.1.2.2, »High-Level Console I/O«.

The example assumes that the default I/O modes are in effect initially for the first calls to the ReadFile and WriteFile functions. Then the input mode is changed to turn off line input mode and echo input mode for the second calls to ReadFile and WriteFile. The SetConsoleTextAttribute function is used to set the colors in which subsequently written text will be displayed. Before exiting, the program restores the original console input mode and color attributes.

The example's NewLine function is used when line input mode is disabled. It handles carriage returns by moving the cursor position to the first cell of the next row. If the cursor is already in the last row of the screen buffer, the contents of the screen buffer are scrolled up one line. For an example that illustrates the use of the ScrollConsoleScreenBuffer function to scroll a screen buffer, see Section 57.2.6, »Scrolling a Screen Buffer's Contents«.

#include <windows.h>

VOID NewLine(VOID);

VOID ScrollScreenBuffer(HANDLE, INT);

HANDLE hStdout, hStdin;

CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

VOID main(void) {

LPSTR lpszPrompt1 = "Type something and press Enter:\n";

LPSTR lpszPrompt2 = "Type any key: ";

CHAR chBuffer[256];

DWORD cRead, cWritten, fdwMode, fdwOldMode;

WORD wOldColorAttrs;

/* Get handles to STDIN and STDOUT. */

hStdin = GetStdHandle(STD_INPUT_HANDLE);

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

if (hStdin == INVALID_HANDLE_VALUE ||

        hStdout == INVALID_HANDLE_VALUE)

    MyErrorExit("GetStdHandle");

/* Save the current text colors. */

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))

    MyErrorExit("GetConsoleScreenBufferInfo");

wOldColorAttrs = csbiInfo.wAttributes;

/* Set text attr. to draw red text on black background. */

if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED))

        MyErrorExit("SetConsoleTextAttribute");

/*

 * Write to STDOUT and read from STDIN by using default

 * modes. Input is echoed automatically, and ReadFile

 * does not return until a carriage return is typed.

 *

 * The default input modes are line, processed, and echo.

 * The default output modes are processed and wrap at EOL.

 */

while (1) {

    if (! WriteFile(

            hStdout,              /* output handle  */

            lpszPrompt1,          /* prompt string  */

            lstrlen(lpszPrompt1), /* string length  */

            &cWritten,            /* bytes written  */

            NULL) )               /* not overlapped */

        break;

    if (! ReadFile(

            hStdin,    /* input handle        */

            chBuffer,  /* buffer to read into */

            255,       /* size of buffer      */

            &cRead,    /* actual bytes read   */

            NULL) )    /* not overlapped      */

        break;

    if (chBuffer[0] == 'q') break;

}

/* Turn off the line input mode, and echo the input mode. */

if (! GetConsoleMode(hStdin, &fdwOldMode))

    MyErrorExit("GetConsoleMode");

fdwMode = fdwOldMode &

          ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);

if (! SetConsoleMode(hStdin, fdwMode))

    MyErrorExit("SetConsoleMode");

/* Prompt for input. */

if (! WriteFile(

        hStdout,              /* output handle  */

        lpszPrompt2,          /* prompt string  */

        lstrlen(lpszPrompt2), /* string length  */

        &cWritten,            /* bytes written  */

        NULL) )               /* not overlapped */

    MyErrorExit("WriteFile");

/*

 * Without line and echo input modes, ReadFile returns

 * when any input is available. Carriage returns must

 * be handled, and WriteFile is used to echo input.

 */

while (1) {

    if (! ReadFile(hStdin, chBuffer, 1, &cRead, NULL))

        break;

    if (chBuffer[0] == '\r')

        NewLine();

    else

        if (! WriteFile(hStdout, chBuffer, cRead,

                        &cWritten, NULL))

            break;

    if (chBuffer[0] == 'q') break;

}

/* Restore the original console mode. */

if (! SetConsoleMode(hStdin, fdwOldMode))

    MyErrorExit("SetConsoleMode");

/* Restore the original text colors. */

if (! SetConsoleTextAttribute(hStdout, wOldColorAttrs))

    MyErrorExit("SetConsoleTextAttribute");

}

/*

 * The NewLine function handles carriage returns when the processed

 * input mode is disabled. It gets the current cursor position,

 * and resets it to the first cell of the next row.

 */

VOID NewLine(VOID) {

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))

    MyErrorExit("GetConsoleScreenBufferInfo");

csbiInfo.dwCursorPosition.X = 0;

/*

 * If it is the last line in the screen buffer, scroll

 * the buffer up.

 */

if ((csbiInfo.dwSize.Y-1) == csbiInfo.dwCursorPosition.Y) {

    ScrollScreenBuffer(hStdout, 1);

}

/* Otherwise, advance the cursor to the next line. */

else

    csbiInfo.dwCursorPosition.Y += 1;

if (! SetConsoleCursorPosition(hStdout,

              csbiInfo.dwCursorPosition))

    MyErrorExit("SetConsoleCursorPosition");

}


  57.2.2  Writing Characters or Colors to Consecutive Cells

You can write characters or color attributes to specified character cells in a screen buffer. The following example uses the WriteConsoleOutputCharacter function to write a string of characters beginning at the upper left corner of a screen buffer. Then the example uses the WriteConsoleOutputAttribute function to write a string of color attributes to the first 51 cells of the same line. The coord parameter for both functions specifies the character cell in the screen buffer at which writing begins. The location in the console window where these characters or colors appear depends on the current window rectangle of the screen buffer. For additional information about the relationship between a screen buffer and its windows, see Section 57.1.1.6, »Window and Screen Buffer Size«, and Section 57.1.1.7, »Scrolling the Screen Buffer«.

    HANDLE hOutput;

    LPTSTR lpszString = "Character String";

    DWORD cWritten;

    BOOL fSuccess;

    COORD coord;

    WORD wColors[3], wColor;

    CHAR chFillChar;

/* Write a string of characters to a screen buffer. */

    coord.X = 0;            /* start at first cell */

    coord.Y = 0;            /*   of first row      */

    fSuccess = WriteConsoleOutputCharacter(

        hOutput,              /* screen buffer handle     */

        lpszString,           /* pointer to source string */

        lstrlen(lpszString),  /* length of string         */

        coord,                /* first cell to write to   */

        &cWritten);           /* actual number written to */

    if (! fSuccess)

        MyErrorExit("WriteConsoleOutputCharacter");

/* Write a string of colors to a screen buffer. */

    wColors[0] = BACKGROUND_RED;

    wColors[1] = BACKGROUND_RED |     /* white background */

                 BACKGROUND_GREEN |

                 BACKGROUND_BLUE;

    wColors[2] = BACKGROUND_BLUE;

    for (;fSuccess && coord.X < 50; coord.X += 3)

        fSuccess = WriteConsoleOutputAttribute(

            hOutput,          /* screen buffer handle     */

            wColors,          /* pointer to source string */

            3,                /* length of string         */

            coord,            /* first cell to write to   */

            &cWritten);       /* actual number written to */

    if (! fSuccess)

        MyErrorExit("WriteConsoleOutputAttribute");

You can write the same character or color attribute to a specified number of consecutive screen buffer cells beginning at a specified location. The following example uses the FillConsoleOutputCharacter function to clear a 80-by-50-character screen buffer, and then it uses the FillConsoleOutputAttribute function to set the color attributes of the same cells.

/* Fill an 80-by-50-character screen buffer with the space character. */

    coord.X = 0;            /* start at first cell */

    coord.Y = 0;            /*   of first row      */

    chFillChar = ' ';

    fSuccess = FillConsoleOutputCharacter(

        hStdout,          /* screen buffer handle     */

        chFillChar,       /* fill with spaces         */

        80*50,            /* number of cells to fill  */

        coord,            /* first cell to write to   */

        &cWritten);       /* actual number written to */

    if (! fSuccess)

        MyErrorExit("FillConsoleOutputCharacter");

/* Set 80-by-50-character screen buffer colors to white text on red. */

    wColor = BACKGROUND_RED |

             FOREGROUND_RED |

             FOREGROUND_GREEN |

             FOREGROUND_BLUE;

    fSuccess = FillConsoleOutputAttribute(

        hStdout,          /* screen buffer handle     */

        wColor,           /* color to fill with       */

        80*50,            /* number of cells to fill  */

        coord,            /* first cell to write to   */

        &cWritten);       /* actual number written to */

    if (! fSuccess)

        MyErrorExit("FillConsoleOutputAttribute");


  57.2.3  Reading and Writing Blocks of Characters and Attributes

The ReadConsoleOutput function copies a rectangular block of character and color data from a screen buffer into a destination buffer. The function treats the destination buffer as a two-dimensional array of CHAR_INFO structures. Similarly, the WriteConsoleOutput function copies a rectangular block of character and color attribute data from a source buffer to a console screen buffer. For more information about reading from or writing to rectangular blocks of screen buffer cells, see Section 57.1.2.8, »Low-Level Console Output Functions«.

The following example uses the CreateConsoleScreenBuffer function to create a new screen buffer. After the SetConsoleActiveScreenBuffer function makes this the active screen buffer, a block of characters and attributes is copied from the top two rows of the SDTOUT screen buffer into a temporary buffer. The data is then copied from the temporary buffer into the new active screen buffer. When the application is finished using the new screen buffer, it calls SetConsoleActiveScreenBuffer to restore the original STDOUT screen buffer.

#include <windows.h>

VOID main(void) {

    HANDLE hStdout, hNewScreenBuffer;

    SMALL_RECT srctReadRect;

    SMALL_RECT srctWriteRect;

    CHAR_INFO chiBuffer[160]; // [2][80];

    COORD coordBufSize;

    COORD coordBufCoord;

    BOOL fSuccess;

    /*

     * Get a handle of the STDOUT screen buffer to copy from and

     * create a new screen buffer to copy to.

     */

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    hNewScreenBuffer = CreateConsoleScreenBuffer(

       GENERIC_READ |           /* read-write access      */

       GENERIC_WRITE,

       0,                       /* not shared             */

       NULL,                    /* no security attributes */

       CONSOLE_TEXTMODE_BUFFER, /* must be TEXTMODE       */

       NULL);                   /* reserved; must be NULL */

    if (hStdout == INVALID_HANDLE_VALUE ||

            hNewScreenBuffer == INVALID_HANDLE_VALUE)

        MyErrorExit("CreateConsoleScreenBuffer");

    /* Make the new screen buffer the active screen buffer. */

    if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )

        MyErrorExit("SetConsoleActiveScreenBuffer");

    /* Set the source rectangle. */

    srctReadRect.Top = 0;    /* top left: row 0, col 0  */

    srctReadRect.Left = 0;

    srctReadRect.Bottom = 1; /* bot. right: row 1, col 79 */

    srctReadRect.Right = 79;

    /* The temporary buffer size is 2 rows x 80 columns. */

    coordBufSize.Y = 2;

    coordBufSize.X = 80;

    /* The top left destination cell of the temporary buffer is

     * row 0, col 0. */

    coordBufCoord.X = 0;

    coordBufCoord.Y = 0;

    /* Copy the block from the screen buffer to the temp. buffer. */

    fSuccess = ReadConsoleOutput(

       hStdout,        /* screen buffer to read from       */

       chiBuffer,      /* buffer to copy into              */

       coordBufSize,   /* col-row size of chiBuffer        */

       coordBufCoord,  /* top left dest. cell in chiBuffer */

       &srctReadRect); /* screen buffer source rectangle   */

    if (! fSuccess)

        MyErrorExit("ReadConsoleOutput");

    /* Set the destination rectangle. */

    srctWriteRect.Top = 10;    /* top lt: row 10, col 0 */

    srctWriteRect.Left = 0;

    srctWriteRect.Bottom = 11; /* bot. rt: row 11, col 79 */

    srctWriteRect.Right = 79;

    /* Copy from the temporary buffer to the new screen buffer. */

    fSuccess = WriteConsoleOutput(

        hNewScreenBuffer, /* screen buffer to write to    */

        chiBuffer,        /* buffer to copy from          */

        coordBufSize,     /* col-row size of chiBuffer    */

        coordBufCoord, /* top left src cell in chiBuffer  */

        &srctWriteRect); /* dest. screen buffer rectangle */

    if (! fSuccess)

        MyErrorExit("WriteConsoleOutput");

    Sleep(10000);

    /* Restore the original active screen buffer. */

    if (! SetConsoleActiveScreenBuffer(hStdout))

        MyErrorExit("SetConsoleActiveScreenBuffer");

}


  57.2.4  Reading Input Buffer Events

You can use the ReadConsoleInput function to directly access a console's input buffer. When a console is created, mouse input is enabled and window input is disabled. To ensure that the process receives all types of events, this example uses the SetConsoleMode function to enable window and mouse input. Then it goes into a loop that reads and handles console input events.

VOID MouseEventProc(MOUSE_EVENT_RECORD);

VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);

VOID KeyEventProc(KEY_EVENT_RECORD);

VOID GetInputEvents(VOID);

DWORD main(VOID) {

    HANDLE hStdin;

    DWORD cNumRead, fdwMode, fdwSaveOldMode, i;

    INPUT_RECORD irInBuf[128];

    /* Get the standard input handle. */

    hStdin = GetStdHandle(STD_INPUT_HANDLE);

    if (hStdin == INVALID_HANDLE_VALUE)

        MyErrorExit("GetStdHandle");

    /* Save the current input mode, to be restored on exit. */

    if (! GetConsoleMode(hStdin, &fdwSaveOldMode) )

        MyErrorExit("GetConsoleMode");

    /* Enable the window and mouse input events. */

    fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;

    if (! SetConsoleMode(hStdin, fdwMode) )

        MyErrorExit("SetConsoleMode");

    /* Loop to read and handle the input events. */

    while (1) {

        /* Wait for the events. */

        if (! ReadConsoleInput(

                hStdin,      /* input buffer handle    */

                irInBuf,     /* buffer to read into    */

                128,         /* size of read buffer    */

                &cNumRead) ) /* number of records read */

            MyErrorExit("ReadConsoleInput");

        /* Dispatch the events to the appropriate handler. */

        for (i = 0; i < cNumRead; i++)

            switch(irInBuf[i].EventType) {

                case KEY_EVENT: /* keyboard input */

                    KeyEventProc(irInBuf[i].Event.KeyEvent);

                    break;

                case MOUSE_EVENT: /* mouse input */

                    MouseEventProc(irInBuf[i].Event.MouseEvent);

                    break;

                case WINDOW_BUFFER_SIZE_EVENT: /* screen buffer

                                                  resizing */

                    ResizeEventProc(

                        irInBuf[i].Event.WindowBufferSizeEvent);

                    break;

                case FOCUS_EVENT:  /* disregard focus events */

                case MENU_EVENT:   /* disregard menu events  */

                    break;

                default:

                    MyErrorExit("unknown event type");

                    break;

            }

    }

    return 0;

}


57.2.5  Scrolling a Screen Buffers Window
  57.2.5  Scrolling a Screen Buffer's Window

To scroll the contents of a screen buffer in the console window, call the SetConsoleWindowInfo function. You can also use this function to change the window size. The function can either specify the new upper left and lower right corners of the screen buffer's window as absolute screen buffer coordinates or specify the changes from the current window coordinates. The function fails if the specified window coordinates are outside the boundaries of the screen buffer.

The following example scrolls the view of the screen buffer up one line by modifying the absolute window coordinates returned by the GetConsoleScreenBufferInfo function.

HANDLE hStdout;

CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

SMALL_RECT srctWindow;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

/* Get the current screen buffer size and window position. */

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))

    MyErrorExit("GetConsoleScreenBufferInfo");

/*

 * Set the srctWindow function to the current window size and

 * location.

 */

srctWindow = csbiInfo.srWindow;

/*

 * If the window is not at the screen buffer top, move it up one

 * line.

 */

if ( srctWindow.Top > 0 ) {

    srctWindow.Top -= 1;      /* move top up by one row    */

    srctWindow.Bottom -= 1;   /* move bottom up by one row */

    if (! SetConsoleWindowInfo(

               hStdout,      /* screen buffer handle       */

               TRUE,         /* absolute coordinates       */

               &srctWindow)) /* specifies new location     */

        MyErrorExit("SetConsoleWindowInfo");

}

The same scrolling can be done by specifying the changes in the window coordinates.

/* Get the current screen buffer window position. */

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))

    MyErrorExit("GetConsoleScreenBufferInfo");

/*

 * If the window is not at the screen buffer top, move it up one

 * line.

 */

if (csbiInfo.srWindow.Top > 0) {

    srctWindow.Top = -1;      /* move top up by one row    */

    srctWindow.Bottom = -1;   /* move bottom up by one row */

    srctWindow.Left = 0;      /* no change                 */

    srctWindow.Right = 0;     /* no change                 */

    if (! SetConsoleWindowInfo(

               hStdout,      /* screen buffer handle   */

               FALSE,        /* deltas, not absolute   */

               &srctWindow)) /* specifies new location */

        MyErrorExit("SetConsoleWindowInfo");

}


57.2.6  Scrolling a Screen Buffers Contents
  57.2.6  Scrolling a Screen Buffer's Contents

The ScrollConsoleScreenBuffer function enables you to move a block of character cells from one part of a screen buffer to another part of the same screen buffer. The function specifies the upper left and lower right cells of the source rectangle to be moved and the destination coordinates of the new location for the upper left cell. The character and color data in the source cells is moved to the new location, and any cells left empty by the move are filled in with a specified character and color. If you specify a clipping rectangle, the cells outside of it are left unchanged.

You can use ScrollConsoleScreenBuffer to delete a line by specifying coordinates of the first cell in the line as the destination coordinates and specifying a scrolling rectangle that includes all the rows below the line.

The following example shows the use of a clipping rectangle to scroll only the bottom 15 rows of the screen buffer. The rows in the specified rectangle are scrolled up one line at a time, and the top row of the block is discarded. The contents of the screen buffer outside the clipping rectangle are left unchanged.

HANDLE hStdout;

BOOL fSuccess;

CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

SMALL_RECT srctScrollRect, srctClipRect;

CHAR_INFO chiFill;

COORD coordDest;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

if (hStdout == INVALID_HANDLE_VALUE)

    MyErrorExit("GetStdHandle");

/* Get the screen buffer size. */

fSuccess = GetConsoleScreenBufferInfo(hStdout, &csbiInfo);

if (! fSuccess)

    MyErrorExit("GetConsoleScreenBufferInfo");

/*

 * The scrolling rectangle is the bottom 15 rows of the

 * screen buffer.

 */

srctScrollRect.Top = csbiInfo.dwSize.Y - 16;

srctScrollRect.Bottom = csbiInfo.dwSize.Y - 1;

srctScrollRect.Left = 0;

srctScrollRect.Right = csbiInfo.dwSize.X - 1;

/* The destination for the scroll rectangle is one row up. */

coordDest.X = 0;

coordDest.Y = csbiInfo.dwSize.Y - 17;

/*

 * The clipping rectangle is the same as the scrolling rectangle.

 * The destination row is left unchanged.

 */

srctClipRect = srctScrollRect;

/* Fill the bottom row with green blanks. */

chiFill.Attributes = BACKGROUND_GREEN | FOREGROUND_RED;

chiFill.Char.AsciiChar = ' ';

/* Scroll up one line. */

fSuccess = ScrollConsoleScreenBuffer(

    hStdout,         /* screen buffer handle     */

    &srctScrollRect, /* scrolling rectangle      */

    &srctClipRect,   /* clipping rectangle       */

    coordDest,       /* top left destination cell*/

    &chiFill);       /* fill character and color */


  57.2.7  Registering a Control Handler Function

This section shows an example of the SetConsoleCtrlHandler function that is used to install a control handler.

When a CTRL+C signal is received, the control handler returns TRUE, indicating that it has handled the signal. This prevents other control handlers from being invoked.

When a CTRL_CLOSE_EVENT signal is received, the control handler returns TRUE. This causes the system to display a dialog box that gives the user the choice of terminating the process and closing the console or allowing the process to continue execution. If the user chooses not to terminate the process, the system closes the console when the process finally terminates.

When a CTRL+BREAK, CTRL_LOGOFF_EVENT, or CTRL_SHUTDOWN_EVENT signal is received, the control handler returns FALSE. This causes the signal to be passed to the next control handler function. If no other control handlers have been registered or none of the registered handlers returns TRUE, the default handler will be invoked, resulting in the process being terminated.

BOOL CtrlHandler(DWORD fdwCtrlType) {

    switch (fdwCtrlType) {

        /* Handle the CTRL+C signal. */

        case CTRL_C_EVENT:

            Beep(1000, 1000);

            return TRUE;

        /* CTRL+CLOSE: confirm that the user wants to exit. */

        case CTRL_CLOSE_EVENT:

            return TRUE;

        /* Pass other signals to the next handler. */

        case CTRL_BREAK_EVENT:

        case CTRL_LOGOFF_EVENT:

        case CTRL_SHUTDOWN_EVENT:

        default:

            return FALSE;

    }

}

VOID main(void) {

BOOL fSuccess;

fSuccess = SetConsoleCtrlHandler(

    (PHANDLER_ROUTINE) CtrlHandler,  /* handler function */

    TRUE);                           /* add to list      */

if (! fSuccess)

    MyErrorExit("Could not set control handler");


  57.2.8  Console Application Issues

The 8-bit console APIs use the OEM codepage. All other APIs use the ANSI codepage by default. This means that strings returned by the console APIs may not be processed correctly by the other APIs and vice versa. For example, if FindFirstFileA returns a string that contains certain extended ANSI characters, WriteConsoleA will not display the string properly.

The best long-term solution for a console application is to use Unicode. Short of that solution, a console application should use the SetFileApisToOEM function. That function changes the relevant Windows NT file functions so that they produce OEM character set strings rather than ANSI character set strings.

When dealing with command lines, a console  application should obtain the command line in Unicode form and convert it to OEM form using the relevant  character-to-OEM functions. Also, note that argv uses the ANSI character set.

Here is a list of Windows NT file functions that are involved in this situation:

_lopen	GetDriveType	LoadLibrary
CopyFile	GetFileAttributes	LoadLibraryEx
CreateDirectory	GetFullPathName	MoveFile
CreateFile	GetModuleFileName	MoveFileEx
CreateProcess	GetModuleHandle	OpenFile
DeleteFile	GetSystemDirectory	RemoveDirectory
FindFirstFile	GetTempFileName	SearchPath
FindNextFile	GetTempPath	SetCurrentDirectory
GetCurrentDirectory	GetVolumeInformation	SetFileAttrributes
GetDiskFreeSpace	GetWindowsDirectory


  57.3  Functions

Following are the functions used to access a console.

AllocConsole
CreateConsoleScreenBuffer
FillConsoleOutputAttribute
FillConsoleOutputCharacter
FlushConsoleInputBuffer
FreeConsole
GenerateConsoleCtrlEvent
GetConsoleCP
GetConsoleCursorInfo
GetConsoleMode
GetConsoleOutputCP
GetConsoleScreenBufferInfo
GetConsoleTitle
GetLargestConsoleWindowSize
GetNumberOfConsoleInputEvents
GetNumberOfConsoleMouseButtons
GetStdHandle
PeekConsoleInput
ReadConsole
ReadConsoleInput
ReadConsoleOutput
ReadConsoleOutputAttribute
ReadConsoleOutputCharacter
ScrollConsoleScreenBuffer
SetConsoleActiveScreenBuffer
SetConsoleCP
SetConsoleCtrlHandler
SetConsoleCursorInfo
SetConsoleCursorPosition
SetConsoleMode
SetConsoleOutputCP
SetConsoleScreenBufferSize
SetConsoleTextAttribute
SetConsoleTitle
SetConsoleWindowInfo
SetStdHandle
WriteConsole
WriteConsoleInput
WriteConsoleOutput
WriteConsoleOutputAttribute
WriteConsoleOutputCharacter


Services
  Chapter 58    Services

58.1  About Services

In the Microsoft Win32 application programming interface (API), a service is an executable object that is installed in a registry database maintained by the service control manager. The services database includes information that determines whether each installed service is started on demand or is started automatically when the system starts up. The database can also contain logon and security information for a service so that a service can run even though no user is logged on. It also enables system administrators to customize security requirements for each service and thereby control access to the service. No more than one instance of a service can be running at a time.

Services can be divided into these two groups: Win32 services that conform to the interface rules of the service control manager and driver services that conform to the device driver protocols for Windows NT.


  58.1.1  The Service Control Manager

A service control manager provides a unified and secure means of controlling services. Each machine that is running Windows NT has a service control manager process started by the system at system startup. The service control manager is a Remote Procedure Call (RPC) server. The functions in the Win32 API that access a service control manager are provided through RPC so that service configuration and service control processes can manipulate services on remote machines.

The Win32 API includes a set of functions that provide a programmer's interface for the following tasks performed by the service control manager:

•	Using the registry to maintain a database of installed service objects.

•	Starting services either when the system is starting up or on demand.

•	Maintaining status information on running services.

•	Transmitting control requests to running services.

Three types of programs use these functions:

Type	Description
Win32 service process
	A process that provides executable code for one or more services. Win32 services use functions that connect to the service control manager and send status information to it. Driver services do not use these functions.
Service configuration program
	A program that queries or modifies a service control manager database. Service configuration programs use functions that open a database, install or delete services in a database, and query or modify the configuration and security parameters of installed services. The functions are used to manipulate Win32 services and driver services.
Service control program
	A program that starts a service and controls a running service. Service control programs use functions that send requests to the service control manager, which starts the requested service or sends the control request to the specified service.


  58.1.2  Database of Installed Services

The service control manager maintains a ServicesActive database in the configuration registry. This is the currently active database that was used to start the system. The registry path to this database is HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. In this directory, there is a <ServiceName> key for each installed Win32 service or driver service. The <ServiceName> key is the name of the service specified by the CreateService function when the service was installed.

The database includes the following information about each installed service:

•	The type of service. For Win32 services, the service type indicates whether the service executes in its own process or shares a process with other Win32 services. For driver services, it indicates whether the service is a kernel driver or a file system driver.

•	The start type of the service. The start type indicates whether the service is started automatically at system startup or whether the service control manager starts it when requested to by a service control process. The start type can also indicate whether the service is disabled, in which case it cannot be started.

•	A fully-qualified path of the service's executable file. The filename extension is .EXE for Win32 services and .SYS for driver services.

•	Optional information used by the service control manager to determine the proper order for starting services. This information can include a list of services that must be running before the service can start, the name of a load ordering group that the service is part of, and a tag identifier that indicates the start order of the service in its load ordering group.

•	For Win32 services, an optional logon account name in which the service process runs and an optional password for this account. If no account is specified, the service runs in the LocalSystem account.

•	For driver services, an optional Windows NT driver object name (for example, \FileSystem\Rdr or \Driver\Xns), used by the I/O system to load the device driver. If no name is specified, the I/O system creates a default name based on the service name.


  58.1.3  Win32 Service Processes

A Win32 service process contains executable code for one or more services. To conform to the interface requirements of the service control manager, it must include:

•	A main function that immediately calls the StartServiceCtrlDispatcher function to connect the main thread of the process to the Service Control Manager.

•	An entry point function, ServiceMain, for each service that can run in the process.

•	A control handler function, Handler, for each service that can run in the process.

For simplicity, the discussions in this section use the term service to mean Win32 service. The information in this section does not apply to driver services.


  58.1.3.1  Main Function

When the service control manager starts a service process, it waits for the process to call the StartServiceCtrlDispatcher function. If a service does not share a process with other services (SERVICE_WIN32_OWN_PROCESS services), the main thread of a service process should make this call immediately, leaving all initialization tasks to be performed by the ServiceMain function after the service is started. For services where multiple services share a process (SERVICE_WIN32_SHARE_PROCESS services) and where some common process-wide initialization needs to be done before any ServiceMain function is called, the main thread can do the work before calling StartServiceCtrlDispatcher, as long as it takes less than 30 seconds. Otherwise, another thread must be created to do the process-wide initialization, while the main thread calls StartServiceCtrlDispatcher. Any service specific initialization should still be done by the individual ServiceMain functions.

If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager and does not return until all running services in the process have terminated. The service control manager uses this connection to send control and service start requests to the main thread of the service process. The main thread acts as a dispatcher by calling the appropriate Handler function to handle control requests or by creating a new thread to execute the appropriate ServiceMain function when a new service is started.

The StartServiceCtrlDispatcher function specifies a dispatch table containing an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored.


  58.1.3.2  Service Main Function

Each service has a ServiceMain function that performs the initialization tasks for the service. A service process that can execute multiple services can have multiple ServiceMain functions.

When a service control program calls the StartService function to start a service, the service control manager starts the service process (if it is not already running). Then the service control manager sends the start request to the control dispatcher in the main thread of the service process. The dispatcher creates a new thread to execute the ServiceMain function for the specified service.

A ServiceMain function should perform the following ordered steps:

1.	Call the RegisterServiceCtrlHandler function immediately to register a Handler function to handle control requests for the service. The return value of RegisterServiceCtrlHandler is a SERVICE_STATUS_HANDLE type that identifies the service in calls to the SetServiceStatus function.

2.	Call SetServiceStatus to update the status of the service control manager information for the service. This function should specify the current service state as SERVICE_START_PENDING.

3.	Complete the initialization tasks for the service, such as starting additional threads to perform the work of the service. If this initialization is time-consuming, the application should make additional calls to SetServiceStatus to report the progress of the initialization to the service control manager.

4.	As one of the initialization tasks, call the CreateEvent function to create an event object. The other threads of the process, such as the control handling thread, use this event object to signal the ServiceMain function thread that it is time to terminate.

5.	When initialization is complete, call SetServiceStatus to specify SERVICE_RUNNING as the current service state.

6.	Call the WaitForSingleObject function to wait for the termination event object to be signaled. This blocks the execution of the ServiceMain function thread until the service is ready to terminate. The service's Handler function sets the event object to the signaled state if it receives the SERVICE_CONTROL_STOP control code. If an error occurs that requires service termination, other threads of the service can also signal the event object.

7.	When the wait function returns, perform any cleanup tasks, and then return.

For more information about the CreateEvent and WaitForSingleObject functions, see Chapter 44, »Synchronization«.

During lengthy initializations, the ServiceMain function should make frequent calls to SetServiceStatus to let the service control manager know that progress is being made. The following members of the SERVICE_STATUS structure specified by SetServiceStatus should change as the initialization progresses:

Member	Value
dwCurrentState	This value should be SERVICE_START_PENDING service state during initialization, changing to SERVICE_RUNNING when initialization is complete.
dwControlsAccepted	Control codes may be disabled during initialization. After initialization is complete, enable the desired control codes.
dwCheckPoint	This value lets the service control manager know how far initialization has progressed. Increment this value each time SetServiceStatus is called during lengthy initializations.
dwWaitHint	This value specifies a worst-case estimate of the amount of time in milliseconds that will elapse before the next status message will be sent out. If this interval elapses and the checkpoint has not been incremented, the service control manager or the service control program that started the service may assume that an error has occurred. Set this value to allow a generous amount of time to complete the next initialization step.


  58.1.3.3  Control Handler Function

Each Win32 service has a control handler function, the Handler function, that is invoked by the main thread's control dispatcher when the service receives a control request. The service specifies the address of this function when it calls the RegisterServiceCtrlHandler entrypoint function, in its ServiceMain function. Control requests are generated by service control programs that call the ControlService function.

Whenever a service's Handler function is invoked, the service must call the SetServiceStatus function to report its status to the service control manager. This reporting must be done even if the service's status did not change.

The ControlService function can specify any of the standard control codes listed in the following table. All services must accept and process the SERVICE_CONTROL_INTERROGATE code. When a service calls SetServiceStatus, it can enable or disable the other standard control codes. Services can also handle additional user-defined control codes, which must be in the range 128 to 255, inclusive.

Control	Meaning
SERVICE_CONTROL_STOP
	Requests the service to stop.
SERVICE_CONTROL_PAUSE
	Requests the service to pause.
SERVICE_CONTROL_CONTINUE
	Requests the paused service to resume.
SERVICE_CONTROL_INTERROGATE
	Requests the service to immediately update its current status information to the service control manager.
SERVICE_CONTROL_SHUTDOWN
	Requests the service to perform cleanup tasks, because the system is shutting down. Due to the extremely limited time available for shutdown, this control should only be used by services that absolutely need to shut down. For instance, the eventlog service needs to clear a dirty bit in the files that it maintains, or the server service needs to shut down so that network connections cannot be made when the system is in the shutdown state.
	If the service takes time to shut down, and sends out STOP_PENDING status messages, it is highly recommended that these messages include a wait hint so that the service controller will know how long to wait before indicating to the system that service shutdown is complete. The system gives the service control manager a limited amount of time (about 20 seconds) to complete service shutdown, after which time system shutdown proceeds regardless of whether service shutdown is complete.


  58.1.4  Service Configuration Programs

Service configuration programs are used by programmers or system administrators to query or modify a service control manager database. These databases are maintained in the configuration registry, so they can also be accessed by using the registry functions or a registry editor. It is, however, safer to use the service control manager's configuration functions, which ensure that the service is installed and configured properly.

Service control manager databases and services are implemented as objects that should only be accessed through the service control manager's configuration functions. A database of installed services is represented by an SCManager object, and an installed service is represented by a service object. An SCManager object is a container object that holds service objects.

The handle type of both SCManager objects and service objects is SC_HANDLE. The OpenSCManager function returns a handle to an SCManager object on a specified machine. The CreateService and OpenService functions return a handle to a service object installed in a specified SCManager object. The CloseServiceHandle function closes SC_HANDLE to either an SCManager object or a service object.

The functions that return SC_HANDLE can request different types of access to the SCManager or service object. The requested access is granted or denied depending on the access token of the calling process and the security descriptor associated with the SCManager or service object.

A configuration program uses the CreateService function to install a new service in an service control manager database. This function specifies the name of the service and provides the service's configuration information that is stored in the database. For a description of the information stored in the database for each service, see Section 58.1.2, »Database of Installed Services«. The DeleteService function removes an installed service from its database.

The following functions are available to determine the current configuration of a service control manager database:

Function	Description
QueryServiceConfig
	Fills in a buffer with a QUERY_SERVICE_CONFIG structure, containing the current configuration information for a specified service object.
QueryServiceObjectSecurity
	Fills in a buffer with the SECURITY_DESCRIPTOR structure of a specified SCManager or service object.
EnumDependentServices
	Fills in a buffer with an array of ENUM_SERVICE_STATUS structures, containing the name and current status of all services that are dependent on a specified service object.
EnumServicesStatus
	Fills in a buffer with an array of ENUM_SERVICE_STATUS structures, containing the name and current status of all services in a specified SCManager object.
To modify the configuration information for a service object, a configuration program uses the ChangeServiceConfig function. To modify the security descriptor for either an SCManager object or a service object, a configuration program uses the SetServiceObjectSecurity function.

Before using either of these functions to reconfigure a service object, a program should use the LockServiceDatabase function. This function tries to acquire a lock on the specified service control manager database and, if successful, prevents the service control manager from starting a service while the database is being reconfigured. A lock should also be acquired before using the registry functions to reconfigure a service object. Note, however, that failure to acquire a lock does not prevent a configuration program from successfully reconfiguring a service object. The only effect of a lock is to prevent the service control manager from starting a service in the locked database. To release the lock on the database when the reconfiguration is complete, use the UnlockServiceDatabase function. To determine whether the database is locked, use the QueryServiceLockStatus function.


  58.1.5  Service Control Programs

A service control program performs the following actions:

•	Starts a Win32 service or a driver service, if the service's start type is SERVICE_DEMAND_START.

•	Sends control requests to a running service.

•	Queries the current status of a running service.

The program must have an open handle to any service object that it wants to start or control. To do this, it must perform these steps:

1.	Use the OpenSCManager function to open a handle to a service control manager database on a specified machine.

2.	Use the OpenService or CreateService function to open a handle to the desired service object.


  58.1.5.1  Service Startup

To start a service, use the StartService function. For Win32 services, the calling process can use the parameters of this function to specify an array of arguments that are passed to the ServiceMain function of the service. This function fails if the service control manager database is locked. If this occurs, the service control program can wait a few seconds and call StartService again. It can check the current lock status of the database by calling the QueryServiceLockStatus function.

When starting a driver service, StartService returns after the device driver has completed its initialization.

When starting a Win32 service, StartService returns after the ServiceMain function thread for the new service has been created. During its initialization, a service specifies a SERVICE_STATUS structure in calls to the SetServiceStatus function to report its progress to the service control manager. The service control program can retrieve this status information by calling the QueryServiceStatus function. During initialization, the dwCurrentState member of the SERVICE_STATUS structure should be SERVICE_START_PENDING. The service should increment the dwCheckPoint member at regular intervals during initialization. The dwWaitHint member is a time interval, in milliseconds, that indicates how long the service control program should wait before calling QueryServiceStatus again. When the initialization is complete, the service changes the dwCurrentState member to SERVICE_RUNNING.


  58.1.5.2  Service Control Requests

To send control requests to a running service, use the ControlService function. This function specifies a control code that is passed to the Handler function of the specified service. This control code can be a user-defined code, or it can be one of the standard codes that enable the calling program to perform the following actions:

•	Stops or pauses a service.

•	Resumes a paused service.

•	Gets updated status information from a service.

Each service specifies the control codes that it will accept and process. To determine which of the standard control codes are accepted by a service, use the QueryServiceStatus function or specify the SERVICE_CONTROL_INTERROGATE control code in a call to the ControlService function. The dwControlsAccepted member of the SERVICE_STATUS structure returned by these functions indicates whether the service can be stopped and whether it can be paused and resumed. All services accept the SERVICE_CONTROL_INTERROGATE control code, which requests the service to immediately report its current status.

Note, however, that the QueryServiceStatus function reports the service control manager's most recent status for a specified service, but does not get an updated status from the service itself. Using the SERVICE_CONTROL_INTERROGATE control code in a call to ControlService ensures that the status information returned is current.


  58.1.6  Service Security

When a process uses the OpenSCManager function to open a handle to a service control manager database, the system performs a security check before granting the requested access. All processes are permitted SC_MANAGER_CONNECT, SC_MANAGER_ENUMERATE_SERVICE, and SC_MANAGER_QUERY_LOCK_STATUS access to all service control manager databases. This access enables any process to open a service control manager database handle that it can use for the OpenService, EnumServicesStatus, and QueryServiceLockStatus functions. Only processes with Administrator privileges are able to open a database handle that can be used by the CreateService and LockServiceDatabase functions.

Security for service objects is provided by an access check performed when a process uses the OpenService function. The access permitted to different users depends on the SECURITY_DESCRIPTOR structure associated with the service object. The service control manager creates a service object's security descriptor when the service is installed by the CreateService function. You can use the QueryServiceObjectSecurity and SetServiceObjectSecurity functions to query and set the security descriptor of a service object. The default security descriptor of a service object permits the following access:

•	All users have SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, SERVICE_ENUMERATE_DEPENDENTS, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL access.

•	Local users have SERVICE_START access in addition to those listed above.

•	LocalSystem users and PowerUsers have SERVICE_START, SERVICE_PAUSE_CONTINUE, and SERVICE_STOP access in addition to those listed above.

•	Administrators have SERVICE_ALL_ACCESS access.


  58.1.6.1  Win32 Service User Accounts

Each Win32 service runs in a user account. The username and password of an account are specified by the CreateService function at the time the service is installed. The user name and password can be changed by using the ChangeServiceConfig function. You can use the QueryServiceConfig function to get the user name (but not the password) of a service object.

When starting a service process, the service control manager logs on to the account associated with the service. If the log on is successful, the system produces an access token and attaches it to the new service process. This token identifies the service process in all subsequent interactions with securable objects (objects that have a security descriptor associated with them). For example, if the service tries to open a handle to a pipe, the system compares the service's access token to the pipe's security descriptor before granting access.

A SERVICE_WIN32_OWN_PROCESS service that runs in a process by itself can have an account from either the built-in (local), primary, or trusted domain. A SERVICE_WIN32_SHARE_PROCESS service that can share a process with multiple services must be installed to run in the LocalSystem account. This restriction exists because different services in the same process must run under the same security context.

The service control manager does not try to maintain the passwords of service user accounts. If a password is expired, the logon fails and the service fails to start. The system administrator who assigns accounts to services can create accounts with passwords that never expire. The administrator can also manage accounts with passwords that expire by using a service configuration program to periodically change the passwords.

If a service needs to recognize another service before sharing its information, the second service can either use the same account as the first service, or it can run in an account belonging to an alias that is recognized by the first service. Services that need to run in a distributed manner across the network should run in domain-wide accounts.


  58.2  Using Services

The examples in this section illustrate the following:

•	The main function of a Win32 service process

•	The entry point function, ServiceMain, of a Win32 service process

•	The control handler function, Handler, of a Win32 service process

•	Opening a service control manager database

•	Installing and deleting a service in a service control manager database

•	Changing or querying the configuration of an installed service

•	Starting a service

•	Sending control requests to a running service


58.2.1  Writing a Win32 Service Processs main Function
  58.2.1  Writing a Win32 Service Process's main Function

The main function of a Win32 service process must call the StartServiceCtrlDispatcher function as soon as possible. For service processes that execute only one service, the function is called immediately, because the service's ServiceMain function can perform all initialization tasks for the service. The following example shows the main function for a SERVICE_WIN32_OWN_PROCESS service process:

/* Globals */

SERVICE_STATUS ssStatus;

HANDLE hServDoneEvent = NULL;

SERVICE_STATUS_HANDLE sshStatusHandle;

/* Exit code that is set by any thread when error occurs. */

DWORD dwGlobalErr = NO_ERROR;

VOID main(VOID) {

  SERVICE_TABLE_ENTRY   steDispatchTable[] = {

      /* entry for "Sample_Srv" */

      { TEXT("Sample_Srv"),

        (LPSERVICE_MAIN_FUNCTION) ServMainFunc},

      /* NULL entry designating the end of the table. */

      { NULL, NULL }

  };

  /*

   * The main thread of a service process starts the service control

   * dispatcher that dispatches start and control requests

   * for the services specified in steDispatchTable. This

   * function does not return unless there is an error.

   */

  if (! StartServiceCtrlDispatcher(steDispatchTable) )

      MyErrorExit("StartServiceCtrlDispatcher");

}

When a service process will execute multiple services, it may be necessary to perform some common process-wide initialization before starting any of the services. If this initialization is brief (less than 30 seconds), the main thread can do it before calling the StartServiceCtrlDispatcher function. Otherwise, you can use one of the following strategies:

•	Use the CreateThread function to create a thread to perform the initialization.

•	Use a global flag that each service's ServiceMain function checks during its initialization so that the first service to start up performs the common initialization.

Other than these initialization issues and the fact that there is a dispatch table with additional entries, the main thread of a multiple service process does not differ from that of a service process with a single service.


  58.2.2  Writing a ServiceMain Function

The ServMainFunc function in the following example is the service's entry point function, ServiceMain. It first calls the RegisterServiceCtrlHandler function to register the Handler function, called the ServCtrlHandler function in this example. Then it calls the ReportStatusToSCMgr subroutine, which updates the service's status by calling the SetServiceStatus function. As the initialization tasks are completed, it makes additional status updates, incrementing the checkpoint value each time.

As part of the initialization, the service calls the CreateEvent function to create the hServDoneEvent event object. The initial state of hServDoneEvent is not-signaled. After the initialization is complete, the service updates its status to SERVICE_RUNNING (with checkpoint and waithint values set to zero). Then it calls the WaitForSingleObject function to wait for the state of hServDoneEvent, to be signaled. When this occurs, the ServMainFunc function updates the services status to SERVICE_STOPPED, cleans up, and exits.

/*

 * ServiceMain function of "Sample_Srv"

 *

 * When the service is started, the service control dispatcher

 * creates a new thread to execute this function.

 */

VOID ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) {

  DWORD dwWait;

  /* Register the control handler function for this service. */

  sshStatusHandle = RegisterServiceCtrlHandler(

      TEXT("Sample_Srv"), /* service name             */

      ServCtrlHandler);   /* control handler function */

  if (sshStatusHandle == (SERVICE_STATUS_HANDLE) NULL)

      goto Cleanup;

  /* SERVICE_STATUS members that do not change in example. */

  ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

  ssStatus.dwServiceSpecificExitCode = 0;

  /* Report the status to service control manager. */

  if (! ReportStatusToSCMgr(

      SERVICE_START_PENDING, /* service state */

      NO_ERROR,              /* exit code     */

      1,                     /* checkpoint    */

      3000) )                /* wait hint     */

      goto Cleanup;

  /*

   * Create the event object. The control handler function signals

   * this event when it receives the "stop" control code.

   */

  hServDoneEvent = CreateEvent (

     NULL,    /* no security attributes */

     TRUE,    /* manual reset event     */

     FALSE,   /* nonsignaled            */

     NULL);   /* no name                */

  if ( hServDoneEvent == (HANDLE) NULL )

      goto Cleanup;

  /* Report the status to the service control manager. */

  if (! ReportStatusToSCMgr(

      SERVICE_START_PENDING, /* service state */

      NO_ERROR,              /* exit code     */

      2,                     /* checkpoint    */

      3000) )                /* wait hint     */

      goto Cleanup;

  /* Start the thread that performs the work of the service. */

  if (! SampleServiceInit() )

      goto Cleanup;

  /* Report the status to the service control manager. */

  if (! ReportStatusToSCMgr(

      SERVICE_RUNNING, /* service state */

      NO_ERROR,        /* exit code     */

      0,               /* checkpoint    */

      0) )             /* wait hint     */

      goto Cleanup;

  /* Wait indefinitely until hServDoneEvent is signaled. */

  dwWait = WaitForSingleObject (

    hServDoneEvent,  /* event object      */

    INFINITE);       /* wait indefinitely */

Cleanup :

  if (hServDoneEvent != NULL)

     CloseHandle(hServDoneEvent);

  /* Try to report the stopped status to the service control manager. */

  if (sshStatusHandle != NULL)

      (VOID) ReportStatusToSCMgr(SERVICE_STOPPED,

                             dwGlobalErr, 0, 0);

  /*

   * When ServiceMain function returns in a single service

   * process, the StartServiceCtrlDispatcher function in

   * the main thread returns, terminating the process.

   */

  return;

}

/*

 * ReportStatusToSCMgr function

 *

 * This function is called by the ServMainFunc() and

 * ServCtrlHandler() functions to update the service's status

 * to the service control manager.

 */

BOOL ReportStatusToSCMgr (DWORD dwCurrentState,

     DWORD dwWin32ExitCode, DWORD dwCheckPoint,

     DWORD dwWaitHint) {

  BOOL fResult;

  /* Disable control requests until the service is started. */

  if (dwCurrentState == SERVICE_START_PENDING)

      ssStatus.dwControlsAccepted = 0;

  else

      ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |

          SERVICE_ACCEPT_PAUSE_CONTINUE;

  /* These SERVICE_STATUS members are set from parameters. */

  ssStatus.dwCurrentState = dwCurrentState;

  ssStatus.dwWin32ExitCode = dwWin32ExitCode;

  ssStatus.dwCheckPoint = dwCheckPoint;

  ssStatus.dwWaitHint = dwWaitHint;

  /* Report the status of the service to the service control manager. */

  if (! (fResult = SetServiceStatus (

      sshStatusHandle,    /* service reference handle */

      &ssStatus) ) ) {    /* SERVICE_STATUS structure */

      /* If an error occurs, stop the service. */

      StopSampleService("SetServiceStatus");

  }

  return fResult;

}

/*

* The StopSampleService function can be used by any thread to report an

* error, or stop the service.

*/

VOID StopSampleService(LPTSTR lpszMsg) {

CHAR chMsg[256];

HANDLE hEventSource;

LPTSTR lpszStrings[2];

  dwGlobalErr = GetLastError();

  /*  Use event logging to log the error. */

  hEventSource = RegisterEventSource(NULL,

                         TEXT("Sample_Srv"));

  sprintf(chMsg, "Sample_Srv error: %d", dwGlobalErr);

  lpszStrings[0] = chMsg;

  lpszStrings[1] = lpszMsg;

  if (hEventSource != NULL) {

      ReportEvent(hEventSource, /* handle of event source */

          EVENTLOG_ERROR_TYPE,  /* event type             */

          0,                    /* event category         */

          0,                    /* event ID               */

          NULL,                 /* current user's SID     */

          2,                    /* strings in lpszStrings */

          0,                    /* no bytes of raw data   */

          lpszStrings,          /* array of error strings */

          NULL);                /* no raw data            */

      (VOID) DeregisterEventSource(hEventSource);

  }

  /* Set a termination event to stop ServiceMain function. */

  SetEvent(hServDoneEvent);

}


  58.2.3  Writing a Control Handler Function

The ServCtrlHandler function in the following example is the service's control handler function, Handler function. When this function is called by the main thread's control dispatcher, it handles the control request and then calls the ReportStatusToSCMgr subroutine to update the service's status.

/*

 * The service control dispatcher invokes this function when it

 * gets a control request from the service control manager.

 */

VOID ServCtrlHandler (DWORD dwCtrlCode) {

  DWORD  dwState = SERVICE_RUNNING;

  /* Handle the requested control code. */

  switch(dwCtrlCode) {

      /* Pause the service if it is running. */

      case SERVICE_CONTROL_PAUSE:

          if (ssStatus.dwCurrentState == SERVICE_RUNNING) {

              PauseSampleService();

              dwState = SERVICE_PAUSED;

          }

          break;

      /* Resume the paused service. */

      case SERVICE_CONTROL_CONTINUE:

          if (ssStatus.dwCurrentState == SERVICE_PAUSED) {

              ResumeSampleService();

              dwState = SERVICE_RUNNING;

          }

          break;

      /* Stop the service. */

      case SERVICE_CONTROL_STOP:

          dwState = SERVICE_STOP_PENDING;

          /*

           * Report the status, specifying the checkpoint and waithint,

           * before setting the termination event.

           */

          (VOID) ReportStatusToSCMgr(

                   SERVICE_STOP_PENDING, /* current state */

                   NO_ERROR,             /* exit code     */

                   1,                    /* checkpoint    */

                   3000);                /* waithint      */

          SetEvent(hServDoneEvent);

          return;

      /* Update the service status. */

      case SERVICE_CONTROL_INTERROGATE:

          break;

      /* invalid control code */

      default:

          break;

    }

    /* Send a status response. */

    (VOID) ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0);

}


  58.2.4  Opening an SCManager Database

The examples in the following sections require an open handle to an SCManager database object. Different operations on a service control manager database require different levels of access, and you should only request the minimum access required. If SC_MANAGER_ALL_ACCESS is requested, the OpenSCManager function fails if the calling process does not have Administrator privileges. The following example shows how to request full access to the ServicesActive database on the local machine.

/* Open a handle to the SC Manager database. */

schSCManager = OpenSCManager(

     NULL,                   /* local machine           */

     NULL,                   /* ServicesActive database */

     SC_MANAGER_ALL_ACCESS); /* full access rights      */

if (schSCManager == NULL)

    MyErrorExit("OpenSCManager");


  58.2.5  Installing a Service

A service configuration program uses the CreateService function to install a service in a service control manager database. The schSCManager handle must have SC_MANAGER_CREATE_SERVICE access to the SCManager object. The following example shows how to install a service.

VOID CreateSampleService() {

LPCTSTR lpszBinaryPathName =

          TEXT("%SystemRoot%\\system\\testserv.exe");

  schService = CreateService(

       schSCManager,              /* SCManager database     */

       TEXT("Sample_Srv"),        /* name of service        */

       SERVICE_ALL_ACCESS,        /* desired access         */

       SERVICE_WIN32_OWN_PROCESS, /* service type           */

       SERVICE_DEMAND_START,      /* start type             */

       SERVICE_ERROR_NORMAL,      /* error control type     */

       lpszBinaryPathName,        /* service's binary       */

       NULL,                      /* no load ordering group */

       NULL,                      /* no tag identifier      */

       NULL,                      /* no dependencies        */

       NULL,                      /* LocalSystem account    */

       NULL);                     /* no password            */

  if (schService == NULL)

      MyErrorExit("CreateService");

  else

      printf("CreateService SUCCESS\n");

  CloseServiceHandle(schService);

}


  58.2.6  Deleting a Service

In the following example, a service configuration program uses the OpenService function to get a handle with DELETE access to an installed service object. The program then uses the service object handle in the DeleteService function to remove the service from the service control manager database.

VOID DeleteSampleService() {

  schService = OpenService(

       schSCManager,       /* SCManager database      */

       TEXT("Sample_Srv"), /* name of service         */

       DELETE);            /* only need DELETE access */

  if (schService == NULL)

      MyErrorExit("OpenService");

  if (! DeleteService(schService) )

      MyErrorExit("DeleteService");

  else

      printf("DeleteService SUCCESS\n");

  CloseServiceHandle(schService);

}


  58.2.7  Changing a Service Configuration

In the following example, a service configuration program uses the ChangeServiceConfig function to change the configuration parameters of an installed service. The program first tries to lock the database, to prevent the service control manager from starting a service while it is being reconfigured. If it successfully locks the database, the program opens a handle to the service object, modifies its configuration, unlocks the database, and then closes the service  object handle. If the program does not successfully in lock the database, it uses the QueryServiceLockStatus function to retrieve information about the lock.

VOID ReconfigureSampleService(BOOL fDisable) {

SC_LOCK sclLock;

LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;

DWORD dwBytesNeeded, dwStartType;

  /* Need to acquire database lock before reconfiguring. */

  sclLock = LockServiceDatabase(schSCManager);

  /* If the database cannot be locked, report the details. */

  if (sclLock == NULL) {

      /* Exit if the database is not locked by another process. */

      if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED)

          MyErrorExit("LockServiceDatabase");

      /* Allocate a buffer to get details about the lock. */

      lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(

          LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256);

      if (lpqslsBuf == NULL)

          MyErrorExit("LocalAlloc");

      /* Get and print the lock status information. */

      if (! QueryServiceLockStatus(

          schSCManager,

          lpqslsBuf,

          sizeof(QUERY_SERVICE_LOCK_STATUS)+256,

          &dwBytesNeeded) )

          MyErrorExit("QueryServiceLockStatus");

      if (lpqslsBuf->fIsLocked)

          printf("Locked by: %s, duration: %d seconds\n",

              lpqslsBuf->lpLockOwner,

              lpqslsBuf->dwLockDuration);

      else

          printf("No longer locked\n");

      LocalFree(lpqslsBuf);

      MyErrorExit("Could not lock database");

  }

  /* The database is locked, so it is safe to make changes. */

  /* Open a handle to the service. */

  schService = OpenService(

       schSCManager,           /* SCManager database */

       TEXT("Sample_Srv"),     /* name of service    */

       SERVICE_CHANGE_CONFIG); /* need CHANGE access */

  if (schService == NULL)

      MyErrorExit("OpenService");

  dwStartType = (fDisable) ? SERVICE_DISABLED :

                             SERVICE_DEMAND_START;

  if (! ChangeServiceConfig(

       schService,        /* handle of service            */

       SERVICE_NO_CHANGE, /* service type: no change      */

       dwStartType,       /* *change* service start type  */

       SERVICE_NO_CHANGE, /* error control: no change     */

       NULL,              /* binary path: no change       */

       NULL,              /* load order group: no change  */

       NULL,              /* tag ID: no change            */

       NULL,              /* dependencies: no change      */

       NULL,              /* account name: no change      */

       NULL) )            /* password: no change          */

      MyErrorExit("ChangeServiceConfig");

  else

      printf("ChangeServiceConfig SUCCESS\n");

  /* Release the database lock. */

  UnlockServiceDatabase(sclLock);

  /* Close the handle to the service. */

  CloseServiceHandle(schService);

}


58.2.8  Querying a Services Configuration
  58.2.8  Querying a Service's Configuration

In the following example, a service configuration program uses the OpenService function to get a handle with SERVICE_QUERY_CONFIG access to an installed service object. Then the program uses the service object handle in the QueryServiceConfig function to retrieve the current configuration of the service.

VOID GetSampleServiceConfig() {

LPQUERY_SERVICE_CONFIG lpqscBuf;

DWORD dwBytesNeeded;

  /* Open a handle to the service. */

  schService = OpenService(

       schSCManager,           /* SCManager database  */

       TEXT("Sample_Srv"),     /* name of service     */

       SERVICE_QUERY_CONFIG);  /* need QUERY access   */

  if (schService == NULL)

      MyErrorExit("OpenService");

  /* Allocate a buffer for the information configuration. */

  lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(

                                       LPTR, 4096);

  if (lpqscBuf == NULL)

      MyErrorExit("LocalAlloc");

  /* Get and print the information configuration. */

  if (! QueryServiceConfig(

      schService,

      lpqscBuf,

      4096,

      &dwBytesNeeded) )

      MyErrorExit("QueryServiceConfig");

  printf("\nSample_Srv configuration: \n");

  printf("  Type: 0x%x\n", lpqscBuf->dwServiceType);

  printf("  Start Type: 0x%x\n", lpqscBuf->dwStartType);

  printf("  Err Control: 0x%x\n", lpqscBuf->dwErrorControl);

  printf("  Binary path: %s\n", lpqscBuf->lpBinaryPathName);

  if (lpqscBuf->lpLoadOrderGroup != NULL)

      printf("  Load order group: %s\n",

                 lpqscBuf->lpLoadOrderGroup);

  if (lpqscBuf->dwTagId != 0)

      printf("  Tag ID: %d\n", lpqscBuf->dwTagId);

  if (lpqscBuf->lpDependencies != NULL)

      printf("  Dependencies: %s\n", lpqscBuf->lpDependencies);

  if (lpqscBuf->lpServiceStartName != NULL)

      printf("  Start Name: %s\n",

                 lpqscBuf->lpServiceStartName);

  LocalFree(lpqscBuf);

}


  58.2.9  Starting a Service

To start a service, the following example opens a handle to an installed database and then specifies the handle in a call to the StartService function. StartService can be used to start either a Win32 service or a driver service, but this example assumes that a Win32 service is being started. After starting the service, the program uses the members of the SERVICE_STATUS structure returned by the QueryServiceStatus function to track the progress of the Win32 service.

VOID StartSampleService() {

SERVICE_STATUS ssStatus;

DWORD dwOldCheckPoint;

  schService = OpenService(

       schSCManager,          /* S. C. Manager database */

       TEXT("Sample_Srv"),    /* name of service        */

       SERVICE_ALL_ACCESS);

     //  SERVICE_START |        /* need START access  */

     //  SERVICE_QUERY_CONFIG); /* and QUERY access   */

  if (schService == NULL)

      MyErrorExit("OpenService");

  if (! StartService(schService, /* handle of service   */

            0,                   /* number of arguments */

            NULL) )              /* no arguments        */

      MyErrorExit("StartService");

  else

      printf("Service start pending\n");

  /* Check the status until the service is running. */

  if (! QueryServiceStatus(

      schService,   /* handle of service       */

      &ssStatus) )  /* address of status info  */

      MyErrorExit("QueryServiceStatus");

  while (ssStatus.dwCurrentState != SERVICE_RUNNING) {

      /* Save the current checkpoint. */

      dwOldCheckPoint = ssStatus.dwCheckPoint;

      /* Wait for the specified interval. */

      Sleep(ssStatus.dwWaitHint);

      /* Check the status again. */

      if (! QueryServiceStatus(

              schService,   /* handle of service       */

              &ssStatus) )  /* address of status info  */

          break;

      /* Break if the checkpoint has not been incremented. */

      if (dwOldCheckPoint >= ssStatus.dwCheckPoint)

          break;

  }

  if (ssStatus.dwCurrentState == SERVICE_RUNNING)

      printf("StartService SUCCESS\n");

  else {

      printf("\nService not started: \n");

      printf("  Current State: %d\n",

                   ssStatus.dwCurrentState);

      printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode);

      printf("  Service Specific Exit Code: %d\n",

                   ssStatus.dwServiceSpecificExitCode);

      printf("  Check Point: %d\n", ssStatus.dwCheckPoint);

      printf("  Wait Hint: %d\n", ssStatus.dwWaitHint);

  }

  CloseServiceHandle(schService);

}


  58.2.10  Sending Control Requests to a Service

The following example uses the ControlService function to send a control code to a running service. Different control codes require different levels of access to the service object. For example, a service object handle must have SERVICE_STOP access to send the SERVICE_CONTROL_STOP code. When ControlService returns, a SERVICE_STATUS structure contains the latest status information for the service.

VOID ControlSampleService(DWORD fdwControl) {

SERVICE_STATUS ssStatus;

DWORD fdwAccess;

  /* The required service object access depends on the control. */

  switch (fdwControl) {

      case SERVICE_CONTROL_STOP:

          fdwAccess = SERVICE_STOP;

          break;

      case SERVICE_CONTROL_PAUSE:

      case SERVICE_CONTROL_CONTINUE:

          fdwAccess = SERVICE_PAUSE_CONTINUE;

          break;

      case SERVICE_CONTROL_INTERROGATE:

          fdwAccess = SERVICE_INTERROGATE;

          break;

      default:

          fdwAccess = SERVICE_INTERROGATE;

  }

  /* Open a handle to the service. */

  schService = OpenService(

       schSCManager,        /* SCManager database */

       TEXT("Sample_Srv"),  /* name of service    */

       fdwAccess);          /* specify access     */

  if (schService == NULL)

      MyErrorExit("OpenService");

  /* Send a control code to the service. */

  if (! ControlService(

      schService,   /* handle of service       */

      fdwControl,   /* control code to send    */

      &ssStatus) )  /* address of status info  */

      MyErrorExit("ControlService");

  /* Print the service status. */

  printf("\nStatus of Sample_Srv: \n");

  printf("  Service Type: 0x%x\n", ssStatus.dwServiceType);

  printf("  Current State: 0x%x\n", ssStatus.dwCurrentState);

  printf("  Controls Accepted: 0x%x\n",

               ssStatus.dwControlsAccepted);

  printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode);

  printf("  Service Specific Exit Code: %d\n",

               ssStatus.dwServiceSpecificExitCode);

  printf("  Check Point: %d\n", ssStatus.dwCheckPoint);

  printf("  Wait Hint: %d\n", ssStatus.dwWaitHint);

  return;

}


  58.3  Functions

Following are the Win32 functions used by services and by programs that control or configure services:

ChangeServiceConfig
CloseServiceHandle
ControlService
CreateService
DeleteService
EnumDependentServices
EnumServicesStatus
Handler
LockServiceDatabase
OpenSCManager
OpenService
QueryServiceConfig
QueryServiceLockStatus
QueryServiceObjectSecurity
QueryServiceStatus
RegisterServiceCtrlHandler
ServiceMain
SetServiceObjectSecurity
SetServiceStatus
StartService
StartServiceCtrlDispatcher
UnlockServiceDatabase


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Tape Backup
  Chapter 59    Tape Backup

59.1  About Tape Backup

In Microsoft Windows, a tape volume consists of a recording medium and its physical carrier. The entire length of tape in a volume is not available for recording data. Short sections at the beginning and the end of the tape are reserved for attaching the tape to the hubs in the carrier. The first position on the tape where data can be recorded is the called the beginning-of-medium marker, and the last position is called the end-of-medium marker.

Every tape volume has one or more partitions. A partition is a portion of the volume, with its own beginning and ending points that does not overlap with any other portion of the volume. Each partition has three predefined positions. The first position in a partition  you can record data is called the beginning-of-partition marker, and the last is called end-of-partition marker. The early-warning position is located immediately before the end-of-partition.The early-warning position notifies type applications to transfer buffered data to the tape before reaching the end-of-partition.

The area between a partition's beginning and ending points is typically divided into sections by filemarks or setmarks. Filemarks and setmarks are special recorded elements that do not contain user data, but simply divide the partition into smaller areas to provide an address scheme. Filemarks and setmarks serve similar purposes, but setmarks provide faster positioning on high-capacity tape drives.

Typically, tape devices support filemarks and setmarks. This enables tape data to be formatted such that a filemark separates data from different disk volumes and setmarks separate data from individual files on a disk volume.

Another recorded element that denotes locations on the tape is an erase gap, an area of erased tape or a pattern that the device does not recognize as a mark or as user data.

There are three types of filemarks. A short filemark contains a short erase gap that cannot be overwritten unless the write operation is performed from the beginning of the partition or from an earlier long filemark. A long filemark contains a long erase gap that enables an application to position the tape at the beginning of the filemark and to overwrite the filemark and the erase gap. A normal filemark does not contain an erase gap. Tape devices that use filemarks support either short and long filemarks or normal filemarks, but not all three.

The area on a partition between setmarks or filemarks is available for recording data. The unit of data written to or read from a tape is referred to as a block.

The tape functions provided in the Win32 application programming interface (API) enable backup applications to read from and write to a tape, initialize a tape, and retrieve tape or tape drive information.


  59.1.1  Tape Initialization

An application must use the CreateFile function to create a handle of a tape device. This handle is used in subsequent operations on the tape in the device.

Before an application writes to a tape, the tape must be formatted according to the needs of the application and the capabilities of the tape drive being used. The CreateTapePartition function reformats a tape, creating on it a specified number of partitions of a specified size.

The PrepareTape function prepares a tape to be accessed or removed. This function can load, unload, lock, or unlock a tape. This function can also tension the tape by moving the tape to the end-of-medium and back to the beginning-of-medium.

To retrieve and set information about an application tape and tape drive, an application uses the GetTapeParameters, SetTapeParameters, and GetTapeStatus functions.

GetTapeParameters retrieves information that describes a tape or a tape drive. The tape information includes the tape's type, density, and block size, the number of partitions on the tape, the amount of tape remaining, and so on. The tape drive information includes the drive's default block size, the maximum partition count, and the features that are supported.

SetTapeParameters either sets the tape block size or sets the tape drive flags that indicate whether the drive supports hardware error correction, data compression, or data padding, or any combination of the three.

GetTapeStatus indicates whether the tape drive is ready to process tape commands.


  59.1.2  Tape Input and Output

The Win32 API provides several functions that applications can use to perform input and output (I/O) on a tape drive. Tape I/O is similar to I/O performed on a communications device.

The GetTapePosition and SetTapePosition functions retrieve and move the current tape position. The WriteTapemark function writes a specified number of setmarks, filemarks, short filemarks, and long filemarks. The EraseTape function erases all or part of a tape.

The ReadFile and WriteFile functions read and write file data from and to the tape. The data is read and written in complete blocks. If the tape's block size is 512 bytes, all read and write operations must use 512-byte buffers.

If ReadFile encounters a filemark, the data up to the filemark is read and the function fails. (The GetLastError function returns an error code indicating the type of filemark that was encountered.) To continue reading beyond the filemark, the application must move the tape past the filemark and call ReadFile again.

ReadFile and WriteFile read and write only the data stream. The BackupRead and BackupWrite functions read and write all the streams associated with a file. These include data, extended attributes, security, and alternative data streams. The security and alternate data streams are relevant only on the new technology file system (NTFS) partition.

The BackupSeek function seeks forward in a file being accessed by BackupRead or BackupWrite. This enables an application to skip information that causes access errors.

If an application needs to access only the file data, it should use ReadFile and WriteFile. These functions can also read alternative data streams if the streams were created by using the CreateFile function.

A tape-backup application must use BackupRead and BackupWrite to copy all information pertaining to a file. However, these functions do not read or write file characteristics such as attributes, file creation time, and so on. Applications must use the file input and output functions, such as GetFileAttributes and SetFileAttributes, to query and set these values.


  59.2  Using Tape Backup

The most common use of the Win32 tape functions is to create a backup application. To perform any input or output on a tape, your application must first obtain a handle of the tape device. The following example shows how to use the CreateFile function to open a tape device.

HANDLE hTape;   /* handle to tape device */

hTape = CreateFile(

    "\\\\.\\TAPE0",     /* name of tape device to open */

    GENERIC_READ | GENERIC_WRITE, /* read-write access */

    0,                    /* not used                  */

    0,                    /* not used                  */

    OPEN_EXISTING,        /* required for tape devices */

    0,                    /* not used                  */

    NULL);                /* not used                  */

To back up a directory tree to a tape, your application must use the FindFirstFile and FindNextFile functions to traverse the directory tree. Each time a file is found, the application should get the file's attributes by using the GetFileAttributes function. If hard links, the application should determine the number of links and save the file's unique identifier in a table for future comparisons. The first time a file is found, the application should use CreateFile to open the file and the BackupRead function to begin the backup. Then, it can use the WriteFile function repeatedly to transfer all the information in the buffer filled by BackupRead to the tape. The second time a file is found (checked against the table of file identifiers when there are hard links), the application can simply write the general file information to the tape, followed by a stream whose identifier is BACKUP_LINK.

When restoring files from tape to disk, your application must use the CreateFile, BackupWrite, and ReadFile functions. For each file on the tape, the application should use CreateFile to create a new file on disk and BackupWrite to begin restoring the file. Then, it should use ReadFile repeatedly until all the information for the file has been read from the tape into the BackupWrite buffer. If one of the streams in the BackupWrite buffer has a BACKUP_LINK stream identifier, the application must establish a hard link. If the data to establish the link does not exist, BackupWrite fails. The application can use a preexisting catalog to locate and restore the original data, or it can notify the user that the file data to be restored is in a different location.


  59.3  Functions

Following are the functions used for tape backup.

BackupRead
BackupSeek
BackupWrite
CreateTapePartition
EraseTape
GetTapeParameters
GetTapePosition
GetTapeStatus
PrepareTape
SetTapeParameters
SetTapePosition
WriteTapemark


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Time
  Chapter 60    Time

60.1  About Date and Time Functions

The Microsoft Win32 application programming interface (API) represents time values in two formats. File time is a 64-bit value representing the number of 100-nanosecond intervals that have elapsed since January 1, 1601. System time is the "real-time" clock format. System time uses a structure containing individual members for the date and time.

The Win32 API also provides functions to manipulate two other time formats: MS-DOS date and time and Windows time.

The following sections describe these time formats and the functions that use them.


  60.1.1  File Times

A Win32 file time uses two 32-bit values as a combined 64-bit value to represent the number of 100-nanosecond intervals that have elapsed since January 1, 1601. File times are recorded in Coordinated Universal Time (UTC) format. The FileTimeToLocalFileTime function converts a UTC-based file time to local time, and the LocalFileTimeToFileTime function converts a local file time to a UTC file time.

Windows records file creation time, last access time, and last write time for each file. (Note that this capability depends on the underlying file system. The file allocation table [FAT] file system does not record creation or access times, but both the high-performance file system [HPFS] and the new technology file system [NTFS] do.) These times are retrieved in a WIN32_FIND_DATA structure containing FILETIME structures for creation, write, and access times. Writing to a file changes the last write time; writing to or reading from the file (including running an executable file) changes the last access time.

The SetFileTime function can be used to explicitly set the file times. The GetFileTime, FindFirstFile, and FindNextFile functions return file times as FILETIME structures.

The file time format is a convenient way to represent time internally, but the number of 100-nanosecond intervals elapsed since 1601 is usually not useful to a user. The FileTimeToSystemTime function converts a FILETIME structure to a SYSTEMTIME structure containing individual members for the month, day, year, weekday, hour, minute, second, and millisecond.

The CompareFileTime function compares two 64-bit file times and returns a value indicating which file time is greater. If the file times are equal, CompareFileTime returns zero.

For more information about files and file systems, see Chapter 45, »Files«, and Chapter 46, »File Systems«.


  60.1.2  System Times

A Win32 system time uses a SYSTEMTIME structure that contains separate member values for the year, month, day, hour, minute, second, and millisecond. This time format is used for the internal system time (the "real-time" clock). As with file times, the system time is kept in UTC format.

The internal system time is set automatically from the hardware clock when Windows starts running. The GetSystemTime function retrieves the system time, and the SetSystemTime function sets it.

Note   To set the system time, a process must have system time privilege. For information about acquiring this privilege, see Chapter 49, »Security«.

An application can also retrieve the current time in local time format (rather than UTC format) by using the GetLocalTime function. The SetLocalTime function sets the internal system time using a specified local time. The only difference between SetLocalTime and SetSystemTime (or between GetLocalTime and GetSystemTime) is the time format.

The conversion between UTC time and local time can be controlled by using the SetTimeZoneInformation function to set the current time-zone parameters. The GetTimeZoneInformation function retrieves the current time-zone settings.

The SystemTimeToFileTime function converts a SYSTEMTIME structure to a 64-bit FILETIME structure.

For compatibility with earlier versions of Windows, the Win32 API also supports the GetTickCount and GetCurrentTime functions. These functions return the time since Windows started running.


  60.1.3  MS-DOS Times

MS-DOS records file dates and times as packed 16-bit values. An MS-DOS date has the following format:

Bits	Contents
0−4	Day of the month (1−31)
5−8	Month (1 = January, 2 = February, etc.)
9−15	Year offset from 1980 (add 1980 to get actual year)
An MS-DOS time has the following format:

Bits	Contents
0−4	Second divided by 2
5−10	Minute (0−59)
11−15	Hour (0−23 on a 24-hour clock)
The DosDateTimeToFileTime function converts MS-DOS date and time values into filetime values. The FileTimeToDosDateTime function converts filetime values into MS-DOS date and time values.


  60.1.4  Windows Time

Windows keeps track of the number of milliseconds elapsed since it was started. This number is kept in a 32-bit value, so it can record 232 100-millisecond intervals before the 32-bit value overflows to zero. This is approximately 49.7 days.

The GetCurrentTime and GetTickCount functions both return the Windows time. These functions are provided primarily for compatibility with earlier versions of Windows.


  60.2  Using Date and Time Functions

This section explains how to perform the following tasks:

•	Set and retrieve file times

•	Set and retrieve the current system time

•	Convert a file time to real-time format


  60.2.1  Displaying File Creation Times in a Directory Listing

The following example displays a detailed directory of files in the current directory.

void main(void)

{

    HANDLE hSearch;

    WIN32_FIND_DATA ffd;

    /* Find the first file or indicate there are none. */

    hSearch = FindFirstFile("*.*", &ffd);

    if (hSearch == INVALID_HANDLE_VALUE)

        puts("no files");

    /* Display the header and process files until done. */

    else {

        printf("\nfile name         created");

        printf("           last written      size\n\n");

        PrintData(&ffd);

        while (FindNextFile(hSearch, &ffd))

            PrintData(&ffd);

    }

}

void PrintData(PWIN32_FIND_DATA pffd)

{

    FILETIME ft;

    SYSTEMTIME stCreate, stWrite;

    if (pffd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

        return;            /* don't display directories */

    /*

     * Convert creation and write times from UTC time to local time.

     * Convert creation and write times to system format.

     */

    FileTimeToLocalFileTime(&pffd->ftCreationTime, &ft);

    FileTimeToSystemTime(&ft, &stCreate);

    FileTimeToLocalFileTime(&pffd->ftLastWriteTime, &ft);

    FileTimeToSystemTime(&ft, &stWrite);

    /* Display the creation and write times. */

    printf("%-12s  %02d/%02d/%d  %02d:%02d",

            pffd->cFileName,

            stCreate.wDay, stCreate.wMonth, stCreate.wYear,

            stCreate.wHour, stCreate.wMinute);

    printf("   %02d/%02d/%d  %02d:%02d   %lu\n",

            stWrite.wDay, stWrite.wMonth, stWrite.wYear,

            stWrite.wHour, stWrite.wMinute, pffd->nFileSizeLow);

}


  60.2.2  Changing a File Time to the Current Time

The following example sets the creation time for a file to the current system time.

HANDLE hf;

FILETIME ft;

SYSTEMTIME st;

/* Open ftime.c for write access. */

hf = CreateFile("\\ftime.c", GENERIC_WRITE, 0,

        (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING,

        FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);

if (hf == INVALID_HANDLE_VALUE) {

    puts("Could not open ftime.c.");

    ExitProcess(1);

}

GetSystemTime(&st);             /* get current time            */

SystemTimeToFileTime(&st, &ft); /* convert to file time format */

SetFileTime(hf, &ft,            /* set creation time for file  */

    (LPFILETIME)NULL, (LPFILETIME)NULL);


  60.2.3  Setting the System Time

The following example enables the user to set the system time.

static char *aszDay[] =  { "Sunday", "Monday", "Tuesday",

        "Wednesday", "Thursday", "Friday", "Saturday" };

void _cdecl main(void)

{

    HANDLE hToken;

    SYSTEMTIME st;

    char szTime[25], *pc;

    TOKEN_PRIVILEGES tkp;

    GetSystemTime(&st);  /* get the current time          */

    ShowTime(&st);       /* display the current time      */

    for (;;) {           /* get the new time in hh:mm format */

        printf("Enter new time: ");

        gets(szTime);

        if ((pc = strchr(szTime, ':')) != NULL) {

            *pc = '\0';

            st.wHour = (WORD)atoi(szTime);

            st.wMinute = (WORD)atoi(pc + 1);

            break;

        }

        else {

            puts("Time must be in hh:mm format:");

        }

    }

    /* Get the current process token handle */

    /* so we can get set-time privilege.    */

    if (!OpenProcessToken(GetCurrentProcess(),

            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

        error("OpenProcessToken");

    /* Get the LUID for system-time privilege. */

    LookupPrivilegeValue(NULL, "SE_SYSTEMTIME_NAME",

            &tkp.Privileges[0].Luid);

    tkp.PrivilegeCount = 1;  /* one privilege to set      */

    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    /* Get set-time privilege for this process. */

    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES) NULL, 0);

    /* Cannot test return value of AdjustTokenPrivileges. */

    if (GetLastError() != ERROR_SUCCESS)

        error("AdjustTokenPrivileges enable");

    if (!SetSystemTime(&st))       /* set the system time */

        error("SetSystemTime");

    ShowTime(&st);

    /* Now disable set-time privilege. */

    tkp.Privileges[0].Attributes = 0;

    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES) NULL, 0);

    if (GetLastError() != ERROR_SUCCESS)

        error("AdjustTokenPrivileges disable");

}

void error(LPSTR lpszFunction)

{

    DWORD dw = GetLastError();

    printf("%s failed: GetLastError returned %u\n",

        lpszFunction, dw);

    ExitProcess(dw);

}

void ShowTime(PSYSTEMTIME pst)

{

    printf("It is now %02u:%02u:%02u on %s, %02u/%02u/%4u.\n",

        pst->wHour, pst->wMinute, pst->wSecond,

        aszDay[pst->wDayOfWeek], pst->wMonth,

        pst->wDay, pst->wYear);

}


  60.3  Functions

Following are the functions used with date and time formats.

CompareFileTime
DosDateTimeToFileTime
FileTimeToDosDateTime
FileTimeToLocalFileTime
FileTimeToSystemTime
GetCurrentTime
GetFileTime
GetLocalTime
GetSystemTime
GetTickCount
GetTimeZoneInformation
LocalFileTimeToFileTime
SetFileTime
SetLocalTime
SetSystemTime
SetTimeZoneInformation
SystemTimeToFileTime


Atoms
  Chapter 61    Atoms

61.1  About Atom Tables

In the Microsoft Win32 application programming interface (API) an atom table is a system-defined table that stores strings and corresponding identifiers. An application places a string in an atom table and receives a 16-bit integer, called an atom, that can be used to access the string. A string that has been placed in an atom table is called an atom name.

Dynamic data exchange (DDE) applications use an atom table to share item-name and topic-name strings with other applications. Instead of passing actual strings, a DDE application passes atoms to its partner application. The partner uses the atoms to obtain the strings from the atom table.


  61.1.1  Global Atom Table

The Windows global atom table, which can contain up to 37 entries, is available to all applications. When an application places a string in the global atom table, the system generates an atom that is unique throughout the system. Any application that has the atom can obtain the string it identifies by querying the global atom table.

An application that defines a private clipboard-data format or DDE-data format for sharing data with other applications should place the format name in the global atom table. This technique prevents conflicts with the names of formats defined by the system or by other applications, and makes the identifiers (atoms) for the messages or formats available to the other applications.


  61.1.2  Local Atom Tables

An application can use a local atom table to efficiently manage a large number of strings used only within the application. These strings, and the associated atoms, are available only to the application that created the table.

An application requiring the same string in a number of structures can reduce memory usage by using a local atom table. Rather than copying the string into each structure, the application can place the string in the atom table and include the resulting atom in the structures. In this way, a string appears only once in memory but can be used many times in the application.

Applications can also use local atom tables to save time when searching for a particular string. To perform a search, an application need only place the search string in the atom table and compare the resulting atom with the atoms in the relevant structures. Comparing atoms is typically faster than comparing strings.

By default, a local atom table can contain up to 37 entries. However, unlike the size of a global atom table, the size of a local atom table can be changed. An application uses the InitAtomTable function to accomplish this task. If the application calls InitAtomTable, however, it must do so before calling any other atom-management function.


  61.1.3  Atom Types

Applications can use two types of atoms: string and integer. The following sections describe these types.


  61.1.3.1  String Atoms

Applications pass null-terminated strings to atom tables and receive string atoms (16-bit integers) in return. String atoms have the following properties:

•	The values of string atoms are in the range 0xC000 through 0xFFFF.

•	Case is not significant in searches for an atom name in an atom table. Also, the entire string must match in a search operation; no substring matching is performed.

•	A reference count is associated with each atom name. The count is incremented each time the atom name is added to the table and decremented each time the atom name is deleted from it. This prevents different users of the same string atom from destroying each other's atom names. When the reference count for an atom name equals zero, the system removes the atom and the atom name from the table.


  61.1.3.2  Integer Atoms

Integer atoms differ from string atoms in the following ways:

•	The values of integer atoms are in the range 0x0001 through 0xBFFF. The values of integer atoms and string atoms do not overlap, so both types of atoms can be used in the same block of code.

•	The string representation of an integer atom is #dddd, where the values represented by dddd are decimal digits. Leading zeros are ignored.

•	There is no reference count or storage overhead associated with an integer atom.

Several Windows functions accept either string or integer atoms as parameters. When passing an integer atom to these functions, an application must use the MAKEINTATOM macro to create the atom. For information about the MAKEINTATOM macro, see the Microsoft Win32 Programmer's Reference, Volume 5.


  61.1.4  Atom Creation and Usage Count

An application creates a local atom by calling the AddAtom function; it creates a global atom by calling the GlobalAddAtom function. Both functions require a pointer to a string. The system searches the appropriate atom table for the string and returns the corresponding atom to the application. In the case of a string atom, if the string already resides in the atom table, the system increments the reference count for the string during this process.

Repeated calls to add the same atom name return the same atom. If the atom name does not exist in the table when AddAtom is called, the atom name is added to the table and a new atom is returned. If it is a string atom, its reference count is also set to one.

An application should call the DeleteAtom function when it no longer needs to use a local atom; it should call the GlobalDeleteAtom function when it no longer needs a global atom. In the case of a string atom, either of these functions reduces the reference count of the corresponding atom by one. When the reference count reaches zero, the system deletes the atom name from the table.

The atom name of a string atom remains in the global atom table as long as its reference count is greater than zero, even after the application that placed it in the table terminates. A local atom table is destroyed when the associated application terminates, regardless of the reference counts of the atoms in the table.


  61.1.5  Atom-Table Queries

An application can determine whether a particular string is already in an atom table by using the FindAtom or GlobalFindAtom function. These functions search an atom table for the specified string and, if the string is there, return the corresponding atom.

An application can use the GetAtomName or GlobalGetAtomName function to retrieve an atom-name string from an atom table, provided the application has the atom corresponding to the string sought. Both functions copy the atom-name string of the specified atom to a buffer and return the length of the string that was copied. GetAtomName retrieves an atom-name string from a local atom table, and GlobalGetAtomName retrieves an atom-name string from the global atom table.


  61.1.6  Atom String Formats

The AddAtom, GlobalAddAtom, FindAtom, and GlobalFindAtom functions take a pointer to a null-terminated string. An application can specify this pointer in one of the following ways.

Format	Description
#dddd	An integer specified as a decimal string. Used to create or find an integer atom.
string atom name	A string atom name. Used to add a string atom name to an atom table and receive an atom in return.


  61.2  Using Atoms

The most typical use for atoms is in dynamic data exchange (DDE) applications. In the DDE protocol, applications use global atoms to identify the applications exchanging data, the nature of the data being exchanged, and the actual data items being exchanged. For more information about DDE and for examples that show how to use atoms, see the Microsoft Win32 Programmer's Reference, Volume 1, Chapter 26, "Dynamic Data Exchange."


  61.3  Functions

Following are the functions associated with atoms.

AddAtom
DeleteAtom
FindAtom
GetAtomName
GlobalAddAtom
GlobalDeleteAtom
GlobalFindAtom
GlobalGetAtomName
InitAtomTable
GetAtomHandle (Obsolete)


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Debugging
  Chapter 62    Debugging

62.1  About Debugging Support

A debugger is an application that enables a developer to observe and correct programming errors. Microsoft Windows NT supports several functions that can be used to create a basic, event-driven debugger. "Event-driven" means that the debugger is notified every time certain events occur in the process being debugged. Notification enables the debugger to take appropriate action in response to the events.

The first section of this chapter describes the debugging-specific features of certain standard Windows NT functions — specifically, process, thread, and exception-handling functions.

The second section of this chapter describes the Windows NT debugging functions. These functions enable an application to wait for debugging events, cause breakpoint exceptions, transfer execution control to the debugger, and so on.


  62.1.1  Support from Process, Thread, and Exception Functions

Some functions essential to debugging are actually part of the process, thread, or exception-handling architectures. This section describes how to start a process that is going to be debugged and how to examine and manipulate the context and execution of a thread. It also describes how a debugger should handle exceptions.


  62.1.1.1  Process Functions

The CreateProcess function enables a debugger to start a process and debug it. The fdwCreate parameter of CreateProcess is used to specify the type of debugging operation. If the DEBUG_PROCESS flag is specified for the parameter, a debugger debugs the new process and all of the process's descendants, provided that the descendants are created without the DEBUG_PROCESS flag set.

If the DEBUG_PROCESS and DEBUG_ONLY_THIS_PROCESS flags are specified for fdwCreate, a debugger debugs the new process but none of its descendants.

One debugger can debug another by creating a process with the DEBUG_PROCESS flag set. The new process (the debugger being debugged) must then create a process with the DEBUG_PROCESS flag set.

The OpenProcess function enables a debugger to obtain the identifier of an existing process. (The DebugActiveProcess function uses this identifier to attach

the debugger to the process.) Typically, debuggers open a process with the PROCESS_VM_READ and PROCESS_VM_WRITE flags set. Using these flags enables the debugger to read from and write to the virtual memory of the process by using the ReadProcessMemory and WriteProcessMemory functions. For more information about processes, see Chapter 43, »Processes and Threads«.


  62.1.1.2  Thread Functions

The CreateThread function creates a new thread for a process. Debuggers typically need to examine or change the contents of a thread's registers. To accomplish this, a debugger must obtain a handle of the thread by using the DuplicateHandle function and specifying the appropriate access to the thread (THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, or both).

A process with appropriate access to a thread can examine the thread's registers by using the GetThreadContext function and set the contents of the thread's registers by using the SetThreadContext function.

A process can also obtain THREAD_SUSPEND_RESUME access to a thread. This enables a debugger to control a thread's execution with the SuspendThread and ResumeThread functions. For more information about threads, see Chapter 43, »Processes and Threads«.


  62.1.1.3  Exception Handling

When an exception occurs in a process that is being debugged, the kernel notifies the debugger by passing the exception to it. This is known as first-chance notification. The kernel then suspends all threads in the process being debugged.

If the debugger does not handle the exception, the kernel attempts to locate an appropriate exception handler. If the kernel cannot locate an appropriate one, the kernel again notifies the debugger that an exception has occurred. This is known as last-chance notification. If the debugger does not handle the exception after the last-chance notification, the kernel terminates the process being debugged.

For more information about exception handling, see Chapter 64, »Structured Exception Handling«.


  62.1.2  Debugging Functions

Although most of the Windows NT debugging functions are used to create a debugger, several functions are designed for use in the process being debugged.

To start a process and debug it, a debugger must use CreateProcess, as described in the previous section.

To debug a process that is already executing, the debugger should use DebugActiveProcess with the process identifier retrieved by OpenProcess. DebugActiveProcess attaches the debugger to the active process. In this case, only the active process can be debugged; its descendants cannot. The debugger must have appropriate access to the executing process to use DebugActiveProcess. For more information about access rights, see Chapter 49, »Security«.

After the debugger has either created or attached itself to the process it intends to debug, the kernel notifies the debugger of all debugging events that occur in the process, and, if specified, in the process's descendants. For more information about debugging events, see Section 62.1.2.2, »Debugging Events«.

The debugger uses the WaitForDebugEvent function at the beginning of its main loop. This function blocks the debugger until a debugging event occurs. When the debugging event occurs, the kernel suspends all threads in the process being debugged and notifies the debugger of the event. The debugger can interact with the user, or manipulate the state of the process being debugged, by using the FlushInstructionCache, GetThreadContext, GetThreadSelectorEntry, ReadProcessMemory, SetThreadContext, and WriteProcessMemory functions.

GetThreadSelectorEntry returns the descriptor table entry for a specified selector and thread. Debuggers use the descriptor table entry to convert a segment-relative address to a linear virtual address. The ReadProcessMemory and WriteProcessMemory functions require linear virtual addresses.

Debuggers frequently read the memory of the process being debugged and write the memory that contains instructions to the instruction cache. After the instructions are written, the debugger calls FlushInstructionCache to execute the cached instructions.

The debugger uses the ContinueDebugEvent function at the end of its main loop. This function allows the process being debugged to continue executing.


  62.1.2.1  Communicating with the Debugger

The OutputDebugString function sends a string from the process being debugged to the debugger by generating an OUTPUT_DEBUG_STRING_EVENT debugging event.

The DebugBreak function causes a breakpoint exception in the current process. A breakpoint is a location in a program where execution is stopped to allow the developer to examine the program's code, variables, and register values, and, as necessary, to make changes, continue execution, or terminate execution.

The FatalExit function terminates the current process and gives execution control to the debugger, but unlike DebugBreak, does not generate an exception. This function should only be used as a last resort, because it does not always free the process's memory or close its files.


  62.1.2.2  Debugging Events

A debugging event is an incident in the process being debugged that causes the kernel to notify the debugger. Debugging events include creating a process, creating a thread, loading a dynamic-link library (DLL), unloading a DLL, sending an output string, and generating an exception.

If a debugging event occurs while a debugger is waiting for one, the kernel fills the DEBUG_EVENT structure specified by WaitForDebugEvent with information describing the event.

When the kernel notifies the debugger of a debugging event, it also suspends all threads in the affected process. The threads do not resume execution until the debugger continues the debugging event by using ContinueDebugEvent. The following debugging events may occur while a process is being debugged.

Debugging event	Description
CREATE_PROCESS_DEBUG_EVENT
	Generated whenever a new process is created in a process being debugged or whenever the debugger begins debugging an already active process. The kernel generates this debugging event before the process begins to execute in user mode and before the kernel generates any other debugging events for the new process.
	The DEBUG_EVENT structure contains a CREATE_PROCESS_DEBUG_INFO structure. This structure includes a handle of the new process, a handle of the process's image file, a handle of the process's initial thread, and other information that describes the new process.
	The handle of the process has PROCESS_VM_READ and PROCESS_VM_WRITE access. If a debugger has these types of access to a thread, it can read and write to the process's memory by using the ReadProcessMemory and WriteProcessMemory functions.
	The handle of the process's image file has GENERIC_READ access and is opened for read-sharing.
	The handle of the process's initial thread has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread. If a debugger has these types of access to a thread, it can read from and write the thread's registers by using the GetThreadContext and SetThreadContext functions and can suspend and resume the thread by using the SuspendThread and ResumeThread functions.
CREATE_THREAD_DEBUG_EVENT
	Generated whenever a new thread is created in a process being debugged or whenever the debugger begins debugging an already active process. This debugging event is generated before the new thread begins to execute in user mode.
	The DEBUG_EVENT structure contains a CREATE_THREAD_DEBUG_INFO structure. This structure includes a handle of the new thread and the thread's starting address. The handle has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread. If a debugger has these types of access to a thread, it can read from and write to the thread's registers by using the GetThreadContext and SetThreadContext functions and can suspend and resume the thread by using the SuspendThread and ResumeThread functions.
EXCEPTION_DEBUG_EVENT
	Generated whenever an exception occurs in the process being debugged. Possible exceptions include attempting to access inaccessible memory, executing breakpoint instructions, attempting to divide by zero, or any other exception noted in Chapter 64, »Structured Exception Handling«.
	The DEBUG_EVENT structure contains an EXCEPTION_DEBUG_INFO structure. This structure describes the exception that caused the debugging event.
	In addition to the standard exception conditions, an additional software exception signals the debugger. The kernel generates a DBG_CONTROL_C exception code whenever a character-mode process encounters a CTRL+C, if the process uses the default CTRL+C handling mechanism.
EXIT_PROCESS_DEBUG_EVENT
	Generated whenever the last thread in a process being debugged exits. This debugging event occurs immediately after the kernel unloads the process's dynamic-link libraries (DLLs) and updates the process's exit code.
	The DEBUG_EVENT structure contains an EXIT_PROCESS_DEBUG_INFO structure that specifies the exit code.
	The debugger deallocates any internal structures associated with the process on receipt of this debugging event. The kernel closes the debugger's handle of the exiting process and all of the process's threads.
EXIT_THREAD_DEBUG_EVENT
	Generated whenever a thread that is part of a process being debugged exits. The kernel generates this debugging event immediately after it updates the thread's exit code.
	The DEBUG_EVENT structure contains an EXIT_THREAD_DEBUG_INFO structure that specifies the exit code.
	The debugger deallocates any internal structures associated with the thread on receipt of this debugging event. The system closes the debugger's handle of the exiting thread.
	This debugging event does not occur if the exiting thread is the last thread of a process. In this case, the EXIT_PROCESS_DEBUG_EVENT debugging event occurs instead.
LOAD_DLL_DEBUG_EVENT
	Generated whenever a process being debugged loads a DLL. This debugging event occurs when the system loader resolves links to a DLL or when the debugged process uses the LoadLibrary function. This debugging event only occurs the first time the kernel attaches a DLL to the virtual address space of a process.
	The DEBUG_EVENT structure contains a LOAD_DLL_DEBUG_INFO structure. This structure includes a handle of the newly loaded DLL, the base address of the DLL, and other information that describes the DLL.
	Typically, a debugger loads a symbol table associated with the DLL on receipt of this debugging event.
OUTPUT_DEBUG_STRING_EVENT
	Generated when a process being debugged uses the OutputDebugString function.
	The DEBUG_EVENT structure contains an OUTPUT_DEBUG_STRING_INFO structure. This structure specifies the address, length, and format of the debugging string.
UNLOAD_DLL_DEBUG_EVENT
	Generated whenever a process being debugged unloads a DLL by using the FreeLibrary function. This debugging event only occurs the last time a DLL is unloaded from a process's address space (that is, when the DLL's usage count is zero).
	The DEBUG_EVENT structure contains an UNLOAD_DLL_DEBUG_INFO structure. This structure specifies the base address of the DLL in the address space of the process that unloads the DLL.
	Typically, a debugger unloads a symbol table associated with the DLL on receipt of this debugging event.
	When a process exits, the kernel automatically unloads the process's DLLs, but does not generate an UNLOAD_DLL_DEBUG_EVENT debugging event.


  62.2  Using Debugging Support

The following example uses the WaitForDebugEvent and ContinueDebugEvent functions to illustrate how a simple debugger might be organized.

DEBUG_EVENT DebugEv;                   /* debugging event info.  */

DWORD dwContinueStatus = DBG_CONTINUE; /* exception continuation */

for(;;) {

 /*

  * Wait for a debugging event to occur. The second parameter

  * indicates that the function does not return until

  * a debugging event occurs.

  */

WaitForDebugEvent(&DebugEv, INFINITE);

  /* Process the debugging event code. */

  switch (DebugEv.dwDebugEventCode) {

    case EXCEPTION_DEBUG_EVENT:

      /*

       * Process the exception code. When handling

       * exceptions, remember to set the continuation

       * status parameter (dwContinueStatus). This value

       * is used by the ContinueDebugEvent function.

       */

      switch (DebugEv.u.Exception.ExceptionRecord.ExceptionCode) {

          case EXCEPTION_ACCESS_VIOLATION:

                 /*

                  * First chance: Pass this on to the kernel.

                  * Last chance: Display an appropriate error.

                  */

          case EXCEPTION_BREAKPOINT:

                 /*

                  * First chance: Display the current

                  * instruction and register values.

                  */

          case EXCEPTION_DATATYPE_MISALIGNMENT:

                 /*

                  * First chance: Pass this on to the kernel.

                  * Last chance: Display an appropriate error.

                  */

          case EXCEPTION_SINGLE_STEP:

                 /*

                  * First chance: Update the display of the

                  * current instruction and register values.

                  */

          case DBG_CONTROL_C:

                 /*

                  * First chance: Pass this on to the kernel.

                  * Last chance: Display an appropriate error.

                  */

          /* Handle other exceptions. */

      }

    case CREATE_THREAD_DEBUG_EVENT:

           /*

            * As needed, examine or change the thread's registers

            * with the GetThreadContext and SetThreadContext

            * functions; suspend and resume thread execution with

            * the SuspendThread and ResumeThread functions.

            */

    case CREATE_PROCESS_DEBUG_EVENT:

           /*

            * As needed, examine or change the registers of the

            * process's initial thread with the GetThreadContext

            * and SetThreadContext functions; read from and write

            * to the process's virtual memory with the

            * ReadProcessMemory and WriteProcessMemory functions;

            * and suspend and resume thread execution with the

            * SuspendThread and ResumeThread functions.

            */

    case EXIT_THREAD_DEBUG_EVENT:

           /* Display the thread's exit code. */

    case EXIT_PROCESS_DEBUG_EVENT:

           /* Display the process's exit code. */

    case LOAD_DLL_DEBUG_EVENT:

           /*

            * Read the debugging information included

            * in the newly loaded DLL.

            */

    case UNLOAD_DLL_DEBUG_EVENT:

           /*

            * Display a message that the DLL has

            * been unloaded.

            */

    case OUTPUT_DEBUG_STRING_EVENT:

           /* Display the output debugging string. */

  }

/* Resume executing the thread that reported the debugging event. */

ContinueDebugEvent(DebugEv.dwProcessId,

    DebugEv.dwThreadId, dwContinueStatus);

}


  62.3  Functions

Following are the functions that support debugging:

ContinueDebugEvent
DebugActiveProcess
DebugBreak
FatalAppExit
FatalExit
FlushInstructionCache
GetThreadContext
GetThreadSelectorEntry
OutputDebugString
ReadProcessMemory
SetDebugErrorLevel
SetThreadContext
WaitForDebugEvent
WriteProcessMemory


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Errors
  Chapter 63    Errors

63.1  About Errors

Well-written applications include code that allows them to recover gracefully from unexpected errors. When an error occurs, the application may need to request user intervention, or it may be able to recover without help. In extreme cases, the application may log the user off or shut down the system.

Microsoft Windows NT includes a special error-handling mechanism for exceptions, such as divide-by-zero errors. For more information about exception handling, see Chapter 64, »Structured Exception Handling«.


  63.1.1  Notifying the User

To notify the user that some kind of error has occurred, many applications simply produce a sound by using the Beep or MessageBeep function or flash the window by using the FlashWindow function. An application can also use these functions to call attention to an error and then display a message box or an error message containing details about the error.


  63.1.2  Logging Off or Shutting Down

An application can use the ExitWindows function to log the current user off. The ExitWindowsEx function can also do any of the following:

•	Shut down the system

•	Shut down the system and restart it

•	Log off and force all running applications to terminate

Logging off stops all processes associated with the security context of the process that called the exit function, logs the user off the system, and displays the Logon dialog box.

Shutting down brings the system to a condition in which it is safe to turn the computer off. All file-system buffers are flushed to the disk, and a message box is displayed informing the user that the computer can be turned off. If the reboot option is specified, the computer restarts.

The calling process must have the SE_SHUTDOWN_NAME privilege to shut down, or to shut down and restart. For an example that enables this privilege and shuts down the system, see Section 63.2.3, »Shutting Down«.


  63.1.3  Last-Error Code

When an error occurs, most functions in the Win32 application programming interface (API) return an error code, usually FALSE, NULL, 0xFFFFFFFF, or −1. Most functions in the Win32 application programming interface (API) also set an internal error code called the last-error code. When a function succeeds, the last-error code is not reset. The error code is maintained separately for each running thread; an error in one thread does not overwrite the last-error code in another thread. An application can retrieve the last-error code by using the GetLastError function; the error code may tell more about what actually occurred to make the function fail.

The SetLastError function sets the error code for the current thread. The SetLastErrorEx function also allows the caller to set an error type indicating the severity of the error. These functions are intended primarily for dynamic-link libraries (DLLs), so that they can emulate the behavior of the Win32 API.

The Win32 API defines a set of error codes that can be set as last-error codes or returned by these functions. A list of these error code appears in Appendix A, »Error Codes«.

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no Win32 API error code has this bit set. Developers who define an error code for an application should set this bit to indicate that the error code has been defined by an application and to ensure that the error code does not conflict with any system-defined error codes.


  63.1.4  Error Message Boxes

Some errors, such as a drive-not-ready error (when the door of the floppy disk drive is open), cause Windows NT to display a message box informing the user that an error has occurred. Applications that handle these errors without user intervention can use the SetErrorMode function to suppress error message boxes.


  63.2  Using Errors

This section contains examples that show how to perform the following tasks:

•	Flash a window, make a sound, and display an error message box

•	Log the current user off

•	Shut down the system and restart it

•	Get the last-error code after a Win32 API failure


  63.2.1  Notifying the User

The following example flashes a window, plays the system exclamation sound, and displays a message box.

FlashWindow(hwnd, TRUE); /* invert the title bar   */

Sleep(500);              /* wait a bit             */

FlashWindow(hwnd, TRUE); /* invert again           */

/* Play the system exclamation sound. */

MessageBeep(MB_ICONEXCLAMATION);


  63.2.2  Logging Off

The ExitWindows function logs the current user off. All applications must agree to terminate before the user logs off. If any application returns FALSE when it processes the WM_QUERYENDSESSION message, the user is not logged off. If your application handles the WM_QUERYENDSESSION message, you can allow the user to cancel the log-off operation, even if another application or Windows originated the end-session request.

The following example logs off the current user, unless the user selects the No button in the message box displayed when the application receives the WM_QUERYENDSESSION message.

            ExitWindows(0, 0); /* log the current user off    */

case WM_QUERYENDSESSION:  /* in application's MainWndProc */

{

    int i  = MessageBox(NULL, "Shutdown?",

       "Received WM_QUERYENDSESSION", MB_YESNO);

    /*

     * Return TRUE to allow shutdown, FALSE to stop.

     */

    return i == IDYES;

    break;

}


  63.2.3  Shutting Down

The ExitWindowsEx function can be used to shut down the system. Shutting down flushes file buffers to disk and brings the system to a condition in which it is safe to turn the computer off. The calling process must have the SE_SHUTDOWN_NAME privilege to shut down the system.

The following example enables the SE_SHUTDOWN_NAME privilege and then shuts down the system.

HANDLE hToken;

TOKEN_PRIVILEGES tkp;

/* Get a token for this process. */

if (!OpenProcessToken(GetCurrentProcess(),

        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

    error("OpenProcessToken");

/* Get the LUID for shutdown privilege. */

LookupPrivilegeValue(NULL, TEXT("SE_SHUTDOWN_NAME"),

        &tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;  /* one privilege to set    */

tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

/* Get shutdown privilege for this process. */

AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES)NULL, 0);

/* Cannot test the return value of AdjustTokenPrivileges. */

if (GetLastError() != ERROR_SUCCESS)

    error("AdjustTokenPrivileges");

/* Shut down the system and force all applications to close. */

if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0))

    error("ExitWindowsEx");

For more information about setting security privileges, see Chapter 49, »Security«.


  63.2.4  Retrieving the Last-Error Code

When a function in the Win32 API fails, it sets the last-error code. If your application needs more details about an error, it can retrieve the last-error code.

The following example shows an error-handling function used by the other examples in this chapter.

void error(LPSTR lpszFunction)

{

    CHAR szBuf[80];

    DWORD dw = GetLastError();

    sprintf(szBuf, "%s failed: GetLastError returned %u\n",

        lpszFunction, dw);

    MessageBox(NULL, szBuf, "ERROR", MB_OK);

    ExitProcess(dw);

}


  63.3  Functions

Following are the functions used with errors.

Beep
ExitWindows
ExitWindowsEx
FlashWindow
GetLastError
MessageBeep
PlaySound
SetErrorMode
SetLastError
SetLastErrorEx


Structured Exception Handling
  Chapter 64    Structured Exception Handling

64.1  About Structured Exception Handling

An exception is an event that occurs during the execution of a program, and that requires the execution of software outside the normal flow of control. Hardware exceptions can result from the execution of certain instruction sequences, such as division by zero or an attempt to access an invalid memory address. A software routine can also initiate an exception explicitly.

The Microsoft Win32 application programming interface (API) supports structured exception handling, a mechanism for handling hardware- and software-generated exceptions. Structured exception handling gives programmers complete control over the handling of exceptions, provides support for debuggers, and is usable across all programming languages and machines.

The Win32 API also supports termination handling, which enables programmers to ensure that whenever a guarded body of code is executed, a specified block of termination code is also executed. The termination code is executed regardless of how the flow of control leaves the guarded body. For example, a termination handler can guarantee that clean-up tasks are performed even if an exception or some other error occurs while the guarded body of code is being executed.

Structured exception and termination handling is an integral part of the Win32 system and it enables a very robust implementation of the system software. It is envisioned that application developers also will use these mechanisms to create consistently robust and reliable applications.

Structured exception handling is made available to application developers primarily through compiler support. For example, the Microsoft compilers provided with the Win32 development kit support the try keyword that identifies a guarded body of code, and the except and finally keywords that identify an exception handler and a termination handler, respectively. Although this chapter uses examples from the support available in Microsoft compilers, it is possible for other compiler vendors to provide this support as well.


  64.1.1  Exception Handling

Exceptions can be initiated by hardware or software, and can occur in kernel-mode as well as user-mode code. Win32 structured exception handling provides a single mechanism for the handling of kernel-mode and user-mode exceptions, both hardware- and software-generated.

The execution of certain instruction sequences can result in exceptions that are initiated by hardware. For example, an access violation is generated by the hardware when a process attempts to read from or write to a virtual address to which it does not have the appropriate access.

Events that require exception handling may also occur during execution of a software routine (for example, when an invalid parameter value is specified). When this happens, a thread can initiate an exception explicitly by calling the RaiseException function. This function enables the calling thread to specify information that describes the exception.


  64.1.1.1  Exception Dispatching

When a hardware or software exception occurs, the processor stops execution at the point at which the exception occurred and transfers control to the system. First, the system saves both the machine state of the current thread and information that describes the exception. The system then attempts to find an exception handler to handle the exception.

The machine state of the thread in which the exception occurred is saved in a CONTEXT structure. This information (called the context record) enables the system to continue execution at the point of the exception if the exception is successfully handled. The description of the exception (called the exception record) is saved in an EXCEPTION_RECORD structure. Because it stores the machine-dependent information of the context record separately from the machine-independent information of the exception record, the exception-handling mechanism is portable to different platforms. The information in both the context and exception records is available by means of the GetExceptionInformation function, and can be made available to any exception handlers that are executed as a result of the exception. The exception record includes the following information:

•	An exception code that identifies the type of exception.

•	Flags indicating whether the exception is continuable. Any attempt to continue execution after a noncontinuable exception generates another exception.

•	A pointer to another exception record. This facilitates creation of a linked list of exceptions if nested exceptions occur.

•	The address at which the exception occurred.

•	An array of 32-bit arguments that provide additional information about the exception.

When an exception occurs in user-mode code, the system goes through the following search for an exception handler:

1.	The system first attempts to notify the process's debugger, if any.

2.	If the process is not being debugged, or if the associated debugger does not handle the exception, the system attempts to locate a frame-based exception handler by searching the stack frames of the thread in which the exception occurred. The system searches the current stack frame first, then proceeds backward through preceding stack frames.

3.	If no frame-based handler can be found, or no frame-based handler handles the exception, the system makes a second attempt to notify the process's debugger.

4.	If the process is not being debugged, or if the associated debugger does not handle the exception, the system provides default handling based on the exception type. For most exceptions, the default action is to call the ExitProcess function.

When an exception occurs in kernel-mode code, the system searches the stack frames of the kernel stack in an attempt to locate an exception handler. If a handler cannot be located or no handler handles the exception, the system is shut down as if the ExitWindows function had been called.


  64.1.1.2  Debugger Support

The system's handling of user-mode exceptions provides support for sophisticated debuggers. If the process in which an exception occurs is being debugged, the system generates a debug event. If the debugger is using the WaitForDebugEvent function, the debug event causes that function to return with a pointer to a DEBUG_EVENT structure. This structure contains the process and thread identifiers that the debugger can use to access the thread's context record. The structure also contains an EXCEPTION_DEBUG_INFO structure that includes a copy of the exception record.

The system's search for an exception handler includes two attempts to notify a process's debugger. The first notification attempt provides the debugger with an opportunity to handle breakpoint or single-step exceptions. The user can then issue debugger commands to manipulate the process's environment before any exception handlers are executed. The second attempt to notify the debugger occurs only if the system is unable to find a frame-based exception handler that handles the exception.

At each notification attempt, the debugger uses the ContinueDebugEvent function to return control to the system. Before returning control the debugger can handle the exception and modify the thread state as appropriate, or it can choose not to handle the exception. Using ContinueDebugEvent the debugger can indicate that it has handled the exception, in which case the machine state is restored and thread execution is continued at the point at which the exception occurred. The debugger can also indicate that it did not handle the exception, which causes the system to continue its search for an exception handler.


  64.1.2  Frame-based Exception Handling

A frame-based exception handler is a mechanism by which a developer deals with the possibility that an exception may occur in a certain sequence of code. A frame-based exception handler consists of the following:

•	A guarded body of code

•	A filter expression

•	An exception-handler block

Frame-based exception handlers are declared in language-specific syntax. For example, in the Microsoft® C Optimizing Compiler, they are implemented by the try-except statement. For more information about the Microsoft C exception-handling syntax, see Section 64.1.4, »Syntax«.

The guarded body of code is a set of one or more statements for which the filter expression and the exception-handler block provide exception-handling protection. The guarded body can be a block of code, a set of nested blocks, or an entire procedure or function. In Microsoft C, a guarded body is enclosed by braces ({}) following the try keyword.

The filter expression of a frame-based exception handler is an expression that is evaluated by the system when an exception occurs within the guarded body. This evaluation results in one of the following actions by the system:

•	The system stops its search for an exception handler, restores the machine state, and continues thread execution at the point at which the exception occurred.

•	The system continues its search for an exception handler.

•	The system transfers control to the exception handler, and thread execution continues sequentially in the stack frame in which the exception handler is found. If the handler is not in the stack frame in which the exception occurred, the system unwinds the stack, leaving the current stack frame and any other stack frames until it is back to the exception handler's stack frame. Before an exception handler is executed, termination handlers are executed for any guarded bodies of code that terminated as a result of the transfer of control to the exception handler. For more information about termination handlers, refer to Section 64.1.3, »Termination Handling«.

The filter expression can be a simple expression, or it can invoke a filter function that attempts to handle the exception. You can call the GetExceptionCode and GetExceptionInformation functions from within a filter expression to get information about the exception being filtered. GetExceptionCode returns a code that identifies the type of exception, and GetExceptionInformation returns a pointer to an EXCEPTION_POINTERS structure that contains pointers to CONTEXT and EXCEPTION_RECORD structures.

These functions cannot be called from within a filter function, but their return values can be passed as parameters to a filter function. GetExceptionCode can be used within the exception-handler block, but GetExceptionInformation cannot because the information it points to is typically on the stack and is destroyed when control is transferred to an exception handler. However, an application can copy the information to safe storage to make it available to the exception handler.

The advantage of a filter function is that it can handle an exception and return a value that causes the system to continue execution from the point at which the exception occurred. With an exception-handler block, in contrast, execution continues sequentially from the exception handler rather than from the point of the exception.

Handling an exception may be as simple as noting an error and setting a flag that will be examined later, printing a warning or error message, or taking some other limited action. If execution can be continued, it may also be necessary to change the machine state by modifying the context record. For an example of a filter function that handles a page fault exception, see Chapter 42, »Memory Management«.

The UnhandledExceptionFilter function can be used as a filter function in a filter expression. It returns EXCEPTION_EXECUTE_HANDLER unless the process is being debugged, in which case it returns EXCEPTION_CONTINUE_SEARCH.


  64.1.3  Termination Handling

A termination handler is a mechanism by which a developer ensures that a specific block of code is executed whenever flow of control leaves a particular guarded body of code. A termination handler consists of the following elements:

•	A guarded body of code

•	A block of termination code to be executed when the flow of control leaves the guarded body

Termination handlers are declared in language-specific syntax. In Microsoft C, they are implemented by the try-finally statement. For more information about the Microsoft C exception-handling syntax, see Section 64.1.4, »Syntax«.

The guarded body of code can be a block of code, a set of nested blocks, or an entire procedure or function. Whenever the guarded body is executed, the block of termination code will be executed. The only exception to this is when the thread terminates during execution of the guarded body (for example, if the ExitThread or ExitProcess function is called from within the guarded body).

The termination block is executed when the flow of control leaves the guarded body, regardless of whether the guarded body terminated normally or abnormally. The guarded body is considered to have terminated normally when the last statement in the block is executed and control proceeds sequentially into the termination block. Abnormal termination occurs when the flow of control leaves the guarded body due to an exception, or due to a control statement such as return, goto, break, or continue. The AbnormalTermination function can be called from within the termination block to determine whether the guarded body terminated normally.


  64.1.4  Syntax

This section describes the syntax and usage of structured exception handling as implemented in Microsoft C. The following keywords are interpreted by the Microsoft C compiler as part of the structured exception-handling mechanism.

Keyword	Description
try	Begins a guarded body of code. Used with the except keyword to construct an exception handler, or with the finally keyword to construct a termination handler.
except	Begins a block of code that is executed only when an exception occurs within its associated try block.
finally	Begins a block of code that is executed whenever the flow of control leaves its associated try block.
The compiler also interprets the GetExceptionCode, GetExceptionInformation, and AbnormalTermination functions as keywords, and their use outside the appropriate exception-handling syntax generates a compiler error. Following are brief descriptions of these functions.

Function	Description
GetExceptionCode	Returns a code that identifies the type of exception. This function can be called only from within the filter expression or exception-handler block of a try-except exception handler.
GetExceptionInformation	Returns a pointer to an EXCEPTION_POINTERS structure containing pointers to the context record and the exception record. This function can be called only from within the filter expression of a try-except exception handler.
AbnormalTermination	Indicates whether the flow of control left the associated try block sequentially after executing the last statement in the block. This function can be called only from within the finally block of a try-finally termination handler.


  64.1.4.1  Exception-handler Syntax

The try and except keywords are used to construct a frame-based exception handler. The following example shows the structure of a try-except exception handler.

try {

    /* guarded body of code */

}

except (filter-expression) {

    /* exception-handler block */

}

Note that the try block and the exception-handler block require braces ({}). Using a goto statement to jump into the body of a try block or into an exception-handler block is not permitted. This rule applies to both try-except and try-finally statements.

The try block contains the guarded body of code that is protected by the exception handler. A function can have any number of try-except statements, and these exception-handling statements can be nested within the same function or in different functions. If an exception occurs within the try block, the system takes control and begins the search for an exception handler. For a detailed description of this search, see Section 64.1.1, »Exception Handling«.

The exception handler only receives exceptions that occur within a single thread. This means that if a try block contains a call to the CreateProcess or CreateThread function, exceptions that occur within the new process or thread are not dispatched to this handler.

The system evaluates the filter expression of each exception handler guarding the code in which the exception occurred until either the exception is handled or there are no more handlers. A filter expression must be evaluated as one of the three following values.

Value	Meaning
EXCEPTION_EXECUTE_HANDLER
	The system transfers control to the exception handler, and execution continues in the stack frame in which the handler is found.
EXCEPTION_CONTINUE_SEARCH
	The system continues to search for a handler.
EXCEPTION_CONTINUE_EXECUTION
	The system stops its search for a handler, and returns control to the point at which the exception occurred. If the exception is non-continuable, this results in a STATUS_NONCONTINUABLE_EXCEPTION exception.
The filter expression is evaluated in the context of the function in which the try-except statement is located, even though the exception may have occurred in a different function. This means that the filter expression can access the function's local variables. Similarly, the exception-handler block can access the local variables of the function in which it is located.

For more information about filter expressions and filter functions, see Section 64.1.2, »Frame-based Exception Handling«.


  64.1.4.2  Termination-handler Syntax

The try and finally keywords are used to construct a termination handler. The following example shows the structure of a try-finally termination handler.

try {

    /* guarded body of code */

}

finally {

    /* finally block */

}

As with the try-except statement, both the try block and the finally block require braces ({}), and using a goto statement to jump into either block is not permitted.

The try block contains the guarded body of code that is protected by the termination handler. A function can have any number of try-finally statements, and these termination handling structures can be nested within the same function or in different functions.

The finally block is executed whenever the flow of control leaves the try block. However, the finally block is not executed if either the ExitProcess or ExitThread function is called from within the try block.

If execution of the try block terminates because of an exception that invokes the exception-handling block of a frame-based exception handler, the finally block is executed before the exception-handling block is executed. Similarly, a call to the standard C longjmp function from the try block causes execution of the finally block before execution resumes at the target of the longjmp operation. If try block execution terminates due to a normal control statement (return, break, continue, or goto), the finally block is executed.

The AbnormalTermination function can be used within the finally block to determine whether the try block terminated sequentially — that is, whether it reached the closing brace (}). Leaving the try block because of a call to longjmp, a jump to an exception handler, or a return, break, continue, or goto statement, is considered an abnormal termination. Note that failure to terminate sequentially causes the system to search backward through all stack frames to determine whether any termination handlers must be called. This can result in performance degradation due to the execution of hundreds of instructions.

Execution of the finally block can terminate by any of the following means:

•	Execution of the last statement in the block and continuation to the next instruction

•	Use of a normal control statement (return, break, continue, or goto)

•	Use of longjmp, or a jump to an exception handler

The finally block is executed in the context of the function in which the try-finally statement is located. This means that the finally block can access that function's local variables.


  64.2  Using Structured Exception Handling

This section explains the following tasks:

•	Using the try-except exception-handling syntax to create a frame-based exception handler.

•	Using the try-finally termination-handing syntax to create a termination handler.


  64.2.1  Using an Exception Handler

The following example shows a version of the standard C strcpy function that can handle an invalid pointer and return NULL if one is encountered.

Note that this exception handler is intended to handle an access-violation exception, but is inappropriate if some other type of exception occurs. Therefore, the filter expression in the example uses the GetExceptionCode function to check the exception type before executing the handler. This enables the system to continue its search for an appropriate handler if some other type of exception occurs.

Note also that there is no problem with using a return statement in the try block of a try-except statement. This differs from the use of return in the try block of a try-finally statement, which causes an abnormal termination of the try block.

LPTSTR SafeStrcpy(LPTSTR lpszString1, LPTSTR lpszString2) {

    try {

        return strcpy(string1, string2);

    }

    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?

                    EXCEPTION_EXECUTE_HANDLER :

                    EXCEPTION_CONTINUE_SEARCH ) {

        return NULL;

    }

}

The following example shows the interaction of nested try-finally and try-except statements. The RaiseException function causes an exception in the guarded body of a try-finally termination handler that is inside the guarded body of a try-except exception handler. The exception causes the system to evaluate the FilterFunction function, whose return value in turn causes the exception handler to be invoked. However, before the exception-handler block is executed, the finally block of the termination handler is executed because the flow of control has left the try block of the termination handler.

DWORD FilterFunction() {

    printf("1 ");                    /* this is printed first  */

    return EXCEPTION_EXECUTE_HANDLER;

}

VOID main(VOID) {

    try {

        try {

            RaiseException(1,        /* exception code         */

                           0,        /* continuable exception  */

                           0, NULL); /* no arguments           */

        }

        finally {

            printf("2 ")             /* this is printed second */

        }

    }

    except ( FilterFunction() ) {

        printf("3\n");               /* this is printed last   */

    }

}


  64.2.2  Using a Termination Handler

The following example shows how a try-finally statement is used to ensure that resources are released when execution of a guarded body of code terminates. In this case, a thread uses the EnterCriticalSection function to wait for ownership of a critical section object. When the thread is finished executing the code that is protected by the critical section, it must call the LeaveCriticalSection function to make the critical section object available to other threads. Using a try-finally statement guarantees that this will happen.

For more information about critical section objects, see Chapter 44, »Synchronization«.

LPTSTR lpBuffer = NULL;

CRITICAL_SECTION csCriticalSection;

try {

    /*

     * EnterCriticalSection synchronizes code

     * with other threads.

     */

    EnterCriticalSection(&CriticalSection);

    /* Perform a task that may cause an exception. */

    lpBuffer = (LPTSTR) LocalAlloc(LPTR, 10);

    strcpy(lpBuffer,"Hello");  /* possible access violation */

    printf("%s\n",lpBuffer);

    LocalFree(lpBuffer);

}

/*

 * LeaveCriticalSection is called even if

 * an exception occurred.

 */

finally {

    LeaveCriticalSection(&CriticalSection);

}


  64.3  Functions

Following are the functions used in structured exception handling.

AbnormalTermination
GetExceptionCode
GetExceptionInformation
RaiseException
SetUnhandledExceptionFilter
UnhandledExceptionFilter


Event Logging
  Chapter 65    Event Logging

65.1  About Event Logging

When an error occurs in an application written for Microsoft Windows, the system administrator or support personnel must determine what caused the error, attempt to recover any lost data, and prevent the error from recurring. If applications record important events such as low-memory conditions or excessive disk retries, the record of this information, called an event log, can be used to help determine what conditions may have caused the error and the context in which the error occurred. (Event logging can also be applied to the Windows operating system and to system services.) By periodically viewing the event log, the system administrator may be able to identify problems before they cause serious damage.

Many applications record errors and events in various proprietary error logs. These proprietary logs have different formats, apply different user interfaces for their display, and cannot be merged to provide a complete report. But all of these logs store similar information and present the logged data in similar ways.

Event logging in Windows provides a standard, centralized way for applications (and Windows) to record important software and hardware events. It also supplies a standard user interface for viewing the logs and a programming interface for examining the logs. Event logging provides a means to merge events from various sources into a single informative story.


  65.1.1  Event Logging Model

Event logs store records of significant events on behalf of the Windows operating system and the applications that run with Windows. Generally, applications should log only information that could be useful in diagnosing a hardware or software problem.

Events are classified as information, warnings, and errors. All event classifications have well-defined common data and can optionally include event-specific data. For example, information can assert that a service has started. Warnings are used for recoverable problems such as low disk-space conditions. Errors are used for nonrecoverable conditions that might cause an application to fail. In addition to logging event classifications, the security service logs successes and failures in audits.


  65.1.2  Logging Guidelines

Because logging functions are general purpose, developers must decide what information is appropriate to log. It is important to note that logging consumes resources: disk space and logging time. The event log is not intended to be used as a trace facility.

You should log information about events that can be used to diagnose problems after they have occurred. Logging low-memory conditions, for example, can provide information about a problem that the system administrator can solve by adding more memory to the computer.

Following are more examples in which event logging is helpful:

•	A disk driver encounters a bad sector on the disk. It may be able to read from or write to the sector after some retries, but the sector will probably go bad eventually. The disk driver should log a warning if it can proceed; otherwise, it should log an error.

•	A file system finds a bad sector and fixes it. A large number of events of this type might indicate that the disk is about to fail. The file system logs a warning event.

•	A device driver encounters a hardware problem, such as a disk controller time-out, a power failure in a parallel port, or a data error from a network or serial card. Logging information about these events can help in diagnosing hardware problems. The device driver logs the hardware problem.

•	An Application encounters resource problems. An application or a device driver may get into a low-memory situation (caused by a code bug, for example) that degrades performance. Logging an event when memory allocation fails might later provide a clue about what went wrong. The application logs the resource problem.

•	A server application (a database or a communications server, for example) records events such as a user logging on, opening a database, or starting a file transfer. The server can also log important information as it runs, such as the number of resources the application is using, errors it encounters (cannot access file, host process disconnected, and so on), a corruption in the database (not able to find a leaf node down a certain path in a tree), or whether a file transfer was successful or not. All of this information can be valuable to a support person (or to the developer of the application). The application records such events and logs them as information events.


  65.1.3  Logging Performance and Size

Typically, how much disk space does an event log require? What is the overhead for an application that makes a call to log an event? The answers to these questions depend on how much information the application chooses to log. This is why it is important to log only essential information and to place event logging calls in an error path in the application, rather than place them in the main path, where the performance hit would be more severe.


  65.1.4  Event Logging Management Information

Event logging management information is stored in the Services key of the configuration database and can be modified by a system administrator.

The structure of the configuration information is as follows:

HKEY_LOCAL_MACHINE

  SYSTEM

    CurrentControlSet

      Services

        EventLog

          Application

          Security

          System

The EventLog key contains several subkeys, called logfiles. The default logfiles are Application, Security, and System. Each logfile subkey can contain subkeys, called sources. You cannot use a source name that has been used as a logfile name, and source names should not be hierarchical. (The backslash character [\] cannot be used in a registry key.) Each source entry contains information specific to the source of the event, as shown in the following table.

Value	Description
EventMessageFile	Specifies the path and filename for the event identifier message file. This value has the type REG_EXPAND_SZ.
CategoryMessageFile	Specifies the path and filename for the category message file. The category and event identifier message strings may be in the same file. This value has the type REG_EXPAND_SZ.
CategoryCount	Specifies the number of categories supported. This value has the type REG_DWORD.
TypesSupported	Specifies a bitmask of supported types. This value has the type REG_DWORD.
When an application uses the RegisterEventSource or OpenEventLog function to get a handle of an event log, the event logging service searches for the specified source name in the registry. For example, the Application logfile might have configured sources of Microsoft® SQL Server (™)  and Microsoft® Excel. If an application uses RegisterEventSource or OpenEventLog with a source name of Application, SQL, or Excel, the event logging service returns a handle to the Application logfile.

An application can use the Application event log without adding a new source key to the registry. If the application calls RegisterEventSource, passing a source name that cannot be found in the registry, the event logging service uses the Application logfile by default. However, because there is not a message or category string file, the event viewer will not be able to map the event identifier or category to a replacement string. For this reason, the recommended procedure is to add a unique source name for the application to the registry. This allows you to specify message files for the event identifier and category in your events. When your application reports an event, Event Viewer (EVENTVWR.EXE) maps the event identifier and category parameters in the reported event to replacement strings in the message files.

Applications and services should add their source names to the Application logfile. Device drivers should add their source name to the System logfile.

For more information about using the registry, see Chapter 52, »Registry and Initialization Files«. For more information about creating and using message files, see your message compiler documentation.


  65.2  Event Logging Operations

In the following table are the five operations that can be performed on the event logs.

Operation	Function
Backup	BackupEventLog
Clear	ClearEventLog
Query	GetOldestEventLogRecord, GetNumberOfEventLogRecords
Read	ReadEventLog
Write	ReportEvent
The OpenEventLog, OpenBackupEventLog, RegisterEventSource, DeregisterEventSource, and CloseEventLog functions also open and close event log handles; this provides an object-oriented model for the function set, as well as some performance gain when performing multiple operations on the logs.

The OpenEventLog and ReportEvent functions take an optional server name as a parameter so that the operations can be performed on the remote server. OpenEventLog should be used for reading or performing some administrative operation (backup, clear, query) on the log, and RegisterEventSource should be used for writing to logs.


  65.2.1  Event Log Entry

The following sections describe the parameters supplied for logged events.


  65.2.1.1  Source

Source is the name of the software that logs the event. For many applications, Source may be simply the application name, or it may reflect a subcomponent of a larger application.


  65.2.1.2  Event Identifier

Event identifiers are looked up within a message file to locate a description string that can be presented to the user. Support personnel also use event identifiers; if a user can identify the source and the event identifier, support personnel will know exactly which event has occurred. Event identifiers are unique to a particular source.


  65.2.1.3  Type

Windows NT defines five types of event logging. Each event must be of a single type, because types cannot be combined.

Event type	Description
Information	Information events are used to note infrequent but significant successful operations. For example, when Microsoft SQL Server successfully loads, it may be appropriate to log a "SQL Server has started" information event. Note that while this is appropriate for major server services, it is generally inappropriate for a desktop application (Microsoft Excel, for example) to log an event each time it is started. Information events should not be used as a trace facility.
Warning	Warning events are used to indicate problems that are not significant, but that may foretell of future errors or other problems. Resource consumption is a good candidate for a Warning event. For example, a warning could be logged if disk space is low. Errors that are recovered without loss of function or data can be classified as warnings.
Error	Error events are used to indicate significant problems that have occurred and that the user should know about. Errors usually indicate a loss of functionality or data. For example, if a service cannot be loaded as the system boots, an Error event can be logged.
Success Audit	Success Audit events are security events that occur when an audited access attempt is successful. For example, a successful logon attempt is a Success Audit event.
Failure Audit	Failure Audit events are security events that occur when an audited access attempt fails. For example, a failed attempt to open a file is a Failure Audit event.


  65.2.1.4  Category

Categories are used to help organize events so that they can be filtered in the Event Viewer. Each Source can define its own numbered Categories and the text strings to which they are mapped. The Categories must be numbered consecutively beginning with the number 1. With Event Viewer, it is possible to filter by Source and within Source, by Category. The security system uses several categories: Logon/Logoff, File System Access, Privileged Actions, Change in Security Policy. Categories for other parts of the system are developed over time as it becomes clear which events are being logged. An application can define its own categories.


  65.2.1.5  Strings

Strings are optional language-independent (nonlocalized) strings used to fill in values for placeholders in description strings. Because the strings are not localized, it is critical that this field be used only to store language-independent strings such as numeric values or string tokens (filenames, user names, and so on). String length must not exceed 32 kilobytes − 1 characters.

It is not acceptable to use several strings to "paste" together a larger description or to use nontoken strings. The insertion string should be treated as data, not text. For example, the following example is not recommended:

Str1$ = successfully

Description = "User was %1 added to database."

Using these two strings to form the string, "User was successfully added to database." (the alternative being Str1$ = "not") is not acceptable for three reasons:

1.	The strings "successfully" and "not" should be localized.

2.	Even if the insertion strings are obtained from language-dependent message files, this is done when the event is logged, not when it is viewed. When the event is viewed, the language may be wrong.

3.	Such substitutions of adverbs and adjectives will not work in many other languages. The preceding example should use two separate events.

The following example shows an appropriate use of strings:

Str1$ = "c:\testapp.c".

Description = "Access denied. Attempted to open the file %1"


  65.2.1.6  Description

Each event is associated with a description located in a message file that is registered by the Source. The description should help the user understand what went wrong and suggest what actions to take. Focus the description toward users solving their own problems, not toward support people or developers. Make the description clear and concise and avoid culture-specific phrases. If your event includes private data in the Data field, include at the end of the description an explanation about what the Data field contains. For example, the network software often notes: "(The SMB is the event data)." As a convention, use parentheses around such remarks, as indicated in this example. Several applications can share the same message file, and the message file can contain descriptions for both the event identifier and the event category.

The description strings are indexed by event identifier, enabling Event Viewer to display event-specific text for any event based on the event identifier. All descriptions are localized and language dependent. Description strings can optionally contain placeholders for insertion strings. Each placeholder is represented by a percent sign and an index number for the string to substitute. For example, the placeholder %1 is replaced by the first insertion string, %5 is replaced by the fifth insertion string, and so on.


  65.2.1.7  Data

Each event can have event-specific data associated with it. Event Viewer has no information of any of the events, and only displays extra data in a combined hexadecimal and text dump format. Use event-specific data sparingly, including it only if you are sure it will be useful to a support technician or a developer. You might include, for example, data containing a structure filled with information that could help a technician debug an application failure.

Examples of event-specific data are found in many network events; network control blocks (NCBs) are included as event-specific data. In all cases, the last part of the description string should include a note about what information is available as event-specific data. Third-party applications can use the Data field to store information the application can process independently of Event Viewer. For example, you could write your own viewer specific to your events, or write a program that scans the logfiles and makes reports, including information from the event-specific data.


  65.2.1.8  The EVENTLOGRECORD Structure

The ReadEventLog function uses the EVENTLOGRECORD structure to format event log information. This structure contains information relating to the content of the event record. The actual event record information follows this structure in the buffer returned by the ReadEventLog function.


  65.2.2  Special Cases

Each call to an event logging function is considered to be an atomic operation. For reading the event log, only whole event records are returned. For logging events, each event record is guaranteed to be written as a complete record in the log. The following list describes how the event logging service handles special conditions:

•	Multiple calls written to the same log. The event logging service serializes the operations; the event logs are written sequentially in the logfile.

•	A call to read and a call to write are made at the same time. What happens depends on where the current read operation is being carried out in the file. If the read position is at the end of the file, either the read operation fails with an "end-of-file" status (if the write operation has not been done), or it returns the new record that the write operation has just written to the log.

•	Clearing the log before reading. The read operation returns an "end-of-file" status after the file is cleared.

•	Clearing the log before writing. The clear operation truncates the logfile; the write operation then writes the new record at the beginning of the log.


  65.3  Using Event Logging

The following sections illustrate these tasks related to event logging:

•	Adding a source to the registry.

•	Reporting an event.

•	Querying the event log.

•	Reading an event.

You can use the Windows Registration Database Editor (REGEDIT.EXE) to view the event log registry keys, and you can use Event Viewer to view the event logs.


  65.3.1  Adding a Source to the Registry

You can use the default Application event log without adding your source name to the registry. However, Event Viewer will not be able to map your event identifier codes to message strings unless you register your source and provide a message-file name.

You can add a new source name to the registry by opening a new registry subkey under the Application key and adding registry values to the new subkey. The following code sample opens a new source name called SamplApp and adds to the new subkey a message-file name and a bitmask of supported types.

HKEY hk;

DWORD dwData;

UCHAR szBuf[80];

/*

 * Add your source name as a subkey under the Application

 * key in the EventLog service portion of the registry.

 */

if (RegCreateKey(HKEY_LOCAL_MACHINE,

"SYSTEM\\CurrentControlSet\\Services\

\\EventLog\\Application\\SamplApp",

            &hk))

    ErrorExit("could not create registry key");

/* Set the Event ID message-file name. */

strcpy(szBuf, "%SystemRoot%\\System\\SamplApp.dll");

/* Add the Event ID message-file name to the subkey. */

if (RegSetValueEx(hk,             /* subkey handle         */

        "EventMessageFile",       /* value name            */

        0,                        /* must be zero          */

        REG_EXPAND_SZ,            /* value type            */

        (LPBYTE) szBuf,           /* address of value data */

        strlen(szBuf) + 1))       /* length of value data  */

    ErrorExit("could not set event message file");

/* Set the supported types flags. */

dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |

    EVENTLOG_INFORMATION_TYPE;

if (RegSetValueEx(hk,      /* subkey handle                */

        "TypesSupported",  /* value name                   */

        0,                 /* must be zero                 */

        REG_DWORD,         /* value type                   */

        (LPBYTE) &dwData,  /* address of value data        */

        sizeof(DWORD)))    /* length of value data         */

    ErrorExit("could not set supported types");

RegCloseKey(hk);


  65.3.2  Reporting an Event

After you have added a source name to the registry, use the RegisterEventSource function to get a handle of the Application event log, as in the following example, which gets the handle and then adds an event to the logs.

LPSTR aszMsg[] = {

    "SamplApp",

    };

HANDLE h;

h = RegisterEventSource(NULL, /* uses local computer         */

    "SamplApp");              /* source name                 */

if (h == NULL)

    ErrorExit("could not register event source");

if (!ReportEvent(h,           /* event log handle            */

        EVENTLOG_ERROR_TYPE,  /* event type                  */

        0,                    /* category zero               */

        0x1003,               /* event identifier            */

        NULL,                 /* no user security identifier */

        1,                    /* one substitution string     */

        0,                    /* no data                     */

        (LPTSTR *) aszMsg,    /* address of string array     */

        NULL))                /* address of data             */

    ErrorExit("could not report event");

DeregisterEventSource(h);


  65.3.3  Querying the Event Log

The following code sample displays the number of event records currently in the Application event log and the System event log.

/* Open the System log. */

h = OpenEventLog(NULL,  /* uses local computer   */

    "System");          /* source name           */

if (h == NULL)

    ErrorExit("could not open System event log");

/* Get the number of records in the System event log. */

if (!GetNumberOfEventLogRecords(h, &cRecords))

    ErrorExit

       ("could not get number of records");

printf("There are %d records in the System event log.\n", cRecords);

CloseEventLog(h);

/* Open the Application log. */

h = OpenEventLog(NULL,  /* uses local computer  */

    "Application");     /* source name          */

if (h == NULL)

    ErrorExit("could not open Application event log");

/* Get the number of records in the Application event log. */

if (!GetNumberOfEventLogRecords(h, &cRecords))

    ErrorExit("could not get number of records");

printf("There are %d records in the Application event log.\n",

    cRecords);

CloseEventLog(h);


  65.3.4  Reading the Event Log

The following code sample reads all the records in the Application logfile and displays the event identifier, event type, and source name for each event log entry.

EVENTLOGRECORD *pevlr;

BYTE bBuffer[BUFFER_SIZE];

DWORD dwRead, dwNeeded, cRecords, dwThisRecord = 0;

    /* Open the Application event log. */

    h = OpenEventLog(NULL,  /* uses local computer      */

        "Application");     /* source name              */

    if (h == NULL)

        ErrorExit("could not open Application event log");

    pevlr = (EVENTLOGRECORD *) &bBuffer;

    /*

     * Opening the event log positions the file pointer

     * for this handle at the beginning of the log.

     *

     * Read records sequentially until there

     * are no more.

     */

    while (ReadEventLog(h,                /* event log handle */

                EVENTLOG_FORWARDS_READ |  /* reads forward    */

                EVENTLOG_SEQUENTIAL_READ, /* sequential read  */

                0,            /* ignored for sequential reads */

                pevlr,        /* address of buffer            */

                BUFFER_SIZE,  /* size of buffer               */

                &dwRead,      /* count of bytes read          */

                &dwNeeded)) { /* bytes in next record         */

        while (dwRead > 0) {

            /*

             * Print the event ID, type, and source name.

             * The source name is just past the end of the

             * formal structure.

             */

            printf("%02d  Event ID: 0x%08X ",

                dwThisRecord++, pevlr->EventID);

            printf("EventType: %d Source: %s\n",

                pevlr->EventType, (LPSTR) ((LPBYTE) pevlr +

                sizeof(EVENTLOGRECORD)));

            dwRead -= pevlr->Length;

            pevlr = (EVENTLOGRECORD *)

                ((LPBYTE) pevlr + pevlr->Length);

        }

        pevlr = (EVENTLOGRECORD *) &bBuffer;

    }

    CloseEventLog(h);


  65.4  Functions

The following functions are used with event logging.

BackupEventLog
ClearEventLog
CloseEventLog
DeregisterEventSource
GetNumberOfEventLogRecords
GetOldestEventLogRecord
OpenBackupEventLog
OpenEventLog
ReadEventLog
RegisterEventSource
ReportEvent


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Performance Monitoring
  Chapter 66    Performance Monitoring

66.1  About Performance Monitoring

Performance monitoring refers to determining the system resources an application consumes, such as processor time and memory. Because the underlying architecture of Microsoft Windows NT is fundamentally different from previous versions of Windows, developers will probably want to examine their applications to ensure efficient use of their system resources and to fine-tune application performance. This is particularly true for applications ported from Windows versions 3.x. Many coding practices recommended for Windows 3.x are not necessary or are not recommended for Windows NT. For example, in Windows 3.x, developers were encouraged to keep files open only while the files were being used. With the increased size of the virtual address space in Windows NT, however, developers should avoid the practice of opening, using, and closing in favor of keeping files open while the application runs.

The Win32 performance-monitoring functions can help in evaluating the effects of such changes as developers migrate to Windows NT.


  66.1.1  Counters and Elapsed Times

A counter is a general term used in programming to refer to an incrementing variable. Some systems include a high-resolution performance counter that provides high-resolution elapsed times. The elapsed time can be used to fine-tune sections of source code. Windows NT supports two functions that enable application developers to obtain the value of a counter.

If a high-resolution performance counter exists on the system, the QueryPerformanceFrequency function can be used to express the frequency in counts per second. The value of the count is processor dependent. On some processors, for example, the count might be the cycle rate of the processor clock.

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter (if one exists on the system). By calling this function at the beginning and end of a section of code, an application essentially uses the counter as a stopwatch.

For example, QueryPerformanceFrequency might indicate that the frequency of the high-resolution performance counter on the system is 50,000 counts per second. If the application calls QueryPerformanceCounter immediately before and immediately after the section of code to be timed, the counter values might be 1500 counts and 3500 counts, respectively. This indicates that .04 seconds (2000 counts) elapsed while the code executed.


  66.1.2  Registry Database

Windows NT includes several tools that monitor the system. To present this information in a different format, to use information inside another application, or to create a performance monitor, your application must retrieve information through the registry. For more information about the registry, see Chapter 52, »Registry and Initialization Files«.


  66.1.2.1  Getting Performance Data

An application can obtain system-performance information by using the RegQueryValueEx registry function, with the HKEY_PERFORMANCE_DATA key. The application can use the RegOpenKey function to open the HKEY_PERFORMANCE_DATA handle, but it should use RegCloseKey to close the handle when it has finished running. This allows monitored software to be to be removed or installed, which cannot happen while they are being monitored. Network transports and drivers are examples of monitored software you may wish to remove.

The performance data is not stored in the registry. Using the RegQueryValueEx function with the HKEY_PERFORMANCE_DATA key causes the system to collect the data from the appropriate system object managers.

If an application is accessing a remote system, it must use the RegConnectRegistry function with the name of the remote system and the HKEY_PERFORMANCE_DATA key. RegConnectRegistry retrieves a key the application can use with RegQueryValueEx to retrieve performance data from the remote system.

The basic layout of the data retrieved by RegQueryValueEx is a PERF_DATA_BLOCK structure followed by one PERF_OBJECT_TYPE structure and accompanying data for each type of object being monitored. The system being observed defines objects that can be monitored. Typical object types include processors, disks, and memory.

The PERF_DATA_BLOCK structure describes the system and the performance data. This includes the size of the data, the number of objects being monitored, the frequency and value of the high-resolution performance counter, an offset to the system name, and so on.

The PERF_OBJECT_TYPE structure describes the performance data for one type of object. This includes the size of the structure and the object-specific data that follows the structure, the number of counters defined for the object type, the number of instances of this object type, the level of informational details provided, the code page, indices to the object name and Explain title in the title database, and so on.

Following each PERF_OBJECT_TYPE structure, there is a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the object. The PERF_COUNTER_DEFINITION structure specifies the type and size of the counter, the offset to the counter, the detail level, the counter name, and Explain title in the registry, and so on.

An instance is an instantiation (the creation of an instance) of a particular object type. The number of instances of a particular object type determines what follows the list of counter definitions. Not all object types have instances. A memory object, for example, has no instances because the system has only one memory. If the object type does not have instances, the counter definitions are followed by a single PERF_COUNTER_BLOCK structure. This structure is followed by data for each counter. The PERF_COUNTER_BLOCK structure contains the total length of the structure, in bytes, and the counter data that follows it.

If the object type has one or more instances, the list of counter definitions is followed by a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance. The PERF_INSTANCE_DEFINITION structure includes the name, identifier, and name of the parent of the instance. For example, the thread object type has instances; each thread in the system is an instance.

The number of object types, instances, and counters may vary from one RegQueryValueEx call to another. Therefore, the number and size of structures included in the performance data as well as the size of the data that follows each structure may also vary. To ensure that it is receiving the appropriate information, an application must use the offsets included in the performance structures to navigate through the performance data. Every offset is relative to the beginning of the structure containing it.


  66.1.2.2  Getting Descriptive Text

The names of the objects and counters, as well as the text that explains their meaning, are not returned in the performance structures described in the previous section. Instead, the structures contain indices to a structure in the Configuration Registry where the Unicode multilingual names and descriptions for each object and counter are stored. To access this information, the application must open the following registry node:

\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\<langid>

The language node (langid) is the ASCII representation of the 3-digit hexadecimal language identifier. For example, the U.S. English node is "009". This node, once opened, can be queried for values of either 'Counters' or 'Help'. The names of object types are included in the 'Counters' data. The 'Help' data supplies the Explain text.

The 'Counters' and 'Help' data are stored in MULTI_SZ strings. This type of data is a list of Unicode strings, each terminated with UNICODE_NULL. The last string is followed by an additional UNICODE_NULL.

The strings are listed in pairs. The first item is the Unicode string of the index contained in PERF_OBJECT_TYPE.ObjectNameTitleIndex or PERF_COUNTER_DEFINITION.CounterNameTitleIndex. The second item is the actual name of the index. Following is a fragment of the paired data:

2     System

4     Memory

6     % Processor Time

10    Read Operations/sec

12    Write Operations/sec

To retrieve a name or the Explain text for an item, an application must do the following:

1.	If the system is remote, use RegConnectRegistry.

2.	Use RegOpenKeyEx, specifying the registry node described previously, and the appropriate language node.

3.	Use RegQueryValueEx, specifying either 'Counters' or 'Help' as the name of the value to query. This provides MULTI_SZ data containing either the names of all the objects and counters, or Help information for all the objects and counters.

4.	Convert the appropriate index (PERF_OBJECT_TYPE.ObjectNameTitleIndex, PERF_OBJECT_TYPE.ObjectHelpTitleIndex, PERF_COUNTER_DEFINITION.CounterNameTitleIndex, or PERF_COUNTER_DEFINITION.CounterHelpTitleIndex) into Unicode or ASCII, depending on whether the application is Unicode or ASCII.

5.	Search the MULTI_SZ data for the appropriate index.

6.	Retrieve the string following the matching index as the object's name or descriptive information.


  66.1.2.3  Getting Selected Data

When using the RegQueryValueEx function, an application must use the lpcbData parameter to specify a byte count of the amount of data to retrieve. Estimating this amount is difficult because the number of object types and their instances is determined by the system configuration and system activity. The amount may vary from one request to another. If the function does not pass enough space, the return value will be ERROR_MORE_DATA. Therefore, your application should include a retry loop in which it passes increasing amounts of buffer space until it no longer gets this error. The successful buffer size should be the starting point for subsequent calls to RegQueryValueEx. This technique is illustrated in the example code at the end of this chapter.

In some cases, the application may not need to retrieve all the performance data provided by the system. Retrieving all the performance data provided by the system may be costly in terms of processor or memory requirements. The lpszValueName parameter of RegQueryValueEx indicates the amount of information to retrieve. This parameter can be in one of the following formats. The strings are case sensitive. If a string includes more than one word, the words must be separated by a space.

String	Meaning
Global	The function returns all data for counters on the local computer except those included in the Costly category, described later in this table.
nnn xx yyy	Each of these strings is a Unicode string representing the decimal value for a PERF_OBJECT_TYPE.ObjectNameTitleIndex. The function returns data only about the specified object types on the local computer.
	Note that more object types may be returned than are requested. This occurs if other object types are needed to support the requested data, e.g., processes are needed to identify threads, so processes will also be returned even if only threads are requested.
Foreign ssss	The string ssss is the name of a foreign computer — that is, one that does not support the registry calls for returning data remotely. The function returns all data for counters on the foreign computer, if your system is capable of collecting data from a foreign computer. You may want to try this approach if RegConnectRegistry fails to connect to a foreign computer.
Foreign ssss nnn xx yyy	This format combines Foreign ssss and nnn xx yyy, discussed above. The function returns all data for the specified counters on the foreign computer, if your system is capable of collecting data from a foreign computer. An application can try this approach if RegConnectRegistry fails to connect to a foreign computer, but you do not want all the available data.
Costly	The function returns data for object types whose data is expensive to collect, in terms of processor time or memory usage. You may wish to start a secondary thread to access this data, if you wish to respond to the user during data collection.


  66.2  Using Performance Monitoring

This section includes examples of code that display objects, counters, and Explain text for a system.


  66.2.1  Displaying Object, Counter, and Instance Names

The following example, PERFEX, includes code that illustrates how to display all counter indices in the system.

#define UNICODE 1

#define _UNICODE 1

//

//  "C" Include files

//

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <malloc.h>

//

//  Windows Include files

//

#include <windows.h>

#include <winperf.h>

#include <tchar.h>

//

//  Local constants

//

#define RESERVED        0L                  // reserved argument in fn. calls

#define INITIAL_SIZE    40960L              // initial perf data buff size

#define EXTEND_SIZE     4096L               // extend size of perf data buff

#define LINE_LENGTH     80                  // display line length

#define WRAP_POINT      LINE_LENGTH-12      // wrap point for explain text

#define OBJECT_TEXT_INDENT 4                // indent of object explain text

//

//  Command line option values

//

#define COMMAND_ERROR   0

#define COMMAND_HELP    1

#define COMMAND_COUNTER 2

//

//

//  Text string Constant definitions

//

const LPTSTR NamesKey = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib");

const LPTSTR DefaultLangId = TEXT("409");

const LPTSTR Counters = TEXT("Counters");

const LPTSTR Help = TEXT("Help");

const LPTSTR LastHelp = TEXT("Last Help");

const LPTSTR LastCounter = TEXT("Last Counter");

const LPTSTR Slash = TEXT("\\");

const LPTSTR Global = TEXT("Global");

//

//  Global Buffers

//

TCHAR   cValueName[LINE_LENGTH];  // used to store counter value string

CHAR    cExeName[LINE_LENGTH*2];  // used in processing command line

CHAR    cCtrName[LINE_LENGTH];    // used in processing command line

BOOL

StringToInt (

    IN  LPTSTR  InStr,

    OUT PDWORD  pdwOutInt

)

/*++

StringToInt

    Returns the decimal interpretation of the string in the InStr

    argument. Works for either Unicode or ANSI strings.

Arguments:

    InStr

        string to translate

    pdwOutInt

        base 10 version of the number in the InStr argument

Return Value:

    TRUE if conversion was successful

    FALSE if not

--*/

{

    // check for NULL pointers passed to function

    if ((!InStr) || (!pdwOutInt)) {

        SetLastError (ERROR_BAD_ARGUMENTS);

        return FALSE;

    }

    if ( (_stscanf (InStr, TEXT(" %d"), pdwOutInt)) == 1) {

        return TRUE;

    } else {

        return FALSE;

    }

} // StringToInt

VOID

DisplayCommandHelp (

)

/*++

DisplayCommandHelp

    displays usage of command line arguments

Arguments

    NONE

Return Value

    NONE

--*/

{

    printf ("\n\nPERFEX:");

    printf ("\n    Sample program to demonstrate Win 32 Performance API");

    printf ("\n\nUsage:");

    printf ("\n\n     perfex [-? | counter]");

    printf ("\n\n          -?  Displays a list of all counter objects in the system");

    printf ("\n     counter  is the name of a counter object");

    printf ("\n                  and displays the performance counters for that object");

    printf ("\n");

} // DisplayCommandHelp

LPTSTR

*BuildNameTable(

    IN HKEY    hKeyRegistry,   // handle to registry db with counter names

    IN LPTSTR  lpszLangId,     // unicode value of Language subkey

    OUT PDWORD  pdwLastItem    // size of array in elements

)

/*++

BuildNameTable

    Caches the counter names and explain text to accelerate name lookups

    for display.

Arguments:

    hKeyRegistry

            Handle to an open registry (this can be local or remote.) and

            is the value returned by RegConnectRegistry or a default key.

    lpszLangId

            The unicode id of the language to look up. (default is 409)

    pdwLastItem

            The last array element

Return Value:

    pointer to an allocated table. (the caller must free it when finished!)

    the table is an array of pointers to zero terminated TEXT strings.

    A NULL pointer is returned if an error occured. (error value is

    available using the GetLastError function).

    The structure of the buffer returned is:

        Array of pointers to zero terminated strings consisting of

            pdwLastItem elements

        MULTI_SZ string containing counter id's and names returned from

            registry for the specified language

        MULTI_SZ string containing explain text id's and explain text strings

            as returned by the registry for the specified language

    The structures listed above are contiguous so that they may be freed

    by a single "free" call when finished with them, however only the

    array elements are intended to be used.

--*/

{

    LPTSTR  *lpReturnValue;     // returned pointer to buffer

    LPTSTR  *lpCounterId;       //

    LPTSTR  lpCounterNames;     // pointer to Names buffer returned by reg.

    LPTSTR  lpHelpText ;        // pointet to exlpain buffer returned by reg.

    LPTSTR  lpThisName;         // working pointer

    BOOL    bStatus;            // return status from TRUE/FALSE fn. calls

    LONG    lWin32Status;       // return status from fn. calls

    DWORD   dwHelpItems;        // number of explain text items

    DWORD   dwCounterItems;     // number of counter text items

    DWORD   dwValueType;        // value type of buffer returned by reg.

    DWORD   dwArraySize;        // size of pointer array in bytes

    DWORD   dwBufferSize;       // size of total buffer in bytes

    DWORD   dwCounterSize;      // size of counter text buffer in bytes

    DWORD   dwHelpSize;         // size of help text buffer in bytes

    DWORD   dwThisCounter;      // working counter

    DWORD   dwLastId;           // largest ID value used by explain/counter text

    HKEY    hKeyValue;          // handle to Perflib entry in registry

    HKEY    hKeyNames;          // handle to names subkey in registry

    LPTSTR  lpValueNameString;  // pointer to buffer conatining subkey name

    //initialize pointers to NULL

    lpValueNameString = NULL;

    lpReturnValue = NULL;

    hKeyValue = NULL;

    hKeyNames = NULL;

    // check for null arguments and insert defaults if necessary

    if (!lpszLangId) {

        lpszLangId = DefaultLangId;

    }

    // open handle to Perflib key in registry to get number of items

    // used in order to compute array and buffer sizes

    lWin32Status = RegOpenKeyEx (

        hKeyRegistry,

        NamesKey,

        RESERVED,

        KEY_READ,

        &hKeyValue);

    // on error, free buffers, close keys and return NULL pointer

    if (lWin32Status != ERROR_SUCCESS) {

        goto BNT_BAILOUT;

    }

    // query registry to get number of Explain text items

    dwBufferSize = sizeof (dwHelpItems);

    lWin32Status = RegQueryValueEx (

        hKeyValue,

        LastHelp,

        RESERVED,

        &dwValueType,

        (LPBYTE)&dwHelpItems,

        &dwBufferSize);

    if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {

        goto BNT_BAILOUT;

    }

    // query registry to get number of counter and object name items

    dwBufferSize = sizeof (dwCounterItems);

    lWin32Status = RegQueryValueEx (

        hKeyValue,

        LastCounter,

        RESERVED,

        &dwValueType,

        (LPBYTE)&dwCounterItems,

        &dwBufferSize);

    if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {

        goto BNT_BAILOUT;

    }

    // use the greater of Help items or Counter Items to size array

    if (dwHelpItems >= dwCounterItems) {

        dwLastId = dwHelpItems;

    } else {

        dwLastId = dwCounterItems;

    }

    // array size is # of elements (+ 1, since names are "1" based)

    // times the size of a pointer

    dwArraySize = (dwLastId + 1) * sizeof(LPTSTR);

    // allocate string buffer for language ID key string

    lpValueNameString = malloc (

        lstrlen(NamesKey) * sizeof (TCHAR) +

        lstrlen(Slash) * sizeof (TCHAR) +

        lstrlen(lpszLangId) * sizeof (TCHAR) +

        sizeof (TCHAR));

    if (!lpValueNameString) {

        lWin32Status = ERROR_OUTOFMEMORY;

        goto BNT_BAILOUT;

    }

    // build the key string for the specified language ID

    lstrcpy (lpValueNameString, NamesKey);

    lstrcat (lpValueNameString, Slash);

    lstrcat (lpValueNameString, lpszLangId);

    lWin32Status = RegOpenKeyEx (   // get handle to this key in the

        hKeyRegistry,               // registry

        lpValueNameString,

        RESERVED,

        KEY_READ,

        &hKeyNames);

    if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;

    // get size of counter names

    dwBufferSize = 0;

    lWin32Status = RegQueryValueEx (

        hKeyNames,

        Counters,

        RESERVED,

        &dwValueType,

        NULL,

        &dwBufferSize);

    if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;

    dwCounterSize = dwBufferSize;

    // get size of help text

    dwBufferSize = 0;

    lWin32Status = RegQueryValueEx (

        hKeyNames,

        Help,

        RESERVED,

        &dwValueType,

        NULL,

        &dwBufferSize);

    if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;

    dwHelpSize = dwBufferSize;

    // allocate buffer with room for pointer array, counter name

    // strings and help name strings

    lpReturnValue = malloc (dwArraySize + dwCounterSize + dwHelpSize);

    if (!lpReturnValue) {

        lWin32Status = ERROR_OUTOFMEMORY;

        goto BNT_BAILOUT;

    }

    // initialize pointers into buffer

    lpCounterId = lpReturnValue;

    lpCounterNames = (LPTSTR)((LPBYTE)lpCounterId + dwArraySize);

    lpHelpText = (LPTSTR)((LPBYTE)lpCounterNames + dwCounterSize);

    // read counter names into buffer. Counter names will be stored as

    // a MULTI_SZ string in the format of "###" "Name"

    dwBufferSize = dwCounterSize;

    lWin32Status = RegQueryValueEx (

        hKeyNames,

        Counters,

        RESERVED,

        &dwValueType,

        (LPVOID)lpCounterNames,

        &dwBufferSize);

    if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;

    // read explain text into buffer. Counter names will be stored as

    // a MULTI_SZ string in the format of "###" "Text..."

    dwBufferSize = dwHelpSize;

    lWin32Status = RegQueryValueEx (

        hKeyNames,

        Help,

        RESERVED,

        &dwValueType,

        (LPVOID)lpHelpText,

        &dwBufferSize);

    if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;

    // load counter array items, by locating each text string

    // in the returned buffer and loading the

    // address of it in the corresponding pointer array element.

    for (lpThisName = lpCounterNames;

         *lpThisName;

         lpThisName += (lstrlen(lpThisName)+1) ) {

        // first string should be an integer (in decimal digit characters)

        // so translate to an integer for use in array element identification

        bStatus = StringToInt (lpThisName, &dwThisCounter);

        if (!bStatus) {

            // error is in GetLastError

            goto BNT_BAILOUT;  // bad entry

        }

        // point to corresponding counter name which follows the id number

        // string.

        lpThisName += (lstrlen(lpThisName)+1);

        // and load array element with pointer to string

        lpCounterId[dwThisCounter] = lpThisName;

    }

    // repeat the above for the explain text strings

    for (lpThisName = lpHelpText;

         *lpThisName;

         lpThisName += (lstrlen(lpThisName)+1) ) {

        // first string should be an integer (in decimal unicode digits)

        bStatus = StringToInt (lpThisName, &dwThisCounter);

        if (!bStatus) {

            // error is in GetLastError

            goto BNT_BAILOUT;  // bad entry

        }

        // point to corresponding counter name

        lpThisName += (lstrlen(lpThisName)+1);

        // and load array element;

        lpCounterId[dwThisCounter] = lpThisName;

    }

    // if the last item arugment was used, then load the last ID value in it

    if (pdwLastItem) *pdwLastItem = dwLastId;

    // free the temporary buffer used

    if (lpValueNameString) {

        free ((LPVOID)lpValueNameString);

    }

    // close the registry keys

    RegCloseKey (hKeyValue);

    RegCloseKey (hKeyNames);

    // exit returning the pointer to the buffer

    return lpReturnValue;

BNT_BAILOUT:

    if (lWin32Status != ERROR_SUCCESS) {

        // if lWin32Status has error, then set last error value to it,

        // otherwise assume that last error already has value in it

        SetLastError (lWin32Status);

    }

    // free buffers used by this routine

    if (lpValueNameString) {

        free ((LPVOID)lpValueNameString);

    }

    if (lpReturnValue) {

        free ((LPVOID)lpReturnValue);

    }

    if (hKeyValue) RegCloseKey (hKeyValue);

    if (hKeyNames) RegCloseKey (hKeyNames);

    return NULL;

} // BuildNameTable

DWORD

GetSystemPerfData (

    IN HKEY hKeySystem,

    IN LPTSTR   pValue,

    IN PPERF_DATA_BLOCK *pPerfData

)

/*++

GetSystemPerfData

    Allocates data buffer as required and queries performance data

    specified in pValue from registry.

Arguments

    hKeySystem

        Handle to performance data in registry

    pValue

        Value string to return from registry

    pPerfData

        address of pointer to allocated perf data block that is

        filled in by call to RegQueryValue.

Return Value

    ERROR_SUCCESS if data returned

    WIN 32 ERROR if error encountered

--*/

{  // GetSystemPerfData

    LONG     lError ;   // Win 32 Error returned by fn. calls

    DWORD    Size;      // size of data buffer passed to fn. call

    DWORD    Type;      // type of data buffer returned by fn. call

    // allocate initial buffer if one is not passed into this routine

    if (*pPerfData == NULL) {

        *pPerfData = malloc (INITIAL_SIZE);

        if (*pPerfData == NULL) {

            return ERROR_OUTOFMEMORY;

        }

    }

    while (TRUE) {

        Size = _msize (*pPerfData); // query the size of the data buffer

        lError = RegQueryValueEx (  // get performance data from reg.

            hKeySystem,

            pValue,

            RESERVED,

            &Type,

            (LPBYTE)*pPerfData,

            &Size) ;

        // check for success and valid perf data block signature

        if ((!lError) &&

            (Size > 0) &&

            (*pPerfData)->Signature[0] == (WCHAR)'P' &&

            (*pPerfData)->Signature[1] == (WCHAR)'E' &&

            (*pPerfData)->Signature[2] == (WCHAR)'R' &&

            (*pPerfData)->Signature[3] == (WCHAR)'F' ) {

            return (ERROR_SUCCESS) ;

        }

        // if buffer is not big enough, reallocate and try again

        if (lError == ERROR_MORE_DATA) {

            *pPerfData = realloc (

                *pPerfData,

                _msize (*pPerfData) +

                EXTEND_SIZE) ;

            if (!*pPerfData) {

                return (lError) ;

            }

        } else {

            return (lError) ;

        }

    }

}  // GetSystemPerfData

/*++

Pointer Functions

    These functions are used to walk down the various structures

    in the perf data block returned by the call to RegQueryValueEx

--*/

PPERF_OBJECT_TYPE

FirstObject (

    PPERF_DATA_BLOCK pPerfData

)

{

    return ((PPERF_OBJECT_TYPE) ((PBYTE) pPerfData + pPerfData->HeaderLength)) ;

}

PPERF_OBJECT_TYPE

NextObject (

    PPERF_OBJECT_TYPE pObject

)

{  // NextObject

    return ((PPERF_OBJECT_TYPE) ((PBYTE) pObject + pObject->TotalByteLength)) ;

}  // NextObject

PERF_COUNTER_DEFINITION *

FirstCounter(

    PERF_OBJECT_TYPE *pObjectDef

)

{

    return (PERF_COUNTER_DEFINITION *)

               ((PCHAR) pObjectDef + pObjectDef->HeaderLength);

}

PERF_COUNTER_DEFINITION *

NextCounter(

    PERF_COUNTER_DEFINITION *pCounterDef

)

{

    return (PERF_COUNTER_DEFINITION *)

               ((PCHAR) pCounterDef + pCounterDef->ByteLength);

}

PERF_INSTANCE_DEFINITION *

FirstInstance (

    PERF_OBJECT_TYPE    *pObject

)

{

    return (PERF_INSTANCE_DEFINITION *)

        ((PBYTE) pObject + pObject->DefinitionLength);

}

PERF_INSTANCE_DEFINITION *

NextInstance (

    PERF_INSTANCE_DEFINITION *pInstance

)

{

    // next instance is after this instance + this instances counter data

    PERF_COUNTER_BLOCK  *pCtrBlk;

    pCtrBlk = (PERF_COUNTER_BLOCK *)

        ((PBYTE)pInstance + pInstance->ByteLength);

    return (PERF_INSTANCE_DEFINITION *)

        ((PBYTE)pInstance + pInstance->ByteLength + pCtrBlk->ByteLength);

}

LONG

PrintExplainText(

    DWORD   Indent,

    LPTSTR  szTextString

)

/*++

PrintExplainText

    Prints Long strings in a wrapped format for display on screen

Arguments

    Indent

        number of characters to indent text from left margin

    szTextString

        string to print on stdout

ReturnValue

    number of lines of text printed

--*/

{

    LPTSTR  szThisChar;

    BOOL    bNewLine;

    DWORD   dwThisPos;

    DWORD   dwLinesUsed;

    szThisChar = szTextString;

    dwLinesUsed = 0;

    // check arguments

    if (!szTextString) {

        return dwLinesUsed;

    }

    if (Indent > WRAP_POINT) {

        return dwLinesUsed; // can't do this

    }

    bNewLine = TRUE;

    // print text

    while (*szThisChar) {

        if (bNewLine){

            for (dwThisPos = 0; dwThisPos < Indent; dwThisPos++) {

                printf (" ");

            }

            bNewLine = FALSE;

        }

        if ((*szThisChar == ' ') && (dwThisPos >= WRAP_POINT)) {

            printf ("\n");

            bNewLine = TRUE;

            // go to next printable character

            while (*szThisChar <= ' ') {

                szThisChar++;

            }

            dwLinesUsed++;

        } else {

            printf ("%c", *szThisChar);

            szThisChar++;

        }

        dwThisPos++;

    }

    printf ("\n");

    bNewLine = TRUE;

    dwLinesUsed++;

    return dwLinesUsed;

} // PrintExplainText

DWORD

ProcessCommandLine (

    IN LPTSTR  lpCmdLine,

    IN LPTSTR  *lppCounterNames,

    IN DWORD   dwLastCounter,

    OUT LPTSTR  *lpValueString

)

/*++

ProcesCommandLine

    Reads arguments in command line and determines what program should do.

    Command line syntax is:

        PERFEX [ ? | Object]

    if "?" is in command line, then list of counter objects is displayed

    if a text string (other than "?") then string is translated to a

    counter object id and the counters for that object are displayed

Arguments

    lpCmdLine

        null terminated string that contains command line arguments

    lppCounterNames

        pointer to array of counter names (used for lookup)

    dwLastCounter

        number of elements in CounterNames array

    lpValueString

        value string to send to ReqQueryValue in order to return counter

        data for specified counter

ReturnValue

    TRUE    if valid data is returned

    FALSE   if unable to process command line (command syntax help should

            be displayed).

--*/

{

    LPTSTR   lpLocalString;

    DWORD   dwReturnValue;

    DWORD   dwElem;

    dwReturnValue = COMMAND_ERROR;  // assume error until proven otherwise

    lpLocalString = lpCmdLine;

    // move pointer past exe name

    while ((*lpLocalString > ' ') && (*lpLocalString)) lpLocalString++;

    // move pointer to next non-space char;

    while ((*lpLocalString <= ' ') && (*lpLocalString)) lpLocalString++;

    if (*lpLocalString) {

        // check for "HELP" command line argument

        if (*lpLocalString == '-') {

            if (*++lpLocalString == '?') {

                *lpValueString = Global;

                dwReturnValue = COMMAND_HELP;

            }

        } else { // first arg is not preceded by a '-' so compare to counters

            // see if command line matches a counter name

            for (dwElem = 0; dwElem <= dwLastCounter; dwElem++) {

                // compare counter name to command line

                if ((lstrcmpi(lppCounterNames[dwElem], lpLocalString)) == 0) {

                    // match found

                    // make element Number a string and exit

                    _stprintf ((LPTSTR)&cValueName[0], TEXT("%d"), dwElem);

                    *lpValueString = (LPTSTR)&cValueName[0];

                    dwReturnValue = COMMAND_COUNTER;

                    break;  // out of for loop

                } // endif command line matches string

            } // end for loop that searches table

        } // if not "-?"

    } else {

        dwReturnValue = COMMAND_ERROR;

    }

    return dwReturnValue;

} // ProcessCommandLine

VOID

DisplayObjectNames (

    PPERF_DATA_BLOCK    pPerf,

    LPTSTR              *pNames

)

/*++

DisplayObjectNames

    Scans the perf data and prints the name of each object found in the

    list

Arguments

    pPerf

        pointer to the perf data block returned by the call to

        RegQueryValueEx

    pNames

        pointer to the name table containing the array of counter names

        and explain text pointers.

Return Value

    NONE

--*/

{

    DWORD       dwThisObject;   // count of objects

    PPERF_OBJECT_TYPE pThisObject;    // pointer to object structure

    printf ("\nThe available performance counter objects are:");

    // loop from first object in buffer returned and display the

    // number of objects in the buffer

    for (dwThisObject = 0, pThisObject = FirstObject (pPerf);

        dwThisObject < pPerf->NumObjectTypes;

        dwThisObject++, pThisObject = NextObject(pThisObject)) {

        printf ("\n\"%ws\"\n",

            pNames[pThisObject->ObjectNameTitleIndex]);

        PrintExplainText (OBJECT_TEXT_INDENT,

            pNames[pThisObject->ObjectHelpTitleIndex]);

    }

} // DisplayObjectNames

VOID

DisplayCounterData (

    PPERF_DATA_BLOCK    pPerf,

    LPTSTR              *pNames

)

/*++

DisplayCounterData

    Scans the perf data and prints the name of counter and instance found

    in the list

Arguments

    pPerf

        pointer to the perf data block returned by the call to

        RegQueryValueEx

    pNames

        pointer to the name table containing the array of counter names

        and explain text pointers.

Return Value

    NONE

--*/

{

    DWORD               dwThisObject;   // count of objects

    PPERF_OBJECT_TYPE   pThisObject;    // pointer to object structure

    DWORD               dwThisCounter;  // count of counters

    PPERF_COUNTER_DEFINITION    pThisCounter;

    LONG               lThisInstance;

    PPERF_INSTANCE_DEFINITION   pThisInstance;

    // for each object in buffer, display each counter and instance

    for (dwThisObject = 0, pThisObject = FirstObject (pPerf);

        dwThisObject < pPerf->NumObjectTypes;

        dwThisObject++, pThisObject = NextObject(pThisObject)) {

        printf ("\n\nThe object \"%ws\", ",

            pNames[pThisObject->ObjectNameTitleIndex]);

        // if there are instnances, then loop through all instances

        // of this object

        if (pThisObject->NumInstances != PERF_NO_INSTANCES) {

            printf (" which has the following instances:");

            for (lThisInstance = 0, pThisInstance = FirstInstance(pThisObject);

                lThisInstance < pThisObject->NumInstances;

                lThisInstance++, pThisInstance = NextInstance(pThisInstance)) {

                printf ("\n\t\"%ws\"",

                    (LPWSTR)((PBYTE)pThisInstance + pThisInstance->NameOffset));

            }

            printf ("\n");

        } else {

            printf (" which has only one occurance,");

        }

        // now display all counters described in this object

        printf ("\nand has the following counters:");

        for (dwThisCounter = 0, pThisCounter = FirstCounter (pThisObject);

            dwThisCounter < pThisObject->NumCounters;

            dwThisCounter++, pThisCounter = NextCounter(pThisCounter)) {

            printf ("\n    \"%ws\"",

                    pNames[pThisCounter->CounterNameTitleIndex]);

        }

    }

} // DisplayCounterData

int

_CRTAPI1 main(

    int argc,

    char *argv[]

)

/*++

main

    entry point to perfex

    This program illustrates how to:

        get performance counter names and explain text from the registry

        obtain counter object value strings for use in querying perf. data

        walk the performance data structures returned by the registry

    This program does not show how to:

        format or process the counter data returned

            the counter data returned by the registry depends on the

            counter type. This data must be processed and formatted by

            the application program.

Arguments

    argc

        # of command line arguments present

    argv

        array of pointers to command line strings

    (note that these are obtained from the GetCommandLine function in

    order to work with both UNICODE and ANSI strings.)

ReturnValue

    0 (ERROR_SUCCESS) if command was processed

    Non-Zero if command error was detected.

--*/

{

    LPTSTR  *lpCounterText; // array of counter name strings

    LPTSTR  lpCommandLine;  // pointer to command line string

    LPTSTR  lpValueString;  // value string to pass to registry for data

    DWORD   dwLastElement;  // number of elements in lpCounterText

    PPERF_DATA_BLOCK  pDataBlock; // pointer to perfdata block

    DWORD   dwStatus;       // return status of fn. calls

    DWORD   dwAction;       // display mode indicated by command line

    // query counter names from registry and load into table

    lpCounterText = BuildNameTable (

        HKEY_LOCAL_MACHINE,

        DefaultLangId,

        &dwLastElement);

    if (!lpCounterText) {

        printf ("ERROR: Unable to read counter names from registry.");

        return (TRUE);

    }

    lpCommandLine = GetCommandLine(); // get command line

    // read command line to determine what to do

    dwAction = ProcessCommandLine (lpCommandLine,

        lpCounterText,

        dwLastElement,

        &lpValueString);

    if (dwAction == COMMAND_ERROR) { // if unable to read command line

        DisplayCommandHelp();        // display command line usage

        free (lpCounterText);        // free buffer and return error

        return (TRUE);

    } else {

        // of command requires processing, then get perf data from reg.

        pDataBlock = NULL;

        dwStatus = GetSystemPerfData (

            HKEY_PERFORMANCE_DATA,

            lpValueString,

            &pDataBlock);

        if (dwStatus != ERROR_SUCCESS) {

            printf ("\nERROR: Unable to obtain data for that counter");

            free (lpCounterText);

            return (dwStatus);

        } else {

            // if data was returned, then display in format requested by

            // command line

            if (dwAction == COMMAND_HELP) {

                // display object names returned from registry

                DisplayObjectNames (pDataBlock, lpCounterText);

            } else {

                // display counter data for specified object

                DisplayCounterData (pDataBlock, lpCounterText);

            }

        }

        free (lpCounterText);

        return (ERROR_SUCCESS); // success

    }

}


  66.2.2  Displaying Counter Title Indices

This section includes example code that displays counter-title indices and their names.

#define UNICODE 1

#define _UNICODE 1

#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

#include <windows.h>

#include <string.h>

#include <memory.h>

#include <process.h>

#include <tchar.h>

#define SZ_DUMMY 10

int GetRegDataBound(HKEY hkey)

{

    TCHAR chDummy[SZ_DUMMY];

    DWORD cSubKeys;

    DWORD cbMaxSubkey;

    DWORD cbMaxClass;

    DWORD cValues;

    DWORD cbMaxValueName;

    DWORD cbMaxValueData;

    DWORD cbSecurityDescriptor;

    FILETIME ftLastWriteTime;

    DWORD lErr;

    DWORD cbClassSize = SZ_DUMMY;

    lErr = RegQueryInfoKey(hkey, chDummy, &cbClassSize,

        NULL, &cSubKeys, &cbMaxSubkey, &cbMaxClass,

        &cValues, &cbMaxValueName, &cbMaxValueData,

        &cbSecurityDescriptor, &ftLastWriteTime);

    if (lErr == ERROR_SUCCESS)

        return cbMaxValueData;

    else

        return -1;

}

int

_CRTAPI1 main(

)

{

    HKEY hKeyData;

    LONG lErr;

    LPTSTR lptstr;

    int   iSize;

    DWORD dwType;

    DWORD dwSize;

    int   iIndex;

    lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,

        TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\409"),

        0, KEY_ALL_ACCESS, &hKeyData);

    assert(lErr == ERROR_SUCCESS);

    iSize = GetRegDataBound(hKeyData);

    if (iSize == -1)

        exit(-1);

    iSize++;

    lptstr = malloc(iSize * sizeof(TCHAR));

    dwSize = iSize;

    lErr = RegQueryValueEx(hKeyData, TEXT("Counters"), 0, &dwType,

        (LPBYTE) lptstr, &dwSize);

    assert(lErr == ERROR_SUCCESS);

    while (*lptstr) {

        _stscanf (lptstr, TEXT(" %d"), &iIndex);

//        iIndex = atoi(lptstr);

        lptstr += lstrlen(lptstr) + 1;

        printf("#define CNTR_%.3d\t \"%ws\"\n", iIndex, lptstr);

        lptstr += lstrlen(lptstr) + 1;

    }

    lErr = RegCloseKey(hKeyData);

    assert(lErr == ERROR_SUCCESS);

    return 0;

}


  66.3  Functions

Following are the functions used for performance monitoring.

RegConnectRegistry
RegQueryValueEx
QueryPerformanceCounter
QueryPerformanceFrequency


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


System Information
  Chapter 67    System Information

67.1  About System Information

The Microsoft Win32 application programming interface (API) includes functions that describe the current system configuration. These functions retrieve a variety of data, such as the computer name, user name, settings of environment variables, processor type, system colors, and so on. It also includes functions that can change the system configuration, shut down the system, and start the Windows Help application.


  67.1.1  System Configuration

Several of the functions in the Win32 API are specifically intended to describe or change the system configuration. At startup, for example, a computer is assigned the name listed in the registry. An application can retrieve this name by using the GetComputerName function and can change the name by using the SetComputerName function. SetComputerName changes the registry, not the current computer name. As a result, the new name is not assigned until the computer is restarted. For more information about the registry, see Chapter 52, »Registry and Initialization Files«.

The GetUserName function retrieves the name of the user currently logged onto the system. The user name is either the logon name or the user's full name, if the latter is included in the registry.

The GetSystemInfo function retrieves processor and memory information, such as the page size, original equipment manufacturer (OEM) identifier, number and type of processors, application address range, and so on. The GetVersion function retrieves the major and minor revision numbers of the installed version of Microsoft Windows. The GetKeyboardType function retrieves such information as the type of keyboard and the number of function keys on the current keyboard.

The SystemParametersInfo function retrieves or sets various system attributes, such as double-click time, screen saver time-out, window border width, and desktop pattern. When an application uses SystemParametersInfo to set a parameter, the change takes place immediately. This function also enables applications to update the user profile so changes to the system will be preserved when the system is restarted.

The GetThreadDesktop function retrieves a handle of the desktop for a given thread. This handle can be used in calls to functions that retrieve and set security attributes.

The Windows directory is the directory that contains Windows-based applications, initialization files, and Help files. The GetWindowsDirectory function retrieves the path to this directory. Applications that create files should do so in the Windows directory. This is the only directory guaranteed to be private to a user running a shared version of Windows.

The system directory is the directory that contains Windows libraries, drivers, and font files. The GetSystemDirectory function retrieves the path to this directory.

An environment variable is a symbolic variable that represents some element of the system, such as a path, a filename, or other literal data. For example, the environment variable PATH represents the directories in which to search for executable files. When a user logs on, the system initializes environment variables based on the environment section of the registry. The ExpandEnvironmentStrings function retrieves the values of specified environment variables.

System metrics are the dimensions of various Windows display elements. (Display elements are the parts of a window and the Windows display that appear on the system display screen.) Typical system metrics include the window border width, icon height, and so on. System metrics also describe other aspects of the system, such as whether a mouse is installed, double-byte characters are supported, or a debugging version of Windows is installed. The GetSystemMetrics function retrieves a specified system metric.

Applications can also retrieve and set the color of window elements such as menus, scroll bars, and buttons by using the GetSysColor and SetSysColors functions, respectively.


  67.1.2  System Shutdown

The Win32 API also provides a way for an application to shut down a local or remote computer. This is particularly useful for system administrators who update system software on remote computers. The InitiateSystemShutdown function starts a timer and displays a dialog box that prompts the user to log off. While the dialog box is displayed, the AbortSystemShutdown function can stop the timer and prevent the computer from shutting down. However, if the timer expires, the computer is shut down. InitiateSystemShutdown can also restart the computer following shutdown.


  67.1.3  Windows Help

Applications can provide help to users by starting the Windows Help application. The WinHelp function opens the specified Help file to an appropriate context, if specified.


  67.2  Using System Information

These sections explain how to perform the following tasks:

•	Get system configuration information

•	Get hardware information

•	Change the color of a window element

•	Shut down the system

•	Start Windows Help


  67.2.1  Getting System Configuration Information

The following example uses the GetComputerName, GetUserName, GetSystemDirectory, GetWindowsDirectory, and ExpandEnvironmentStrings functions to get information that describes the system configuration. This example displays the information in a window's client area.

LPTSTR lpszSystemInfo;    /* ptr. to system info. string */

DWORD cchBuff = 256;      /* size of comp. or user name  */

TCHAR tchBuffer2[BUFFER]; /* buffer for concat'd. str.   */

DWORD dwResult;           /* function return value       */

SYSTEM_INFO siSysInfo;    /* struct. for hardware info.  */

int aTabs[1] = {260};     /* tab stop for TabbedTextOut  */

TCHAR tchBuffer[BUFFER];  /* buffer for expanded string  */

int nSize;                /* size of string              */

lpszSystemInfo = tchBuffer2;

/* Get and display the name of the computer. */

GetComputerName(lpszSystemInfo, &cchBuff);

nSize = sprintf(tchBuffer, "Computer name:  %s",

    lpszSystemInfo);

TextOut(hdc, 15, 20, tchBuffer, nSize);

/* Get and display the user name. */

GetUserName(lpszSystemInfo, &cchBuff);

nSize = sprintf(tchBuffer, "User name:  %s",

    lpszSystemInfo);

TextOut(hdc, 15, 40, tchBuffer, nSize);

/* Get and display the system directory. */

nSize = GetSystemDirectory(lpszSystemInfo, MAX_PATH);

nSize = sprintf(tchBuffer, "System directory:  %s",

    lpszSystemInfo);

TextOut(hdc, 15, 60, tchBuffer, nSize);

/* Get and display the Windows directory. */

nSize = GetWindowsDirectory(lpszSystemInfo, MAX_PATH);

nSize = sprintf(tchBuffer, "Windows directory:  %s",

    lpszSystemInfo);

TextOut(hdc, 15, 80, tchBuffer, nSize);

/* Display the "environment variables" header. */

nSize = sprintf(tchBuffer,

    "Environment variables (partial list):");

TextOut(hdc, 15, 105, tchBuffer, nSize);

/* Expand the OS and NTVERSION environment variables. */

dwResult = ExpandEnvironmentStrings(

               "OS=%OS%     NTVERSION=%NTVERSION%",

               lpszSystemInfo,

               BUFFER);

TextOut(hdc, 25, 120, (LPCTSTR) lpszSystemInfo,

    dwResult - 1);

/* Expand the PATH environment variable. */

dwResult = ExpandEnvironmentStrings(

               "PATH=%PATH%",

               lpszSystemInfo,

               BUFFER);

TextOut(hdc, 25, 135, (LPCTSTR) lpszSystemInfo,

    dwResult - 1);

/* Expand the LIBPATH environment variable. */

dwResult = ExpandEnvironmentStrings(

               "LIBPATH=%LIBPATH%",

               lpszSystemInfo,

               BUFFER);

TextOut(hdc, 25, 150, (LPCTSTR) lpszSystemInfo,

    dwResult - 1);

/* Expand the TMP environment variable. */

dwResult = ExpandEnvironmentStrings(

               "TMP=%TMP%",

               lpszSystemInfo,

               BUFFER);

TextOut(hdc, 25, 165, (LPCTSTR) lpszSystemInfo,

    dwResult - 1);

The next example uses the GetVersion function to obtain the current version of Windows and then displays the version number in a message box.

DWORD dwResult;          /* function return value      */

TCHAR tchBuffer[BUFFER]; /* buffer for expanded string */

int nSize;               /* size of string             */

dwResult = GetVersion();

nSize = sprintf(tchBuffer, "Windows version %d.%d\n",

    LOBYTE(LOWORD(dwResult)),

    HIBYTE(LOWORD(dwResult)));

MessageBox(NULL, tchBuffer, "GetVersion", MB_ICONINFORMATION);


  67.2.2  Getting Hardware Information

The following example uses the GetSystemInfo function to obtain hardware information such as the OEM identifier, processor type, page size, and so on. The example displays the information in a window's client area.

SYSTEM_INFO siSysInfo;   /* struct. for hardware info. */

int aTabs[1] = {260};    /* tab stop for TabbedTextOut */

TCHAR tchBuffer[BUFFER]; /* buffer for expanded string */

int nSize;               /* size of string             */

/* Display the "hardware information" header. */

nSize = sprintf(tchBuffer,

    "Hardware information:");

TextOut(hdc, 15, 20, tchBuffer, nSize);

/* Copy the hardware information to the SYSTEM_INFO structure. */

GetSystemInfo(&siSysInfo);

/* Display the contents of the SYSTEM_INFO structure. */

nSize = sprintf(tchBuffer,

    "OEM ID: %u\tNumber of Processors: %u",

    siSysInfo.dwOemId,

    siSysInfo.dwNumberOfProcessors);

TabbedTextOut(hdc, 25, 40, tchBuffer,

    nSize, 1, aTabs, 25);

nSize = sprintf(tchBuffer,

    "Page size: %u\tProcessor Type: %u",

    siSysInfo.dwPageSize,

    siSysInfo.dwProcessorType);

TabbedTextOut(hdc, 25, 60, tchBuffer,

    nSize, 1, aTabs, 25);

nSize = sprintf(tchBuffer,

    "Minimum app address: %lx\tMaximum app address: %lx",

    siSysInfo.lpMinimumApplicationAddress,

    siSysInfo.lpMaximumApplicationAddress);

TabbedTextOut(hdc, 25, 80, tchBuffer,

    nSize, 1, aTabs, 25);

nSize = sprintf(tchBuffer,

    "Active processor mask: %u",

    siSysInfo.dwActiveProcessorMask);

TextOut(hdc, 25, 100, tchBuffer, nSize);

The following example uses the GetSystemMetrics function to determine whether a mouse is installed and whether the mouse buttons are swapped. The example also uses the SystemParametersInfo function to retrieve the mouse threshold and speed. It displays the information in a message box.

TCHAR tchBuffer[BUFFER]; /* buffer for expanded string */

int nSize;               /* size of string             */

BOOL fResult;            /* system shutdown flag       */

int aMouseInfo[3];       /* array for mouse info.      */

/* Is there a mouse? */

fResult = GetSystemMetrics(SM_MOUSEPRESENT);

if (fResult == 0) {

    /* Indicate if there is no mouse. */

    nSize = sprintf(tchBuffer, "No mouse installed.");

} else {

    /*

     * If there is a mouse, determine if

     * its buttons are swapped.

     */

    fResult = GetSystemMetrics(SM_SWAPBUTTON);

    if (fResult == 0) {

        nSize = sprintf(tchBuffer, "Buttons not swapped.\r");

    } else {

        nSize = sprintf(tchBuffer, "Buttons swapped.\r");

    }

    /* Get the mouse speed and the threshold values. */

    SystemParametersInfo(SPI_GETMOUSE, /* get mouse info.   */

        NULL,                          /* not used          */

        &aMouseInfo,                   /* holds mouse info. */

        NULL);                         /* not used          */

    nSize += sprintf(tchBuffer + nSize,

        "Speed: %d\r", aMouseInfo[2]);

    sprintf(tchBuffer + nSize,

        "Threshold (x,y): %d,%d",

        aMouseInfo[0], aMouseInfo[1]);

}

/* Display the mouse information. */

MessageBox(NULL, tchBuffer, "Mouse information",

    MB_ICONINFORMATION);

This next example uses SystemParametersInfo to double the mouse speed and update the MouseSpeed value in the win.ini file.

TCHAR tchBuffer[BUFFER]; /* buffer for expanded string */

int nSize;               /* size of string             */

int aMouseInfo[3];       /* array for mouse info.      */

/* Get the current mouse speed. */

SystemParametersInfo(SPI_GETMOUSE, /* get mouse info.   */

    NULL,                          /* not used          */

    &aMouseInfo,                   /* holds mouse info. */

    NULL);                         /* not used          */

/* Double it. */

aMouseInfo[2] = 2 * aMouseInfo[2];

/* Change the mouse speed to the new value and update WIN.INI. */

SystemParametersInfo(SPI_SETMOUSE, /* set mouse info.    */

    NULL,                          /* not used           */

    aMouseInfo,                    /* mouse info. to set */

    SPIF_UPDATEINIFILE);           /* update win.ini     */


  67.2.3  Changing the Colors of Window Elements

The following example uses the SetSysColor function to change the color of active window borders to dark purple, of active title bars to dark cyan, and of the window background to light gray.

                          /* window elements to change */

int aiElements[3] = {COLOR_ACTIVEBORDER,

                     COLOR_ACTIVECAPTION,

                     COLOR_WINDOW};

DWORD aColors[3];               /* array of RGB values */

/* Define the new colors. */

aColors[0] = RGB(0x80, 0x00, 0x80);  /* dark purple */

aColors[1] = RGB(0x00, 0x80, 0x80);  /* dark cyan   */

aColors[2] = RGB(0xC0, 0xC0, 0xC0);  /* light gray  */

/*

 * Set the window elements in aiElements to the colors

 * specified in aColors.

 */

SetSysColors(3, aiElements, aColors);

The next example uses the GetSysColors function to retrieve the color of the window background and displays the red, green, blue (RGB) value, in hexadecimal notation, in a message box.

DWORD dwResult;          /* function return value      */

TCHAR tchBuffer[BUFFER]; /* buffer for expanded string */

int nSize;               /* size of string             */

/* Get the color of the window background. */

dwResult = GetSysColor(COLOR_WINDOW);

nSize = sprintf(tchBuffer,

    "Window color: {%x, %x, %x}",

    GetRValue(dwResult),

    GetGValue(dwResult),

    GetBValue(dwResult));

MessageBox(NULL, tchBuffer, "GetSysColor", MB_ICONINFORMATION);


  67.2.4  Shutting Down the System

The following example uses the InitiateSystemShutdown function to begin the system shutdown process on the local computer. Note that the application must first enable the SE_SHUTDOWN_NAME privilege to shut down the computer the user is logged onto.

HANDLE hToken;               /* handle to process token  */

TOKEN_PRIVILEGES tkp;        /* ptr. to token structure  */

BOOL fResult;                /* system shutdown flag     */

/*

 * Get the current process token handle

 * so we can get shutdown privilege.

 */

if (!OpenProcessToken(GetCurrentProcess(),

        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

    ErrorHandler("OpenProcessToken failed.");

/* Get the LUID for shutdown privilege. */

LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,

        &tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;  /* one privilege to set    */

tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

/* Get shutdown privilege for this process. */

AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

    (PTOKEN_PRIVILEGES) NULL, 0);

/* Cannot test the return value of AdjustTokenPrivileges. */

if (GetLastError() != ERROR_SUCCESS)

    ErrorHandler("AdjustTokenPrivileges enable failed.");

/* Display the shutdown dialog box and start the time-out countdown. */

fResult = InitiateSystemShutdown(

    NULL,            /* shut down local computer */

    "Click on the main window and press \

     the Escape key to cancel shutdown.",

                   /* msg. to user               */

    20,            /* time-out period            */

    FALSE,         /* prompt user to close apps. */

    TRUE);         /* reboot after shutdown      */

if (!fResult) {

    ErrorHandler("InitiateSystemShutdown failed.");

}

/* Disable shutdown privilege. */

tkp.Privileges[0].Attributes = 0;

AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES) NULL, 0);

if (GetLastError() != ERROR_SUCCESS)

    ErrorHandler("AdjustTokenPrivileges disable failed.");

If the AbortSystemShutdown function is executed in the time-out period specified by InitiateSystemShutdown, the system does not shut down. The following example enables the user to prevent the system from shutting down by clicking on the application's main window and pressing the esc key. As noted earlier, your application must enable the SE_SHUTDOWN_NAME privilege to stop the system shutdown.

HANDLE hToken;              /* handle to process token */

TOKEN_PRIVILEGES tkp;       /* ptr. to token structure */

BOOL fResult;               /* system shutdown flag    */

case WM_KEYDOWN:

    /* Process only the Escape key. */

    if (wParam != VK_ESCAPE) {

        break;

    }

    /*

     * Get the current process token handle

     * so we can get shutdown privilege.

     */

    if (!OpenProcessToken(GetCurrentProcess(),

            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

        ErrorHandler("OpenProcessToken failed.");

    /* Get the LUID for shutdown privilege. */

    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,

            &tkp.Privileges[0].Luid);

    tkp.PrivilegeCount = 1;  /* one privilege to set    */

    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    /* Get shutdown privilege for this process. */

    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES)NULL, 0);

    /* Cannot test the return value of AdjustTokenPrivileges. */

    if (GetLastError() != ERROR_SUCCESS)

        ErrorHandler("AdjustTokenPrivileges enable failed.");

    /* Prevent the system from shutting down. */

    fResult = AbortSystemShutdown(NULL);

    if (!fResult) {

        ErrorHandler("AbortSystemShutdown failed.");

    }

    /* Disable shutdown privilege. */

    tkp.Privileges[0].Attributes = 0;

    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,

        (PTOKEN_PRIVILEGES) NULL, 0);

    if (GetLastError() != ERROR_SUCCESS)

        ErrorHandler("AdjustTokenPrivileges disable failed.");

    break;


  67.2.5  Starting Windows Help

The following example uses the WinHelp function to start the Windows Help application, open the Win32 API Help file, and display the Help file index.

HWND            hwnd;           /* main window handle         */

/* Start Windows Help; display index of Win32 API Help file. */

WinHelp(hwnd, "api32wh.hlp", HELP_INDEX, NULL);

This next example opens the Win32 API Help file, searches the file for the "menus" topic, and displays the topic.

HWND            hwnd;           /* main window handle         */

/* Start Windows Help; display menus topic of Win32 API Help. */

WinHelp(hwnd, "api32wh.hlp", HELP_KEY, (DWORD) "menus");


  67.3  Functions

Following are the functions used to retrieve or set system information, shut down the system, or start Windows Help.

AbortSystemShutdown
ExpandEnvironmentStrings
GetComputerName
GetKeyboardType
GetSysColor
GetSystemDirectory
GetSystemInfo
GetSystemMetrics
GetThreadDesktop
GetUserName
GetVersion
GetWindowsDirectory
InitiateSystemShutdown
SetComputerName
SetSysColors
SystemParametersInfo
WinHelp
DOS3Call (Obsolete)
GetCurrentPDB (Obsolete)
GetCurrentTask (Obsolete)
GetDOSEnvironment (Obsolete)
GetSystemDir (Obsolete)
GetWindowsDir (Obsolete)
GetWinFlags (Obsolete)
IsTask (Obsolete)


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Communications
  Chapter 68    Communications

68.1  About Communications

A communications resource is a physical or logical device that provides a single bidirectional, asynchronous data stream. Serial ports, parallel ports, fax machines, and modems are examples of communications resources. For each communications resource, there is a service provider, consisting of a library or driver, that enables applications to access the resource.

The file input and output (I/O) functions (CreateFile, CloseHandle, ReadFile, ReadFileEx, WriteFile, and WriteFileEx) provide the basic interface for opening and closing a communications resource handle and for read and write operations. The Win32 application programming interface (API) also includes a set of communications functions that provide access to communications resources. This chapter describes the use of file I/O and communications functions, which enable applications to perform the following tasks:

•	Open a handle to a specified communications resource.

•	Set and query the configuration of a serial communications resource.

•	Read from or write to a serial communications resource.

•	Monitor a specified set of events that might occur for a given serial communications resource.

•	Send a control command to the device driver associated with a specified communications resource, causing the driver to execute an extended function.


  68.1.1  Communications Resource Handles

A process uses the CreateFile function to open a handle to a communications resource. For example, specifying COM1 opens a handle to a serial port, and LPT1 opens a handle to a parallel port. If the specified resource is currently being used by another process, CreateFile fails. Any thread of the process can use the handle returned by CreateFile to identify the resource in any of the functions that access the resource.

When using CreateFile to open a handle directly to a device, an application must use the special characters "\." to identify the device. For example, to open a handle to drive A, specify "\.a:" for the lpszName parameter of CreateFile. The calling process can use the handle in the DeviceIoControl function to send control codes to the device.

When the process calls CreateFile to open a communications resource, it specifies the following attributes:

•	The type of read-write access to the specified resource.

•	Whether the handle can be inherited by child processes.

•	Whether the handle can be used in overlapped (asynchronous) I/O operations.

•	a description of overlapped operations, see Section 68.1.3, »Read and Write Operations«.)

When the process uses CreateFile to open a communications resource, it must specify certain values for the following parameters:

•	The fdwShareMode parameter must be zero, opening the resource for exclusive access.

•	The fdwCreate parameter must specify the OPEN_EXISTING flag.

•	The hTemplateFile parameter must be NULL.


  68.1.2  Serial Communications Resource Configuration

When the CreateFile function opens a handle to a serial communications resource, the system initializes and configures the resource according to the values set up the last time the resource was opened. Preserving the previous settings enables the user to retain the settings specified through an MS-DOS MODE command when the device is reopened. The values inherited from the previous open operation include the configuration settings of the device control block (a DCB structure) and the timeout values used in I/O operations. If the device has never been opened, it is configured with the system defaults.

To determine the initial configuration of a serial communications resource, a process calls the GetCommState function, which fills in a serial port DCB structure with the current configuration settings. To modify this configuration, a process specifies a DCB structure in a call to the SetCommState function.

Members of the DCB structure specify the configuration settings such as the baud rate, the number of data bits per byte, and the number of stop bits per byte. Other DCB members specify special characters and enable parity checking and flow control. When a process needs to modify only a few of these configuration settings, it should first call GetCommState to fill in a DCB structure with the current configuration. Then the process can adjust the important values in the DCB structure and reconfigure the device by calling SetCommState and specifying the modified DCB structure. This procedure ensures that the unmodified members of the DCB structure contain appropriate values. For example, a common error occurs when a device is configured with a DCB structure in which the structure's XonChar member is equal to the XoffChar member. Some members of the DCB structure are different from those in previous versions of Windows. In particular, the flags for controlling RTS (request-to-send) and DTR (data-terminal-ready) flow control have changed.

The BuildCommDCB function provides another way to modify a DCB structure. BuildCommDCB uses a string with the same form as the MS-DOS MODE command-line arguments to specify the baud rate, parity scheme, number of stop bits, and number of character bits. The remaining members of DCB are not changed by this function, except that the appropriate members are set to disable XON/XOFF and hardware flow control. BuildCommDCB only modifies a DCB structure; it does not reconfigure the device.

A process can reconfigure a communications resource by using the GetCommProperties function to get information from a device driver about the configuration settings that it supports. The process can use this information to avoid specifying a configuration that is not supported.

The SetCommState function reconfigures the communications resource, but it does not affect the internal output and input buffers of the specified driver. The buffers are not flushed, and pending read and write operations are not terminated prematurely.

A process reinitializes a communications resource by using the SetupComm function, which performs the following tasks:

•	Terminates pending read and write operations, even if they have not been completed.

•	Discards unread characters and frees the internal output and input buffers of the driver associated with the specified resource.

•	Reallocates the internal output and input buffers.

A process is not required to call SetupComm. If it does not, the resource's driver initializes the device with the default settings the first time that the communications resource handle is used.


  68.1.3  Read and Write Operations

The Win32 API supports both synchronous and asynchronous (overlapped) file I/O operations on serial communications resources. Overlapped operations enable the calling thread to perform other tasks while the operation executes in the background. A thread uses the ReadFile or ReadFileEx function to read from a communications resource, and the WriteFile or WriteFileEx function to write to a communications resource. ReadFile and WriteFile can be performed synchronously or asynchronously. ReadFileEx and WriteFileEx can only be performed asynchronously.

The behavior of these read and write functions is affected by whether the function is invoked as an overlapped operation; whether the timeout parameters are associated with the handle; and whether flow control parameters are associated with the handle.

A thread can also write to a communications resource by using the TransmitCommChar function, which transmits a specified character ahead of any pending data in the output buffer. This is useful in transmitting a high priority signal character to the receiving system. Transmission of the high priority character is still subject to flow control and write timeouts, and the operation is performed synchronously.

A thread can use the PurgeComm function to discard all characters in a device's output or input buffer. PurgeComm can also terminate pending read or write operations, even if the operations have not been completed. If a thread uses PurgeComm to flush an output buffer, the deleted characters are not transmitted. To empty the output buffer while ensuring that the contents are transmitted, a thread can call the FlushFileBuffers function (a synchronous operation). Note, however, that FlushFileBuffers is subject to flow control but not to write timeouts, and it will not return until all pending write operations have been transmitted.


  68.1.3.1  Overlapped Operations

Overlapped operations enable a thread to execute a time-consuming I/O operation in the background, leaving the thread free to perform other tasks. To enable overlapped I/O operations on a communications resource, the thread must specify the FILE_FLAG_OVERLAPPED flag in the CreateFile function when the handle is opened. To invoke the ReadFile or WriteFile function as an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure. If the function's OVERLAPPED pointer is NULL, the operation is performed synchronously, even though the handle was created with FILE_FLAG_OVERLAPPED enabled. The OVERLAPPED structure must contain a handle to a manual-reset (not an auto-reset) event object. The system sets the state of the event object to not-signaled when a call to the I/O function returns before the operation has been completed. The system sets the state of the event object to signaled when the operation has been completed. The thread uses wait function to check the current state of the event object or to wait for its state to be signaled.

The ReadFileEx and WriteFileEx functions can be performed only as overlapped operations. The calling thread specifies a pointer to the FileIOCompletionRoutine function, which is executed when the overlapped operation is completed. The completion routine is executed only if the calling thread performs an alertable operation.

For more information about event objects, wait functions, alertable waits, and completion routines, see Chapter 44, »Synchronization«.


  68.1.3.2  Timeouts

A handle to a communications resource has an associated set of timeout parameters that affect the behavior of read and write operations. Timeouts can cause a ReadFile, ReadFileEx, WriteFile, or WriteFileEx operation to conclude when a timeout interval elapses, even though the specified number of characters have not been read or written. It is not treated as an error when a timeout occurs during a read or write operation (that is, the read or write function's return value indicates success). The count of bytes actually read or written is reported by ReadFile or WriteFile (or by the GetOverlappedResult or FileIOCompletionRoutine function, if the I/O was performed as an overlapped operation).

When a communications resource is opened, the timeout values are set according to the values set when the resource was last opened. If the resource has never been opened or if the SetupComm function is called, all timeout parameters are set to zero. To determine the current timeout values, an application can call the GetCommTimeouts function. To change the timeout values, an application can call the SetCommTimeouts function.

Two types of timeouts are enabled by the timeout parameters. An interval timeout occurs when the time between the receipt of any two characters exceeds a specified number of milliseconds. Timing starts when the first character is received and is restarted when each new character is received. A total timeout occurs when the total amount of time consumed by a read operation exceeds a calculated number of milliseconds. Timing starts immediately when the I/O operation begins. Write operations support only total timeouts. Read operations support both interval and total timeouts, which can be used separately or combined.

The size, in milliseconds, of the total timeout period for a read or write operation is calculated by using the multiplier and constant values from the COMMTIMEOUTS structure specified in the GetCommTimeouts or SetCommTimeouts function. The following formula is used:

Timeout = (MULTIPLIER * number_of_bytes) + CONSTANT

Using both a multiplier and a constant enables the total timeout period to vary, depending on the amount of data being requested. An application can use only the constant by setting the multiplier to zero, or use only the multiplier by setting the constant to zero. If both the constant and multiplier are zero, the total timeout is not used.

If all read timeout parameters are zero, read timeouts are not used, and a read operation is not complete until the requested number of bytes have been read or an error occurs. Similarly, if all write timeout parameters are zero, a write operation is not completed until the requested number of bytes have been written or an error occurs.

If the read interval timeout parameter is the value MAXDWORD and both read total timeout parameters are zero, read operations are completed immediately after reading whatever characters are available in the input buffer, even if it is empty. This is the same as the ReadComm function in previous versions of Windows.

Interval timing forces a read operation to return when there is a lull in reception. A process using interval timeouts can set a fairly short interval parameter, so it can respond quickly to small, isolated bursts of one or a few characters, yet it can still collect large buffers of characters with a single call when data is received in a steady stream.

Timeouts for a write operation can be useful when transmission is blocked by some kind of flow control or when the SetCommBreak function has been called to suspend character transmission.

The following table summarizes the behavior of read operations based on the values specified for interval or total timeouts.

Total	Interval	Behavior
0	0	Returns when the buffer is completely filled. The timeouts are not used.
T	0	Returns when the buffer is completely filled or when T milliseconds have elapsed since the beginning of the operation.
0	Y	Returns when the buffer is completely filled or when Y milliseconds have elapsed between the receipt of any two characters. Timing does not begin until the first character is received.
T	Y	Returns when the buffer is completely filled or when either timeout occurs.
Note, however, that timing is relative to the system controlling the physical device. For a remote device such as a modem, the timing is relative to the server system to which the modem is attached. Any network propagation delay is not factored in. For example, a client application might specify a total timeout that computes to be 500 milliseconds. When 500 milliseconds has elapsed at the server, a timeout error is returned to the client. If there is a 50 milliseconds network propagation delay, the client will not be notified of timeout until approximately 50 milliseconds after the timeout actually occurred.

The timeout parameters affect the behavior of overlapped read and write operations on a communications device. With overlapped I/O, the ReadFile, WriteFile, ReadFileEx, or WriteFileEx function can return before the operation has been completed. The timeout parameters can determine when the operation has been completed.


  68.1.3.3  Communications Errors

There are other circumstances where a read or write operation can be completed with fewer than the requested number of characters, even though a timeout has not occurred. Following are some examples:

•	Some drivers support the use of special characters, which when received, complete a read operation immediately with only the characters that have been read to that point.

•	The PurgeComm function can be invoked to prematurely terminate pending read or write operations. This function can also delete the contents of the output or input buffers, or both.

•	If a communications error occurs during a read or write operation, all I/O operations on the communications resource are terminated. Break conditions, parity errors, or framing errors are examples of such errors. When an error occurs, the process must call the ClearCommError function to clear the error flag before it can begin additional I/O operations. ClearCommError reports the specific error that occurred and the current status of the device.


  68.1.4  Communications Events

A process can monitor a set of events that occur in a communications resource. For example, an application can use event monitoring to determine when the CTS (clear-to-send) and DSR (data-set-ready) signals change state.

A process can monitor events on a given communications resource by using the SetCommMask function to create an event mask. To determine the current event mask for a communications resource, a process can use the GetCommMask function. The following table lists the events that can be monitored.

Value	Meaning
EV_BREAK	A break was detected on input.
EV_CTS	The CTS (clear-to-send) signal changed state.
EV_DSR	The DSR (data-set-ready) signal changed state.
EV_ERR	A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING	A ring indicator was detected.
EV_RLSD	The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR	Any character was received and placed in the input buffer.
EV_RXFLAG	The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY	The last character in the output buffer was sent.
After a set of events is specified, a process uses the WaitCommEvent function to wait for one of the events to occur. WaitCommEvent can be used synchronously or as an overlapped operation. For additional information about executing a function as an overlapped operation, see Section 68.1.3, »Read and Write Operations«.

When one of the events specified in the event mask occurs, the process completes the wait operation and sets an event mask variable is set to indicate the type of event detected. If the process calls SetCommMask is called for a communications resource while a wait is pending for that resource, WaitCommEvent returns an error.

Note that WaitCommEvent detects only events that occur after the wait was started. For example, if the EV_RXCHAR event is specified, the conditions of the wait are satisfied when any character is received and placed in the driver's input buffer. Characters already in the input buffer when WaitCommEvent is called do not satisfy the conditions of the wait.

When monitoring an event that occurs when a signal (CTS, DSR, and so on) changes state, WaitCommEvent reports the change, but not the current state. To query the current state of the CTS (clear-to-send), DSR (data-set-ready), RLSD (receive-line-signal-detect), and ring indicator signals, a process can use the GetCommModemStatus function.


  68.1.5  Extended Functions

Some communications functions can be invoked for a device by using the EscapeCommFunction function. This function sends a code to direct the device to execute an extended function. For example, an application can suspend character transmission with the SETBREAK code and resume transmission with the CLRBREAK code. These particular operations can also be started by calling the SetCommBreak and ClearCommBreak functions. EscapeCommFunction can also be used to implement manual modem control. For example, the CLRDTR and SETDTR codes can be used to implement manual DTR (data-terminal-ready) flow control. Note, however, that an error occurs if a process uses EscapeCommFunction to manipulate the DTR line when the device has been configured to enable DTR handshaking, or the RTS (request-to-send) line if RTS handshaking is enabled.

The DeviceIoControl function enables a process to send an extended function code directly to a specified device driver, causing the device to perform a given operation. DeviceIoControl provides an interface to a device associated with a communications resource that has functionality not supported by the standard serial communications functions. It enables an application to configure a device using parameters unique to that device as well as to invoke any device-specific functions.


  68.2  Using the Communications Functions

This section explains how to perform the following tasks:

•	Configure a communications resource.

•	Monitor communications events.


  68.2.1  Configuring a Communications Resource

The following example opens a handle to COM1 and fills in a DCB structure with the current configuration. The DCB structure is then modified and used to reconfigure the device.

DCB dcb;

HANDLE hCom;

DWORD dwError;

BOOL fSuccess;

hCom = CreateFile("COM1",

    GENERIC_READ | GENERIC_WRITE,

    0,    /* comm devices must be opened with exclusive access */

    NULL, /* no security attrs */

    OPEN_EXISTING, // comm devices must use OPEN_EXISTING

    0,    /* not overlapped I/O */

    NULL  /* hTemplate must be NULL for comm devices */

    );

if (hCom == INVALID_HANDLE_VALUE) {

    dwError = GetLastError();

    /* handle error */

}

/*

 * Omit the call to SetupComm to use the default queue sizes.

 * Get the current configuration.

 */

fSuccess = GetCommState(hCom, &dcb);

if (!fSuccess) {

    /* handle error *

}

/* Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit */

dcb.BaudRate = 9600;

dcb.ByteSize = 8;

dcb.Parity = NOPARITY;

dcb.StopBits = ONESTOPBIT;

fSuccess = SetCommState(hCom, &dcb);

if (!fSuccess) {

    /* handle error */

}


  68.2.2  Monitoring Communications Events

The following example code opens the serial port for overlapped I/O, creates an event mask to monitor CTS and DSR signals, and then waits for an event to occur. The WaitCommEvent function should be expected as an overlapped operation so the other threads of the process cannot perform I/O operations during the wait.

HANDLE hCom;

OVERLAPPED o;

BOOL fSuccess;

DWORD dwEvtMask;

hCom = CreateFile("COM1",

    GENERIC_READ | GENERIC_WRITE,

    0, /* exclusive access */

    NULL, /* no security attrs */

    OPEN_EXISTING,

    FILE_FLAG_OVERLAPPED,

    NULL

    );

if (hCom == INVALID_HANDLE_VALUE) {

    /* Deal with the error. */

}

/* Set the event mask. */

fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR);

if (!fSuccess) {

    /* deal with error */

}

/* Create an event object for use in WaitCommEvent. */

o.hEvent = CreateEvent(NULL, /* no security attributes */

    FALSE, /* auto reset event */

    FALSE, /* not signalled */

    NULL /* no name */

    );

assert(o.hEvent);

if (WaitCommEvent(hCom, &dwEvtMask, &o)) {

    if (dwEvtMask & EV_DSR) {

        /*

         * . . .

         */

    }

    if (dwEvtMask & EV_CTS) {

        /*

         * . . .

         */

    }

}


  68.3  Functions

Following are the functions used with communications devices.

BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
DeviceIoControl
EscapeCommFunction
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
PurgeComm
SetCommBreak
SetCommMask
SetCommState
SetCommTimeouts
SetupComm
TransmitCommChar
WaitCommEvent


Introduction to Multimedia Services
  Chapter 69    Introduction to Multimedia Services

69.1  About Windows Multimedia Services

Microsoft Windows provides developers with high-level and low-level services for developing multimedia applications that use the extended capabilities of a multimedia personal computer.

Windows provides the following multimedia services:

•	A Media Control Interface (MCI) for controlling media devices.

•	Extensible string-based and message-based interfaces for communicating with MCI device drivers.

•	MCI device drivers for playing and recording waveform audio, playing Musical Instrument Digital Interface (MIDI) files, and playing compact disc audio from a CD-ROM drive.

•	Low-level application programming interface (API) support for multimedia-related services.

•	Low-level support for playing and recording audio with waveform and MIDI audio devices.

•	Low-level support for precision timer services.

•	Multimedia file input and output (I/O) services that provide buffered and unbuffered file I/O and support for standard Resource Interchange File Format (RIFF) files. The services are extensible by means of custom I/O procedures that can be shared among applications.

•	A MIDI Mapper supporting standard MIDI patch services. This allows MIDI files to be authored independently of users' MIDI synthesizer setups.

•	Control Panel options that let users change display drivers, set up a screen saver, install multimedia device drivers, assign waveform sounds to system alerts, and configure the MIDI Mapper.

This chapter covers the following topics:

•	The software architecture of the multimedia services

•	The design philosophy and implementation of the multimedia services

•	Basic information about developing applications that use the multimedia services


  69.2  Architecture of Windows Multimedia Services

Although the multimedia services are provided by a number of files, the overall architecture can be viewed as consisting of just three software modules:

•	The WINMM library, which provides the MCI services and low-level multimedia support functions

•	Multimedia device drivers, which provide communication between the low-level WINMM functions and multimedia devices, such as waveform, MIDI, and timer hardware

•	Drivers for MCI, which provide high-level control of media devices


  69.3  Windows Multimedia Design Philosophy

The architecture of the multimedia services is designed around the concepts of extensibility and device independence. Extensibility allows the software architecture to accommodate advances in technology easily, without changes to the architecture itself. Device independence makes it easy to develop multimedia applications that will run on a wide range of hardware providing different levels of multimedia support. Three design elements of the system software provide extensibility and device independence:

•	A translation layer (WINMM) that isolates applications from device drivers and centralizes device-independent code

•	Run-time linking that allows the translation layer to link to the drivers it needs

•	A well-defined and consistent driver interface that minimizes special-case code and makes the installation and upgrade process easier


  69.4  Building a Multimedia Application

Before writing a multimedia application, you should be familiar with programming in the Windows environment.

When using the multimedia services, you must include the MMSYSTEM.H header file in all source-code files that call multimedia functions. This header file depends on declarations made in the WINDOWS.H header file, so you must first include WINDOWS.H. The MMSYSTEM.H header file provides function prototypes as well as definitions of multimedia data types and constants.

In addition to linking the normal Windows libraries, you must also link to the WINMM.LIB import library when linking an application that uses multimedia functions.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Media Control Interface
  Chapter 70    Media Control Interface

70.1  About the Media Control Interface

The Media Control Interface (MCI) provides applications written for Microsoft Windows with device-independent capabilities for controlling media devices such as audio hardware, videodisc players, and animation players. This chapter presents an introduction to MCI and shows how to begin using it in Windows-based applications.

MCI provides a device-independent, extensible interface for controlling virtually any type of media device. Because of the high level of device independence provided by MCI, you are encouraged to use MCI rather than low-level functions to access the multimedia capabilities of Windows.

The chapter covers the following topics:

•	The architecture of MCI

•	The MCI command set

•	MCI programming interfaces

•	Use of the command-message interface

•	The command-string interface (an introduction)

For more information about using MCI to control different types of audio devices, see Chapter 72, »High-Level Audio«.


  70.2  The Architecture of MCI

To provide extensibility, MCI is designed around an architecture that uses special MCI device drivers to interpret and execute MCI commands.

MCI device drivers can control media hardware directly or through the low-level multimedia functions provided by Windows. Most commonly used devices, such as waveform audio and Musical Instrument Digital Interface (MIDI) devices, are controlled through the low-level multimedia functions.


  70.2.1  The MCI Programming Interfaces

MCI provides two programming interfaces: command string and command message.


  70.2.1.1  The Command-String Interface

The command-string interface allows you to use English-language commands to communicate with MCI devices. For example, the following command string plays a WAVE file named TIMPANI.WAV.

play timpani.wav

The command-string interface is designed for use with high-level programming and authoring environments such as Microsoft® Visual Basic (™)  and Asymetrix® ToolBook®. Use the command-string interface for applications that provide a text-based interface to let users control MCI devices.


  70.2.1.2  The Command-Message Interface

The command-message interface uses a message-passing paradigm to communicate with MCI devices. The following example performs the same operation as the previous command-string example.

WORD wDeviceID;

MCI_PLAY_PARMS mciPlayParms;

mciSendCommand(wDeviceID,            /* device identifier */

    MCI_PLAY,                        /* command message   */

    0,                               /* flags             */

    (DWORD) (LPVOID) &mciPlayParms); /* structure         */

The command-message interface is designed to be used by applications requiring a C-language interface to control multimedia devices. Use the command-message interface for applications that directly control multimedia devices.


  70.2.2  The MCI Command Set

The MCI command set provides a generic core set of commands to control different types of media devices. For example, MCI uses the same command to begin playback of a waveform audio file, a videodisc track, and an animation sequence. Some devices have unique capabilities, such as the capability of an animation player to use a frame-based time format. For such devices, MCI provides extended commands that are unique to a particular type of device.

The commands in the command-string interface provide a good overview of the MCI command set. Each of these commands is represented by a similar command message in the command-message interface. For example, the close command string is the equivalent of the MCI_CLOSE command message.

Following are some commonly used commands.

Command	Description
capability	Requests information about the capabilities of a device.
close	Closes a device after it has been used.
info	Requests information about a device (for example, a description of the hardware associated with the device).
open	Opens and initializes a device.
pause	Pauses playing or recording on a device.
play	Begins playing on a device.
record	Begins recording on a device.
resume	Resumes playing or recording on a paused device.
seek	Changes the current position in the media.
set	Changes control settings, such as the time format the device is using.
status	Requests information about the status of a device (for example, whether the device is playing or paused).
stop	Stops playing or recording on a device.


  70.2.3  About MCI Devices

MCI device drivers can be classified as either simple devices or compound devices. Simple devices do not require a data file for playback. Videodisc players and compact disc (CD) audio players are examples of simple devices. Compound devices require a data file for playback. MIDI sequencers and waveform audio players are examples of compound devices. The data file associated with a compound device is known as a device element. Examples of device elements are MIDI files and WAVE files.


  70.2.3.1  Standard MCI Device Types

A device type identifies a class of MCI devices that responds to a common set of commands. Following are the currently defined device types.

Device type	Description
animation	Animation device
cdaudio	CD audio player
dat	Digital audio tape player
digitalvideo	Digital video in a window (not based on graphics device interface)
other	Undefined MCI device
overlay	Overlay device (analog video in a window)
scanner	Image scanner
sequencer	MIDI sequencer
videodisc	Videodisc player
waveaudio	Audio device that plays digitized waveform files


  70.2.3.2  Device Names

For any given device type, there might be several MCI drivers that share the command set but operate on different data formats. For example, for animation devices there are several MCI drivers that use the same command set but use different file formats. To uniquely identify an MCI driver, MCI uses device names.

Device names are identified in the [mci] section of the registry. This section identifies all MCI device drivers to Windows. The following is part of a typical [mci] section.

[mci]

waveaudio=mciwave.drv

sequencer=mciseq.drv

MMMovie=mcimmp.drv

cdaudio=mcicda.drv

The key name (on the left side of the equal sign) is the device name. The value corresponding to the key name (on the right side of the equal sign) identifies the filename of the MCI driver. The device name is often the same as the device type for the driver, as is the case for the waveaudio, sequencer, and cdaudio devices in the preceding example. The MMMovie device is an animation device, but it uses a unique device name.

If an MCI driver is installed using a device name that already exists in the [mci] section, Windows appends an integer to the device name of the new driver, creating a unique device name. In the preceding example, a driver installed using the cdaudio device name would be assigned device name cdaudio1. A subsequent cdaudio device would be assigned device name cdaudio2.


  70.2.4  Opening MCI Devices

Before using an MCI device, you must initialize it by opening it. Opening a device loads its driver into memory (if it isn't already loaded) and establishes a device identifier to identify the device in subsequent commands. (The device identifier is not used in the command-string interface.) There are several ways to specify the device you want to open:

•	With simple devices, you can open the device by specifying the device name.

•	With compound devices, you can open the device by specifying the device name, the device element, or both.

For example, the following command string opens a CD audio device (a simple device) by specifying the device name.

open cdaudio

The next command string opens a waveform audio device (a compound device) by specifying the device name and a device element.

open bells.wav type waveaudio

You can also open a compound device by specifying only the device element, as shown in the following example.

open bells.wav

If you specify only a device element when opening a compound device, MCI uses the filename extension of the device element filename to determine which device to open. The registry contains an [mci extensions] section that associates filename extensions and corresponding MCI device types. The following is part of an [mci extensions] section.

[mci extensions]

wav=waveaudio

mid=sequencer

rmi=sequencer


  70.3  Using the Command-Message Interface

Applications that require a C-language interface to MCI should use the command-message interface. This section provides background and detailed information about using this interface.


  70.3.1  About Command Messages

MCI command messages consist of the following three elements:

•	A constant message value

•	A structure (parameter block) specifying additional parameters for the command

•	A set of flags specifying options for the command and validating members in the structure

Commands are sent by using the mciSendCommand function, which has parameters for the message, flags, and a pointer to the structure. For more information about the mciSendCommand function, see Section 70.3.3, »Sending Command Messages«.


  70.3.1.1  Command-Message Example

For an example of an MCI command message, consider MCI_PLAY. The MMSYSTEM.H header file defines the MCI_PLAY command message, the MCI_NOTIFY, MCI_WAIT, MCI_FROM, and MCI_TO flags, and the MCI_PLAY_PARMS structure. The MCI_PLAY_PARMS structure has the following form.

typedef struct {

    DWORD   dwCallback;

    DWORD   dwFrom;

    DWORD   dwTo;

} MCI_PLAY_PARMS;

The MCI_WAIT and MCI_NOTIFY flags are option flags. MCI_WAIT tells the driver to wait until the command is complete before returning control to the application. MCI_NOTIFY tells the driver to notify the application when the command is complete. For more information on using these flags, see Section 70.3.6, »Using the Wait and Notify Flags«.

The MCI_FROM and MCI_TO flags validate the dwFrom and dwTo members in the MCI_PLAY_PARMS structure. These members specify beginning and ending positions for the play operation. Both flags are optional. If either flag is specified, the driver takes the value from the corresponding member in the structure as a beginning or ending position; otherwise, the members are ignored.

Note   Members in a structure are ignored unless corresponding flags are specified to validate the members.


  70.3.1.2  Items in Query Commands

Two command messages that query devices for information, MCI_GETDEVCAPS and MCI_STATUS, extend the command-message paradigm by adding a dwItem member to the structure and defining item constants for the member. Item constants specify which item of information is being requested. For example, MMSYSTEM.H defines the MCI_STATUS_PARMS structure for the MCI_STATUS command message as follows.

typedef struct {

    DWORD   dwCallback;

    DWORD   dwReturn;

    DWORD   dwItem;

    DWORD   dwTrack;

} MCI_STATUS_PARMS;

If you use the MCI_STATUS_ITEM flag to validate the dwItem member, make sure that dwItem contains a constant defined by MMSYSTEM.H to indicate the exact status information requested. The MCI_STATUS command message uses the following constants for dwItem:

MCI_STATUS_CURRENT_TRACK
MCI_STATUS_LENGTH
MCI_STATUS_MEDIA_PRESENT
MCI_STATUS_MODE
MCI_STATUS_NUMBER_OF_TRACKS
MCI_STATUS_POSITION
MCI_STATUS_READY
MCI_STATUS_TIME_FORMAT


  70.3.2  Summary of MCI Command Messages

MCI defines four classifications of command messages. The command messages and options in the following two classifications are defined as the minimum command set for any MCI driver:

•	System command messages are handled directly by MCI rather than by the driver.

•	Required command messages are handled by the driver. All drivers should support the required command messages and options.

Regardless of the specific driver you use, you should be able to assume that the command messages and options in the two preceding groups are available.

The command messages in the following two classifications are not supported by all drivers:

•	Basic (or optional) command messages are used by some devices. If a device supports a basic command message, it must support a defined set of options for the command message.

•	Extended command messages are specific to certain device types or drivers. They include new command messages (for example, the MCI_PUT and MCI_WHERE command messages for the animation device type) and extensions to existing command messages (for example, the MCI_ANIM_GETDEVCAPS_CAN_STRETCH option added to the MCI_STATUS command message for the animation device type).

If you need to use a basic or extended command message or option, you should query the device driver before trying to use the command message or option (that is, unless you are certain that the MCI driver you have used during development is the same one that will be available on the delivery system). The following tables summarize the specific command messages in each category.

MCI directly processes the following system command messages, rather than passing them to MCI device drivers.

Command	Description
MCI_BREAK	Sets a break key for an MCI device.
MCI_SYSINFO	Returns information about MCI devices.
Required command messages must be supported by all MCI device drivers. The following table lists the required command messages.

Command	Description
MCI_CLOSE	Closes the device.
MCI_GETDEVCAPS	Obtains the capabilities of a device.
MCI_INFO	Obtains textual information from a device.
MCI_OPEN	Initializes the device.
MCI_STATUS	Obtains status information from the device.
Following are the basic command messages. The use of these command messages by a device is optional.

Command	Description
MCI_LOAD	Loads data from a file.
MCI_PAUSE	Stops playing.
MCI_PLAY	Starts transmitting output data.
MCI_RECORD	Starts recording data.
MCI_RESUME	Resumes playing or recording on a paused device.
MCI_SAVE	Saves data to a file.
MCI_SEEK	Seeks forward or backward.
MCI_SET	Sets the operating state of the device.
MCI_STATUS	Obtains status information about the device. (Supplements the required MCI_STATUS command message with options for devices using linear media with identifiable positions.)
MCI_STOP	Stops playing or recording.
Some MCI devices have additional command messages or add options to existing command messages. Although some extended command messages apply only to a specific device driver, most of them apply to all drivers of a particular device type. For example, the sequencer command set extends the MCI_SET command message to add time formats that are needed by MIDI sequencers.

Unless you are certain that the specific MCI driver you use during development will be available on the delivery system, do not assume that the device supports the extended command messages or options. You can use the MCI_GETDEVCAPS command message to determine whether a specific feature is supported. Applications should be ready to handle an MCIERR_UNSUPPORTED_FUNCTION return value.

The following extended command messages are available with certain device types.

Command	Device types	Description
MCI_CUE	waveaudio	Prepares for playing or recording.
MCI_DELETE	waveaudio	Deletes a data segment from the media element.
MCI_ESCAPE	videodisc	Sends custom information to a device.
MCI_FREEZE	overlay	Disables video acquisition to the frame buffer.
MCI_PUT	animation overlay	Defines the source, destination, and frame windows.
MCI_REALIZE	animation	Tells the device to select and realize its palette into a display context of the displayed window.
MCI_SPIN	videodisc	Starts the disc spinning or stops the disc from spinning.
MCI_STEP	animation, videodisc	Steps the play one or more frames forward or reverse.
MCI_UNFREEZE	overlay	Enables the frame buffer to acquire video data.
MCI_UPDATE	animation	Repaints the current frame into the display context.
MCI_WHERE	animation, overlay	Obtains the rectangle specifying the source, destination, or frame area.
MCI_WINDOW	animation, overlay	Controls display window options such as caption text.


  70.3.3  Sending Command Messages

Windows provides the following functions to send command messages to devices and to query devices for error information.

Function	Description
mciSendCommand	Sends a command message to an MCI device.
mciGetErrorString	Returns the error string corresponding to an error number.


  70.3.3.1  The MCI Device Identifier

MCI returns a device identifier when you open a device by using the MCI_OPEN command message. Use this identifier to identify the opened device when sending subsequent commands.

MMSYSTEM.H defines a special constant, MCI_ALL_DEVICE_ID, to indicate that a command message is to be sent to all of the MCI devices that an application has opened. You can use MCI_ALL_DEVICE_ID with any command message that does not return information. For instance, the following example closes all of the MCI devices that have been opened by an application.

DWORD dwReturn;

/*

 * Closes all MCI devices opened by this application.

 * Waits until devices are closed before returning.

 */

if (dwReturn = mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE,

        MCI_WAIT, NULL))

    /* Error, unable to close all devices. */

    return FALSE;

Note   Although using the MCI_ALL_DEVICE_ID identifier is a convenient way to broadcast a command to all your devices, don't rely on it to synchronize devices; the timing between messages can vary.


  70.3.4  Opening a Device

Before using a device, you must initialize it by using the MCI_OPEN command message. The variations of this command message make it one of the most complex of all MCI commands.


  70.3.4.1  The MCI_OPEN_PARMS Structure

Like all MCI command messages, MCI_OPEN has an associated structure. The default structure for MCI_OPEN is the MCI_OPEN_PARMS structure. Certain devices, such as waveaudio, animation, and overlay devices, have extended structures to accommodate additional optional parameters. Unless you need to use these additional parameters, you can use the MCI_OPEN_PARMS structure with any MCI device.

MCI uses the wDeviceID member of this structure to return the device identifier to the application. You should check the return value of the mciSendCommand function before using the device identifier, to be sure that it is valid. A nonzero return value indicates that an error occurred during the opening of the device process.

Note   You can also determine the device identifier by specifying the device name in a call to the mciGetDeviceID function.

Other members used in opening a device correspond to the following flags for the command message.

Flag	Meaning
MCI_OPEN_ALIAS	The lpstrAlias member of the structure contains a pointer to a device alias.
MCI_OPEN_ELEMENT	The lpstrElementName member of the structure contains a pointer to the element name.
MCI_OPEN_SHAREABLE	The device or element was opened as shareable.
MCI_OPEN_TYPE	The lpstrDeviceType member of the structure contains a pointer to the device-type identifier.
MCI_OPEN_TYPE_ID	The lpstrDeviceType member of the structure contains an integer device-type identifier.


  70.3.4.2  Opening Simple Devices

To open a simple device such as a CD audio or videodisc device, use the lpstrDeviceType member in the MCI_OPEN_PARMS structure to identify the device to open. There are three ways to identify devices:

•	Specify a pointer to a null-terminated string containing the device name.

•	Specify a device-type constant.

•	Specify the actual name of the device driver.

Regardless of which method you use to identify the device, you must specify the MCI_OPEN_TYPE flag to validate the lpstrDeviceType member. For instance, the following example opens a CD audio device by specifying the device name.

UINT wDeviceID;

DWORD dwReturn;

MCI_OPEN_PARMS mciOpenParms;

/* Open a compact disc device by specifying the device name. */

mciOpenParms.lpstrDeviceType = "cdaudio";

if (dwReturn = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE,

        (DWORD)(LPVOID) &mciOpenParms))

    /* Error, unable to open device. */

    return FALSE;

/* Device opened successfully. Get the device ID. */

wDeviceID = mciOpenParms.wDeviceID;

You can also open a device by specifying a device-type constant. To be opened by means of a device-type constant, device drivers must be installed in the [mci] section of the registry by using the following device types.

Device type	Device-type constant
animation	MCI_DEVTYPE_ANIMATION
cdaudio	MCI_DEVTYPE_CD_AUDIO
dat	MCI_DEVTYPE_DAT
digitalvideo	MCI_DEVTYPE_DIGITAL_VIDEO
other	MCI_DEVTYPE_OTHER
overlay	MCI_DEVTYPE_OVERLAY
scanner	MCI_DEVTYPE_SCANNER
sequencer	MCI_DEVTYPE_SEQUENCER
videodisc	MCI_DEVTYPE_VIDEODISC
waveaudio	MCI_DEVTYPE_WAVEFORM_AUDIO
If you open a device by specifying a device-type constant, you must specify the MCI_OPEN_TYPE_ID flag in addition to the MCI_OPEN_TYPE flag. The following example opens a CD audio device by specifying a device-type constant.

UINT wDeviceID;

DWORD dwReturn;

MCI_OPEN_PARMS mciOpenParms;

/*

 * Open a compact disc device by

 * specifying a device-type constant.

 */

mciOpenParms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;

if (dwReturn = mciSendCommand(NULL, MCI_OPEN,

        MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID,

        (DWORD)(LPVOID) &mciOpenParms))

    /* Error, unable to open device. */

    return FALSE;

/* Device opened successfully. Get the device ID. */

wDeviceID = mciOpenParms.wDeviceID;

When you open a device by specifying a device-type constant, MCI uses the high-order word of the lpstrDeviceType member to distinguish between multiple occurrences of the device type in the registry.

For example, if the registry lists entries for waveaudio1 and waveaudio2, the following statement sets the lpstrDeviceType member to specify the device identified by waveaudio2.

LPSTR lpstrDeviceType;

lpstrDeviceType = (LPSTR)MAKELONG(MCI_DEVTYPE_WAVEFORM_AUDIO, 2);

Similarly, to specify the device identified by waveaudio1, set the high-order word of lpstrDeviceType to 0 or 1. (Setting the high-order word to 0 tells MCI to use an unnumbered device or the lowest-numbered device.)

You can also open a device by specifying the filename of the device driver in the lpstrDeviceType member of the MCI_OPEN_PARMS structure. You don't need to specify the complete path or the filename extension — MCI assumes that drivers are located in the Windows system directory and have a filename extension of .DRV.

Note   Opening MCI devices by specifying the filename of the device driver may be useful during development and testing. However, this technique is not recommended for applications because it makes them device dependent. Applications that open MCI devices by filename may not work in all systems.


  70.3.4.3  Opening Compound Devices

There are three ways to open a compound device:

•	Specify only the device (by using the device name, a device-type constant, or the filename of the device driver).

•	Specify both the device and the device element.

•	Specify only the device element.

The first method — specifying only the device — is useful for determining the capabilities of a device by using the MCI_GETDEVCAPS command message. To actually control a media device, you must specify a device element when you open the device.

To specify a device element, fill the lpstrElementName member of the MCI_OPEN_PARMS structure with a pointer to a null-terminated string containing the filename of the device element. You must also validate the lpstrElementName member by specifying the MCI_OPEN_ELEMENT flag in the dwFlags parameter of the mciSendCommand function.

You can specify the device in the same manner used for simple devices: by device name, by device-type constant, or by the filename of the driver. The following example opens the waveaudio device with a WAVE file named TIMPANI.WAV.

UINT wDeviceID;

DWORD dwReturn;

MCI_OPEN_PARMS mciOpenParms;

/*

 * Open a waveaudio device by specifying

 * the device name and device element.

 */

mciOpenParms.lpstrDeviceType = "waveaudio";

mciOpenParms.lpstrElementName = "timpani.wav";

if (dwReturn = mciSendCommand(NULL, MCI_OPEN,

        MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

        (DWORD)(LPVOID) &mciOpenParms))

    /* Error, unable to open device. */

    return FALSE;

/* Device opened successfully. Get the device ID. */

wDeviceID = mciOpenParms.wDeviceID;

You can also open a device by specifying just a device element. MCI uses the filename extension of the given device element along with the [mci extensions] section of the registry to select the device to open. For more information about opening devices by specifying only a device element, see Section 70.2.4, »Opening MCI Devices«.


  70.3.5  Closing a Device

The MCI_CLOSE command message releases access to a device or device element. MCI frees a device when all processes using a device have closed it. To help MCI manage devices, applications should explicitly close each device or device element when they are finished using it.

Note   It is very important that applications close all opened MCI devices before terminating. You can close all devices with a single command message by specifying the MCI_ALL_DEVICE_ID constant as the device identifier.


  70.3.6  Using the Wait and Notify Flags

Typically, MCI returns control to the application immediately, even if it takes several seconds to complete the action initiated by a command. For example, after a CD audio device receives a seek command, control returns to the application before the seek operation is complete. You can use the following two flags to request that MCI wait until a command is complete before returning control to the application, or that MCI notify the application when the command is complete.

Flag	Description
MCI_NOTIFY	Directs the device to return control immediately and post the MM_MCINOTIFY message when the requested action is complete.
MCI_WAIT	Directs the device to wait until the requested action is complete before returning control to the application.


  70.3.6.1  Using the Notify Flag

The MCI_NOTIFY flag directs MCI to post the MM_MCINOTIFY message when the device completes an action. The application specifies the handle of the destination window for the message in the dwCallBack member of the structure sent with the command message. Every structure associated with a command message contains this member.

Note   MCI can have only one pending notification message for each device.

When MCI posts the MM_MCINOTIFY message, it sets the low-order word of the lParam parameter of the window procedure to the identifier of the device initiating the callback. The wParam parameter of the window procedure contains one of the following constants specifying the notification status of the callback.

Flag	Meaning
MCI_NOTIFY_SUCCESSFUL	The conditions required for initiating the callback are satisfied and the command finished without interruption.
MCI_NOTIFY_SUPERSEDED	MCI had a notification pending and received another notify request. MCI resets the callback conditions to correspond to the notify request of the new command.
MCI_NOTIFY_ABORTED	The application sent a new command that prevented the callback conditions set by a previous command from being satisfied. If an application interrupts a command that requested notification, MCI does not inform the window procedure of the notify command being aborted.
MCI_NOTIFY_FAILURE	A device error occurred while a device was executing the command. For example, MCI posts this message when a hardware error occurs during a play command.


  70.3.6.2  Using the Wait Flag and Break Command Message

Specifying the MCI_WAIT flag with a command message causes MCI to wait until the command has finished before returning control to the application. Using the wait flag with commands that take a long time essentially disables a system from receiving any user input until the command is complete.

MCI supports a break key to interrupt the wait operation and return control to the application. The break key does not interrupt the command, but by returning control to the application, it allows the application to monitor user input.

By default, MCI defines the break key as CTRL+BREAK. Applications can redefine this key by using the MCI_BREAK command message. MCI_BREAK uses the MCI_BREAK_PARMS structure.

The following flags validate members in the MCI_BREAK_PARMS structure:

Flag	Description
MCI_BREAK_HWND	Validates the hwndBreak member, which specifies the window that must have the focus to enable break detection.
MCI_BREAK_KEY	Validates the nVirtKey member, which specifies the virtual-key code to be used for the break key.
MCI_BREAK_OFF	Disables any existing break key.


  70.3.7  Obtaining MCI System Information

The MCI_SYSINFO command message obtains system information about MCI devices. MCI handles this message without relaying it to any MCI device. MCI returns the system information in the MCI_SYSINFO_PARMS structure.

The MCI_SYSINFO command message has the following flags.

Flag	Meaning
MCI_SYSINFO_QUANTITY	MCI returns the number of devices of a given type listed in the [mci] section of the registry. When this flag is used with the MCI_SYSINFO_OPEN flag, the number of open devices is returned.
MCI_SYSINFO_NAME	MCI returns the name of a device that satisfies the query. When this flag is used with the MCI_SYSINFO_OPEN flag, only the names of open devices are returned.
MCI_SYSINFO_OPEN	MCI returns the number or names of open devices.
MCI_SYSINFO_INSTALLNAME	MCI returns the name listed in the registry entry used to install the device.
You use the MCI_SYSINFO_QUANTITY flag to determine the number of devices for a particular type listed in the [mci] section of the registry. For this flag, set the wDeviceType member of the structure to the device type. When requesting the number of devices, set the wDeviceID parameter to NULL. MCI returns the number of devices as a doubleword in the lpstrReturn member of the structure. If you combine the MCI_SYSINFO_QUANTITY flag with the MCI_SYSINFO_OPEN flag, MCI returns the number of devices of that type opened by the process.

Once you have the number of devices, you can enumerate the names of the devices by using the MCI_SYSINFO_NAME flag. To get information by using this flag, you must create a buffer for the return name. In the structure, specify a pointer to the buffer, the size of the buffer, the index number corresponding to the device (1 is the first device), and the device type. This information is entered in the lpstrReturn, dwRetSize, dwNumber, and wDeviceType members. MCI returns the device name in the buffer. When requesting the name of a particular device, set the wDeviceID parameter to NULL. To restrict the names to open devices, use the MCI_SYSINFO_OPEN flag with MCI_SYSINFO_NAME.

To retrieve information on all devices in the system, you can assign the MCI_ALL_DEVICE_ID constant to the wDeviceID parameter. When you use this identifier, MCI ignores the contents of the wDeviceType member and returns information on all MCI devices listed in the registry. When you use the MCI_SYSINFO_OPEN flag with the MCI_ALL_DEVICE_ID identifier, MCI returns information about the devices opened by the task.

You can retrieve the installation name of an open device by using the MCI_SYSINFO_INSTALLNAME flag. To get the installation name, you must create a buffer for the return name. In the structure, specify a pointer to the buffer and the size of the buffer in the lpstrReturn and dwRetSize members. MCI places the device that corresponds to the wDeviceID parameter name in the buffer.


  70.4  About the Command-String Interface

This section presents an introduction to the MCI command-string interface. MCI provides the following functions for working with command strings.

Function	Description
mciSendString	Sends a command string to an MCI device driver. This function also has parameters for callback functions and return strings.
mciGetErrorString	Returns the error string corresponding to an error number.


  70.4.1  Sending Command Strings

Use the mciSendString function to send command strings to a device. The following statement passes the "play to 500" command string to a waveaudio device driver.

DWORD dwErrorCode;

dwErrorCode = mciSendString("play waveaudio to 500", NULL, 0, 0L);

If the mciSendString function succeeds, it returns zero. If the function fails, it returns an error code. To get extended error information, use the mciGetErrorString function.


  70.4.2  Additional Information About Command Strings

The MCITEST application contains examples of using the mciSendString and mciGetErrorString functions. You can use this application to experiment with MCI devices and command strings.


Introduction to Audio
  Chapter 71    Introduction to Audio

71.1  About Audio Services

Microsoft Windows provides several different types and levels of audio services. You should become familiar with these types and levels so you can choose the services appropriate for your application.

This chapter covers the following topics:

•	The different types and levels of audio services

•	An overview of the audio architecture

•	Audio file formats used by Windows

•	Books and specifications providing additional information about audio

This chapter assumes you have a basic knowledge of digital audio and Musical Instrument Digital Interface (MIDI). For more information on these subjects, see Section 71.4, »Further Reading«.


  71.1.1  Types of Audio Services

Different types of audio services require different formats for the audio information and different technologies to reproduce audio. Windows offers the following types of audio services:

•	Waveform audio services provide playback and recording support for digital audio hardware. Waveform audio is useful for reproducing nonmusical audio material such as sound effects and voice-over narration. Waveform audio has moderate storage-space and data-transfer rate requirements — as low as 11 kilobytes per second of audio.

•	MIDI audio services provide support for MIDI-file and MIDI-event playback (through internal or external synthesizers) and MIDI-event recording. MIDI audio is useful with music-related applications such as music composition and MIDI sequencer programs. Because they require less storage space and a lower data-transfer rate than waveform audio, you may want to use MIDI audio services to provide introductory and background music in your applications.

•	Compact disc (CD) audio services provide support for playback of Red Book audio information on CDs by means of the CD-ROM drive on multimedia computers. CD audio offers the highest quality reproduction of musical material but has the highest storage-space requirements — 176 kilobytes per second of audio. You cannot read from the CD-ROM drive while playing CD audio.


  71.1.2  Levels of Audio Services

The different levels of audio services let you choose services appropriate to the requirements of your application and to your programming ability. Windows offers two levels of audio services:

•	High-level audio services allow you to play and record audio files by using as little as one function call. Compared with low-level audio services, high-level services are easier to use and require less programming. High-level services also meet the audio requirements of most applications.

•	Low-level audio services allow you to communicate directly with audio device drivers to manage playback and recording. Low-level audio services require more programming than high-level services but give you more control over audio playback and recording.

The easiest way to play and record audio is to use high-level audio services. If the high-level audio services do not meet the audio needs of your application, you can use low-level audio services to write your own routines to manage audio playback and recording.


  71.2  Windows Audio Architecture

Windows provides audio services through high-level audio functions, Media Control Interface (MCI) device drivers, low-level audio functions, the MIDI Mapper, and low-level audio device drivers. »This illustration« shows the relationship between an application and the elements of Windows that provide audio support.


  71.2.1  High-Level Audio Functions

MCI functions, along with MCI device drivers, provide high-level audio support for MIDI, waveform, and CD audio devices. MCI drivers can play disk-resident (hard disk and CD-ROM) audio files in the background while an application runs in the foreground. In addition to MCI, Windows provides high-level audio support with three special-purpose functions that play waveform sounds: MessageBeep, PlaySound, and sndPlaySound. You can also use these functions to play waveform sounds associated with system alerts and sounds identified by entries in the registry.

High-level audio functions should meet the audio requirements of most applications. For information about using MCI and the MessageBeep, PlaySound, and sndPlaySound functions, see Chapter 72, »High-Level Audio«.


  71.2.2  Low-Level Audio Functions

Low-level audio functions provide a device-independent interface to audio hardware in multimedia computers. These functions supply low-level audio services by letting applications communicate directly with the audio device drivers. MCI drivers and the MessageBeep, PlaySound, and sndPlaySound functions use these low-level functions to provide high-level audio services.

Low-level audio functions are provided for applications — such as audio tools programs — that have special-purpose audio requirements. For example, a MIDI sequencer application would use low-level audio functions to record and play MIDI data. For information about using low-level audio services, see Chapter 73, »Low-Level Audio«.


  71.2.3  The MIDI Mapper

The MIDI Mapper provides standard patch services for device-independent playback of MIDI files. Standard patch services ensure that different MIDI synthesizers use the same instrument sounds to reproduce the music in a MIDI file.

The MIDI Mapper translates and redirects messages sent to it by low-level MIDI output functions. Because the high-level MIDI services use low-level MIDI output functions, the MIDI Mapper can be used with high-level as well as low-level MIDI services. For information about the architecture of the MIDI Mapper and how to use the MIDI Mapper with high-level audio services, see Chapter 72, »High-Level Audio«. For information about using the MIDI Mapper with low-level audio services, see Chapter 73, »Low-Level Audio«. MIDI files must follow certain authoring guidelines to use the standard patch services provided by the MIDI Mapper. For details about these authoring guidelines, see Chapter 72, »High-Level Audio«.


  71.3  Audio File Formats

Windows supports a tagged file structure called the Resource Interchange File Format (RIFF). There are two RIFF file formats currently defined for audio files.

RIFF type	Filename extension	Description
RMID	.RMI	MIDI audio file
WAVE	.WAV	Waveform audio file
The WAVE file format supports a number of digital audio data formats. All multimedia computers support pulse code modulated (PCM) formats of 8-bit monaural data at sample rates of 11.025 kilohertz (kHz) and 22.05 kHz.

In addition to Resource Interchange File Format MIDI (RMID) files, the MCI MIDI sequencer plays standard MIDI files in the format defined by the International MIDI Association in the "Standard MIDI Files 1.0" specification. For information about how to obtain this specification, see Section 71.4, »Further Reading«. RMID files are standard MIDI files with a RIFF header.


  71.3.1  Using RIFF Files

The multimedia file input and output (I/O) services include functions for working with RIFF files. For information about using these functions, see Chapter 75, »Multimedia File Input/Output«.


  71.4  Further Reading

For more information on digital audio, digital-signal processing, and computer music, see the following books:

Boom, Michael. Music Through MIDI. Redmond: Microsoft Press, 1987.

Chamberlin, Hal. Musical Applications of Microprocessors. Hasbrouk Heights: Hayden Book Company, Inc., 1985.

Pohlmann, Ken. Principles of Digital Audio. Indianapolis: Howard W. Sams & Co., 1985.

Roads, Curtis, and John Strawn. Foundations of Computer Music. Cambridge: The MIT Press, 1985.

Strawn, John F. Digital Audio Engineering, An Anthology. Los Altos: William Kaufmann, Inc., 1985.

Strawn, John F. Digital Audio Signal Processing, An Anthology. Los Altos: William Kaufmann, Inc., 1985.

For information about MIDI and standard MIDI files, see the following MIDI specifications:

MIDI 1.0 Detailed Specification

Standard MIDI Files 1.0 Specification

These specifications are available from the International MIDI Association at the following address:

International MIDI Association
5316 West 57th Street
Los Angeles, CA 90056


High-Level Audio
  Chapter 72    High-Level Audio

This chapter explains how to use the high-level audio services of Microsoft Windows to add sound to applications. For an overview of the audio services, see Chapter 71, »Introduction to Audio«.

This chapter covers the following topics:

•	Playing waveform sounds

•	Using the Media Control Interface (MCI) to play and record audio

•	Using the Musical Instrument Digital Interface (MIDI) Mapper for device-independent MIDI file playback

•	Authoring MIDI files

This chapter assumes you have a basic knowledge of digital audio and MIDI. For additional information on these subjects, see the suggestions for further reading at the end of Chapter 71, in Section 71.4, »Further Reading«.


  72.1  Function Prefixes

High-level audio function names begin with the following prefixes:

Prefix	Function group
snd	System-alert sound functions
mci	MCI functions


  72.2  Playing Waveform Sounds

One basic way to use sound is to associate a sound with a user action or with a warning or alert message. These sounds tend to be short in duration and are often played repeatedly. Windows provides three functions to play waveform sounds.

Function	Description
MessageBeep	Plays the sound that corresponds to a given system-alert level.
PlaySound	Plays the sound that corresponds to the given filename or registry entry.
sndPlaySound	Plays the sound that corresponds to the given filename or registry entry.
These functions provide methods of playing the following waveform sounds:

•	WAVE files stored on a hard disk or CD-ROM

•	In-memory WAVE resources

•	WAVE files specified by entries in the registry

•	WAVE files associated with system-alert levels


  72.2.1  Restrictions in Playing Waveform Sounds

There are some restrictions to using the MessageBeep, PlaySound, and sndPlaySound function to play waveform sounds:

•	The entire sound must fit in available physical memory.

•	The sound must be in a data format playable by one of the installed waveform audio device drivers.

Use MessageBeep, PlaySound, and sndPlaySound to play WAVE files that are relatively small in size — up to about 100 kilobytes. For larger sound files, use the MCI services. For information about using MCI, see Section 72.3, »Playing and Recording Audio Using Media Control Interface«.


  72.2.2  Using the PlaySound and sndPlaySound Functions

The PlaySound and sndPlaySound functions can be used to perform the following tasks:

•	Play WAVE files

•	Loop sounds

•	Play WAVE resources

•	Play sounds specified in the registry

The following sections describe these tasks. Although the examples shown use the sndPlaySound function, most of the sample code works with the PlaySound function as well.


  72.2.2.1  Playing WAVE Files

The following statement plays the C:\SOUNDS\BELLS.WAV file.

sndPlaySound("C:\\SOUNDS\\BELLS.WAV", SND_SYNC);

If the specified file does not exist or does not fit into the available physical memory, sndPlaySound plays the default system sound specified by the SystemDefault entry in the [sounds] section of the registry. If there is no SystemDefault entry, sndPlaySound fails without producing any sound. If you don't want the default system sound to play, specify the SND_NODEFAULT flags in the following example.

sndPlaySound("C:\\SOUNDS\\BELLS.WAV", SND_SYNC | SND_NODEFAULT);


  72.2.2.2  Looping Sounds

If you specify the SND_LOOP and SND_ASYNC flags for the wFlags parameter of the sndPlaySound function, as in the following example, the sound continues to play repeatedly.

sndPlaySound("C:\\SOUNDS\\BELLS.WAV", SND_LOOP | SND_ASYNC);

If you want to "loop" a sound, you must play it asynchronously. You cannot use the SND_SYNC flag with the SND_LOOP flag. A looped sound continues to play until sndPlaySound is called to play another sound. To stop playing a looped or asynchronous sound without playing another sound, use the following statement.

sndPlaySound(NULL, 0);


  72.2.2.3  Playing WAVE Resources

You can also build WAVE files into an application as resources and use the sndPlaySound function to play these sounds by specifying the SND_MEMORY flag. The SND_MEMORY flag indicates that the lpszSoundName parameter is a pointer to an in-memory image of the WAVE file. To include a WAVE file as a resource in an application, add the following entry to the application's resource script (.RC) file.

soundName WAVE c:\sounds\bells.wav

The name soundName is a placeholder for a name that you supply to refer to this WAVE resource. WAVE resources are loaded and accessed just like other application-defined Windows resources. The function in the following example plays a specified WAVE resource.

/* Plays a specified WAVE resource. */

BOOL PlayResource(LPSTR lpName)

{

    BOOL bRtn;

    LPSTR lpRes;

    HANDLE hResInfo, hRes;

    /* Find the WAVE resource. */

    hResInfo = FindResource(hInst, lpName, "WAVE");

    if (hResInfo == NULL)

        return FALSE;

    /* Load the WAVE resource. */

    hRes = LoadResource(hInst, hResInfo);

    if (hRes == NULL)

        return FALSE;

    /* Lock the WAVE resource and play it. */

    lpRes = LockResource(hRes);

    if (lpRes != NULL) {

        bRtn = sndPlaySound(lpRes, SND_MEMORY | SND_SYNC |

            SND_NODEFAULT);

        UnlockResource(hRes);

    }

    else

        bRtn = 0;

    /* Free the WAVE resource and return success or failure. */

    FreeResource(hRes);

    return bRtn;

}

To play a WAVE resource by using this function, pass to the function a pointer to a string containing the name of the resource, as shown in the following example.

PlayResource("soundName");


  72.2.2.4  Playing Sounds Specified in the Registry

The sndPlaySound function also plays waveform sounds referred to by a key-name in the [sounds] section of the registry. This enables users to assign their own sounds to system alerts and warnings, or to user actions such as mouse-button click. For example, the [sounds] section of the registry might look like the following.

[sounds]

SystemDefault=C:\SOUNDS\BUMMER.WAV, Says BUMMER

SystemAsterisk=C:\SOUNDS\WHALES.WAV, Whale sounds

SystemExclamation=C:\SOUNDS\LASER.WAV, Laser gun sounds

SystemHand=C:\SOUNDS\OHOH.WAV, Says OH-OH

SystemQuestion=C:\SOUNDS\JIBERISH.WAV, Person mumbling

SystemStart=C:\SOUNDS\CHORD.WAV, Plays a chord

MouseClick=C:\SOUNDS\CLICK.WAV, Recording of a clicking sound

To play a sound identified by a registry entry, call sndPlaySound with the lpszSoundName parameter pointing to a string that contains the name of the entry that identifies the sound. For example, to play the sound associated with the MouseClick entry in the [sounds] section of the registry and wait for the sound to finish before returning, use the following statement.

sndPlaySound("MouseClick", SND_SYNC);

If the specified registry entry or the waveform file it identifies does not exist, or if the sound does not fit into the available physical memory, sndPlaySound plays the default system sound specified by the SystemDefault entry. If there is no SystemDefault entry, sndPlaySound fails without producing any sound. If you don't want the default system sound to play, specify the SND_NODEFAULT flag, as in the following example.

sndPlaySound("MouseClick", SND_SYNC | SND_NODEFAULT);

Note   The sndPlaySound function always searches the [sounds] section of the registry for a keyname matching the lpszSoundName parameter before attempting to load a file with this name.

The [sounds] section of the registry includes an optional string following the waveform filename for descriptive text about the sound in the file. This descriptive text is displayed in the Sound option of the Control Panel.


  72.2.3  Playing System-Alert Sounds

The MessageBeep function uses the waveform audio hardware to produce a variety of user-selectable sounds.

When you call MessageBeep, it searches the [sounds] section of the registry for the WAVE file that corresponds to the specified alert level. Following are the registry entries for system-alert sounds.

Registry Entry	Description
SystemDefault	Identifies the sound produced when the MessageBeep function is called with the wAlert  parameter set to an invalid alert level or when the requested alert sound can't be found. This is called the default system sound.
SystemAsterisk	Identifies the sound produced when MessageBeep is called with wAlert set to MB_ICONASTERISK.
SystemExclamation	Identifies the sound produced when MessageBeep is called with wAlert set to MB_ICONEXCLAMATION.
SystemHand	Identifies the sound produced when MessageBeep is called with wAlert set to MB_ICONHAND.
SystemQuestion	Identifies the sound produced when MessageBeep is called with wAlert set to MB_ICONQUESTION.
If MessageBeep is called with wAlert set to zero, it plays the default system sound. If wAlert is set to −1, MessageBeep uses the computer speaker to produce a standard beep sound. If MessageBeep can't play the requested sound, it plays the default system sound. If it can't play the default system sound, then it produces a beep sound using the computer speaker.

The Sound option of the Control Panel enables users to set these registry entries to customize their environment for system-alert sounds. It also enables users to disable these alert sounds.


  72.3  Playing and Recording Audio Using Media Control Interface

The Media Control Interface (MCI) provides a high-level interface for controlling both internal and external media devices. It provides support for playing wave- form, MIDI, and compact disc audio and for recording waveform audio. MCI is the easiest way for multimedia applications to play and record audio.

MCI uses device drivers to interpret and execute high-level MCI commands. MCI device drivers can stream digital audio and MIDI data directly from a storage device to the appropriate device driver, allowing applications to play files too large to fit in available physical memory. This data streaming takes place in the background while an application is running. The application is responsible only for setting up MCI and telling it to start playing or recording.

MCI provides two types of interface: command-message and command-string. This section explains how to use the command-message interface for waveform, MIDI, and compact disc audio devices. For an introduction to MCI and for information about the command-string interface, see Chapter 70, »Media Control Interface«.


  72.3.1  MCI Audio Data Types

The MMSYSTEM.H header file defines data types and function prototypes for MCI. You must include this header file in any source-code module that uses MCI functions.

Following are the data types for structures used with extended MCI commands related to audio.

Type	Description
MCI_SEQ_SET_PARMS	Specifies a structure for the MCI_SET command message for MIDI sequencer devices.
MCI_WAVE_DELETE_PARMS	Specifies a structure for the MCI_DELETE command message for waveform audio devices.
MCI_WAVE_OPEN_PARMS	Specifies a structure for the MCI_OPEN command message for waveform audio devices.
MCI_WAVE_SET_PARMS	Specifies a structure for the MCI_SET command message for waveform audio devices.


  72.3.2  MCI Audio Commands

MCI provides a standard set of commands applying to all types of media devices. Some of these commands can be extended to accommodate unique features of a particular type of device.

Following are the MCI command messages that perform common audio playback and recording tasks.

MCI command	Audio task
MCI_OPEN	Open an audio device.
MCI_CLOSE	Close an audio device.
MCI_PLAY	Play all or part of audio selection; resume playback from pause.
MCI_STOP	Stop playback.
MCI_PAUSE	Pause playback.
MCI_SEEK	Change current location.
MCI_CUE	Cue a device so playback or recording begins with minimum delay.
MCI_RECORD	Begin recording on a waveform audio device.
MCI_SAVE	Save a recorded waveform audio file.
MCI_INFO	Query device information such as the product name and the name of the device element currently associated with the device (returns information in string format).
MCI_GETDEVCAPS	Query device capabilities such as the device name and number of inputs and outputs (if the device can record).
MCI_STATUS	Query device status such as current playback position, media length, media format, time format, record level, CD audio track, and MIDI sequencer tempo.
MCI_SET	Set device parameters such as time format, waveform data format, and MIDI sequencer tempo.


  72.3.3  Opening MCI Audio Devices

MCI requires that audio devices be opened before they can be accessed. Use the MCI_OPEN command message along with the MCI_OPEN_PARMS structure to open an audio device and obtain an MCI device identifier. Subsequent commands use this device identifier to identify the device to receive the command.

The MCI device identifier is returned in the wDeviceID member. Always check the return value of the mciSendCommand function after sending an MCI_OPEN command message before using this device identifier. A nonzero return value indicates that there was an error in opening the device and that the returned device identifier is not valid.

For waveform audio devices, you can use an extended structure, MCI_WAVE_OPEN_PARMS. This structure has a dwBufferSeconds member to specify the number of seconds of buffering used by the MCI waveform device driver. If you use this member, you must specify the MCI_WAVE_OPEN_BUFFER flag for the dwParam1 parameter of mciSendCommand to validate the member.

If you do not want to specify the number of seconds of buffering for the driver to use, you can use the MCI_WAVE_OPEN_PARMS structure when you open waveform audio devices.

When you open a simple device, such as a compact disc audio device, you must specify the device name. When you open a compound device, such as a waveform or MIDI sequencer device, the device name is optional. Use the lpstrDeviceType member of the MCI_OPEN_PARMS structure to specify the device name. MCI lets you use a string or a constant for this member. Following are the strings and constants for MCI audio devices.

Device	String	Constant
Compact disc	cdaudio	MCI_DEVTYPE_CD_AUDIO
Waveform	waveaudio	MCI_DEVTYPE_WAVEFORM_AUDIO
MIDI sequencer	sequencer	MCI_DEVTYPE_SEQUENCER
A string is the default format for specifying device names. If you use a constant to specify the device name, you must specify the MCI_OPEN_TYPE_ID flag in addition to the MCI_OPEN_TYPE flag.


  72.3.3.1  Opening Waveform and MIDI Sequencer Devices

Waveform and MIDI sequencer devices are compound devices. Compound devices require an associated device element — a WAVE or MIDI file. There are three ways to open compound devices:

•	Specify only the device name.

•	Specify only the device element and let MCI select the device associated with the file extension of the device element.

•	Specify both the device name and the device element.

Specify only the device name when opening a device to query its capabilities with the MCI_GETDEVCAPS command message and when you plan to use the device to play more than one device element.

If you don't specify a device name when you open a compound device, MCI chooses an appropriate device type by comparing the file extension of the device element with entries in the [mci extensions] section of the registry. The following example uses this technique to open a MIDI sequencer device to play a MIDI file named CHOPIN.RMI.

UINT wDeviceID;

MCI_OPEN_PARMS mciOpenParms;

    .

    .

    .

/* Open the device by specifying only the device element. */

mciOpenParms.lpstrElementName = "CHOPIN.RMI";

if (mciSendCommand(0,                           /* device ID */

        MCI_OPEN,                               /* command   */

        MCI_OPEN_ELEMENT,                       /* flags     */

        (DWORD) (LPVOID) &mciOpenParms))  /* parameter block */

    /* Error, unable to open device. */

    return FALSE;

else

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;

Instead of letting MCI choose the device, you can specify the device name when you open the device. The following example uses this technique to open a waveform audio device to play the BELLS.WAV file. This example uses a string to specify the device name. For an example using a constant to specify the device name, see Section 72.3.3.3, »Opening Compact Disc Devices«.

UINT wDeviceID;

MCI_OPEN_PARMS mciOpenParms;

    .

    .

    .

/*

 * Open the device by specifying both the device

 * element and the device name.

 */

mciOpenParms.lpstrDeviceType = "waveaudio";

mciOpenParms.lpstrElementName = "C:\\SOUNDS\\BELLS.WAV";

if (mciSendCommand(0,                           /* device ID */

        MCI_OPEN,                               /* command   */

        MCI_OPEN_ELEMENT | MCI_OPEN_TYPE,       /* flags     */

        (DWORD) (LPVOID) &mciOpenParms))  /* parameter block */

    /* Error, unable to open device. */

    return FALSE;

else

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;


  72.3.3.2  Using the MIDI Mapper With the MCI Sequencer

The MIDI Mapper is the default output device for the MCI MIDI sequencer. It provides standard patch services for device-independent playback of MIDI files. Applications that use the MCI sequencer to play MIDI files should use the MIDI Mapper. For details about the MIDI Mapper, see Section 72.4, »The MIDI Mapper« For information about authoring device-independent MIDI files, see Section 72.5, »Authoring MIDI Files«.

When you open the MCI MIDI sequencer, MCI attempts to select the MIDI Mapper as the output device. If the MIDI Mapper is unavailable because it is already in use, MCI selects another MIDI output device.

Note   The MIDI Mapper currently supports only one client at a time in the current versions of Microsoft Windows NT.

After opening the sequencer, you should check to see if the MIDI Mapper was available and was selected as the output device. The following example uses the MCI_STATUS command message to verify that the MIDI Mapper is the output device for the MCI sequencer.

UINT wDeviceID;

DWORD dwReturn;

MCI_STATUS_PARMS mciStatusParms;

    .

    .

    .

/* Make sure the opened device is the MIDI Mapper. */

mciStatusParms.dwItem = MCI_SEQ_STATUS_PORT;

if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,

        MCI_STATUS_ITEM, (DWORD)(LPVOID) &mciStatusParms)) {

    /* Error sending MCI_STATUS command. */

}

if (LOWORD(mciStatusParms.dwReturn) == MIDI_MAPPER) {

    /* The MIDI Mapper is the output device. */

}

else {

    /* The MIDI Mapper is not the output device. */

}

MCI also provides a command message that explicitly selects the MIDI Mapper as the output device for the sequencer. The following example uses the MCI_SET command message to select the MIDI Mapper as the output device for the MCI sequencer.

UINT wDeviceID;

DWORD dwReturn;

MCI_SEQ_SET_PARMS mciSeqSetParms;

    .

    .

    .

/* Set the MIDI Mapper as the output port for the open device. */

mciSeqSetParms.dwPort = MIDI_MAPPER;

if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SEQ_SET_PORT,

                              (DWORD)(LPVOID) &mciSeqSetParms)) {

    /* Error, unable to set Mapper as output port. */

}

Before querying the sequencer or setting an output port, you must successfully open the sequencer. Both of the previous examples assume that the wDeviceID parameter contains a valid device identifier for the sequencer.


  72.3.3.3  Opening Compact Disc Devices

Because a compact disc audio device is a simple device, you need only specify the device name when opening it by using either a string or a constant device identifier. The following example opens a compact disc device by using a constant device identifier to specify the device name.

UINT wDeviceID;

MCI_OPEN_PARMS mciOpenParms;

    .

    .

    .

/* Open the device by specifying a constant device ID. */

mciOpenParms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;

if (mciSendCommand(0,                           /* device ID */

        MCI_OPEN,                               /* command   */

        MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID,       /* flags     */

        (DWORD) (LPVOID) &mciOpenParms))  /* parameter block */

    /* Error, unable to open device. */

    return FALSE;

else

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;


  72.3.4  Handling MCI Errors

Always check the return value of the mciSendCommand function. If it indicates an error, you can use the mciGetErrorString function to get a textual description of the error. You can also interpret the error code yourself; MMSYSTEM.H defines constants for MCI error return codes.

Note   To interpret an error return value from mciSendCommand yourself, mask the high-order word, the low-order word contains the error code. However, if you pass the error return value to the mciGetErrorString function, you must pass the entire doubleword value.

The following example function takes the MCI error code specified by dwError, passes it to mciGetErrorString, and displays the resulting textual error description by using the MessageBox function.

/*

 * Uses mciGetErrorString to get a

 * text description of an MCI error.

 * Displays the error description by using MessageBox.

 */

void showError(DWORD dwError)

{

    char szErrorBuf[MAXERRORLENGTH];

    MessageBeep(MB_ICONEXCLAMATION);

    if(mciGetErrorString(dwError, (LPSTR) szErrorBuf,

            MAXERRORLENGTH))

        MessageBox(hMainWnd, szErrorBuf,

                "MCI Error", MB_ICONEXCLAMATION);

    else

        MessageBox(hMainWnd, "Unknown Error", "MCI Error",

                MB_ICONEXCLAMATION);

}


  72.3.5  Starting Playback

Once you successfully open an MCI audio device, you can use the MCI_PLAY command message along with the MCI_PLAY_PARMS structure to begin playback. MMSYSTEM.H defines MCI_PLAY_PARMS as follows.

typedef struct {

        DWORD   dwCallback; /* callback for MCI_NOTIFY flag */

        DWORD   dwFrom;     /* playback begin position      */

        DWORD   dwTo;       /* playback end position        */

} MCI_PLAY_PARMS;

Playback begins at the current position in the device element. When a device element is opened, the current position is set to the beginning of the medium. After a device element is played, the current position is at the end of the medium. You can use the MCI_SEEK command message to change the current position. For more information about MCI_SEEK, see Section 72.3.6, »Changing the Current Position«.

You can also set beginning and ending positions for playback by specifying the MCI_FROM and MCI_TO flags with the MCI_PLAY command message. If you specify one of these flags, you must fill in the corresponding dwFrom or dwTo member in the MCI_PLAY_PARMS structure with the desired beginning or ending time. If you are using a time format other than the default time format, you must set the time format before specifying a beginning or ending time with MCI_PLAY.


  72.3.5.1  Example: Playing a WAVE File

The following example function opens a waveform device and plays the WAVE file specified by the lpszWAVEFileName parameter.

/*

 * Plays a given WAVE file by using MCI_OPEN, MCI_PLAY.

 * Returns when playback

 * begins. Returns 0L on success;

 * otherwise returns an MCI error code.

 */

DWORD playWAVEFile(HWND hWndNotify, LPSTR lpszWAVEFileName)

{

    UINT wDeviceID;

    DWORD dwReturn;

    MCI_OPEN_PARMS mciOpenParms;

    MCI_PLAY_PARMS mciPlayParms;

    /*

     * Open the device by specifying the

     * device name and device element.

     * MCI will choose a device capable

     * of playing the given file.

     */

    mciOpenParms.lpstrDeviceType = "waveaudio";

    mciOpenParms.lpstrElementName = lpszWAVEFileName;

    if (dwReturn = mciSendCommand(0, MCI_OPEN,

            MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

            (DWORD)(LPVOID) &mciOpenParms)) {

        /*

         * Failed to open device;

         * don't close it, just return error.

         */

        return dwReturn;

    }

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;

    /*

     * Begin playback. The window-procedure function

     * for the parent window is notified with an

     * MM_MCINOTIFY message when playback is

     * complete. The window procedure then

     * closes the device.

     */

    mciPlayParms.dwCallback = (DWORD) hWndNotify;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY,

            MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    return 0;

}


  72.3.5.2  Example: Playing a MIDI File

The following example function opens a MIDI sequencer device, verifies that the MIDI Mapper was selected as the output port, plays the MIDI file specified by the lpszMIDIFileName parameter, and closes the device after playback is complete.

/*

 * Plays a given MIDI file using MCI_OPEN, MCI_PLAY.

 * Returns as soon as playback begins. The window

 * procedure function for the given window is notified

 * when playback is complete. Returns 0L on success;

 * otherwise returns an MCI error code.

 */

DWORD playMIDIFile(HWND hWndNotify, LPSTR lpszMIDIFileName)

{

    UINT wDeviceID;

    DWORD dwReturn;

    MCI_OPEN_PARMS mciOpenParms;

    MCI_PLAY_PARMS mciPlayParms;

    MCI_STATUS_PARMS mciStatusParms;

    /*

     * Open the device by specifying the

     * device name and device element.

     * MCI will attempt to choose the

     * MIDI Mapper as the output port.

     */

    mciOpenParms.lpstrDeviceType = "sequencer";

    mciOpenParms.lpstrElementName = lpszMIDIFileName;

    if (dwReturn = mciSendCommand(NULL, MCI_OPEN,

            MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

            (DWORD)(LPVOID) &mciOpenParms)) {

        /*

         * Failed to open device;

         * don't close it, just return error.

         */

        return dwReturn;

    }

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;

    /* See if the output port is the MIDI Mapper. */

    mciStatusParms.dwItem = MCI_SEQ_STATUS_PORT;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,

            MCI_STATUS_ITEM,

            (DWORD)(LPVOID) &mciStatusParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    /*

     * The output port is not the MIDI Mapper.

     * Ask if user wants to continue.

     */

    if (LOWORD(mciStatusParms.dwReturn) != MIDI_MAPPER) {

        if (MessageBox(hMainWnd,

                "The MIDI Mapper is not available. Continue?",

                "", MB_YESNO) == IDNO) {

            /*

             * User does not want to continue. Not an error;

             * just close the device and return.

             */

            mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

            return 0;

        }

    }

    /*

     * Begin playback. The window procedure function

     * for the parent window is notified with an

     * MM_MCINOTIFY message when playback is complete.

     * The window procedure then closes the device.

     */

    mciPlayParms.dwCallback = (DWORD) hWndNotify;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY,

            MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    return 0;

}


  72.3.5.3  Example: Playing a Compact Disc Track

The following example function opens a compact disc device, plays the track specified by the wTrack parameter, and closes the device after playback is complete.

/*

 * Plays a given compact disc track using

 * MCI_OPEN, MCI_PLAY. Returns as

 * soon as playback begins. The window procedure

 * function for the given window will be notified

 * when playback is complete. Returns 0L on

 * success; otherwise, it returns an MCI error code.

 */

DWORD playCDTrack(HWND hWndNotify, BYTE bTrack)

{

    UINT wDeviceID;

    DWORD dwReturn;

    MCI_OPEN_PARMS mciOpenParms;

    MCI_SET_PARMS mciSetParms;

    MCI_PLAY_PARMS mciPlayParms;

    /*

     * Open the compact disc device by specifying

     * the device name.

     */

    mciOpenParms.lpstrDeviceType = "cdaudio";

    if (dwReturn = mciSendCommand(NULL, MCI_OPEN,

            MCI_OPEN_TYPE, (DWORD)(LPVOID) &mciOpenParms)) {

        /*

         * Failed to open device;

         * don't close it, just return error.

         */

        return dwReturn;

    }

    /* Device opened successfully, get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;

    /* Set the time format to track/minute/second/frame. */

    mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_SET,

            MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    /*

     * Begin playback from the given track and play

     * until the beginning of the next track. The window

     * procedure function for the parent window will be

     * notified with an MM_MCINOTIFY message when playback

     * is complete. Unless the play command fails, the

     * window procedure closes the device.

     */

    mciPlayParms.dwFrom = MCI_MAKE_TMSF(bTrack, 0, 0, 0);

    mciPlayParms.dwTo = MCI_MAKE_TMSF(bTrack + 1, 0, 0, 0);

    mciPlayParms.dwCallback = (DWORD) hWndNotify;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY,

            MCI_FROM | MCI_TO | MCI_NOTIFY,

            (DWORD)(LPVOID) &mciPlayParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    return 0;

}

To specify a track-relative position with a compact disc device, you must use the track/minute/second/frame time format. For details about setting time formats, see Section 72.3.7, »Setting the Time Format«.


  72.3.6  Changing the Current Position

To change the current position in a device element, use the MCI_SEEK command message along with the MCI_TO flag and the MCI_SEEK_PARMS structure. MMSYSTEM.H defines MCI_SEEK_PARMS as follows.

typedef struct {

        DWORD   dwCallback; /* callback for MCI_NOTIFY flag */

        DWORD   dwTo;       /* seek position */

} MCI_SEEK_PARMS;

If you use the dwTo member to specify a seek position with MCI_SEEK, you should query the time format and set it, if necessary.

In addition to specifying a position with the dwTo member, you can specify the MCI_SEEK_TO_START or MCI_SEEK_TO_END flags for the dwParam1 parameter of the mciSendCommand function to find the starting and ending positions of the device element. If you use one of these flags, don't specify the MCI_TO flag.


  72.3.7  Setting the Time Format

Use the MCI_SET command message along with the MCI_SET_PARMS structure to set the time format for an open device. Set the dwTimeFormat member to one of the following constants.

Constant	Time format
MCI_FORMAT_BYTES	Bytes (in pulse code modulated [PCM] format files)
MCI_FORMAT_MILLISECONDS	Milliseconds
MCI_FORMAT_MSF	Minute/second/frame
MCI_FORMAT_SAMPLES	Samples
MCI_FORMAT_SMPTE_24	SMPTE, 24 frame
MCI_FORMAT_SMPTE_25	SMPTE, 25 frame
MCI_FORMAT_SMPTE_30	SMPTE, 30 frame
MCI_FORMAT_SMPTE_30DROP	SMPTE, 30 frame drop
MCI_FORMAT_TMSF	Track/minute/second/frame
MCI_SEQ_FORMAT_SONGPTR	MIDI song pointer
The following example sets the time format to milliseconds on the device specified by wDeviceID:

UINT wDeviceID;

MCI_SET_PARMS mciSetParms;

    .

    .

    .

/* Set time format to milliseconds. */

mciSetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;

if (mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT,

                   (DWORD) &mciSetParms))

    /* Error, unable to set time format. */

    return FALSE;

else

    /* Time format set successfully. */

    return TRUE;


  72.3.7.1  Using the Minute/Second/Frame Time Format

In the minute/second/frame time format specified with the MCI_FORMAT_MSF constant, the time is relative to the beginning of the medium. The time is packed into a double as follows.

Word	Byte	Contents
High-order word	High-order byte	Unused
	Low-order byte	Frames
Low-order word	High-order byte	Seconds
	Low-order byte	Minutes
The MMSYSTEM.H header file defines the following macros to get and set elements of a minute/second/frame packed doubleword.

Macro	Description
MCI_MSF_MINUTE	Gets minute value in a minute/second/frame doubleword.
MCI_MSF_SECOND	Gets second value in a minute/second/frame doubleword.
MCI_MSF_FRAME	Gets frame value in a minute/second/frame doubleword.
MCI_MAKE_MSF	Sets minute, second, and frame values in a minute/second/frame doubleword.
Note   The first few seconds of audio compact discs contain table-of-contents data. To play from the beginning of a disc using the minute/second/frame time format, use the MCI_STATUS command message to get the position of the first track and play from that position.


  72.3.7.2  Using the Track/Minute/Second/Frame Time Format

In the track/minute/second/frame time format specified with the MCI_FORMAT_TMSF constant, the time is relative to the beginning of the specified track. The time is packed into a doubleword, as follows.

Word	Byte	Contents
High-order word	High-order byte	Frames
	Low-order byte	Seconds
Low-order word	High-order byte	Minutes
	Low-order byte	Track
The MMSYSTEM.H header file defines the following macros to get and set elements of a track/minute/second/frame packed doubleword.

Macro	Description
MCI_TMSF_TRACK	Gets track value in a track/minute/second/frame doubleword.
MCI_TMSF_MINUTE	Gets minute value in a track/minute/second/frame doubleword.
MCI_TMSF_SECOND	Gets second value in a track/minute/second/frame doubleword.
MCI_TMSF_FRAME	Gets frame value in a track/minute/second/frame doubleword.
MCI_MAKE_TMSF	Sets track, minute, second, and frame values in a track/minute/second/frame doubleword.


  72.3.7.3  Using the SMPTE Time Formats

Society of Motion Picture and Television Engineers (SMPTE) time formats are based on standard time formats developed for the motion picture and television industries. For SMPTE time formats, the time is packed into a doubleword, as shown in the following table follows.

Word	Byte	Contents
High-order word	High-order byte	Frames
	Low-order byte	Seconds
Low-order word	High-order byte	Minutes
	Low-order byte	Hours


  72.3.8  Closing MCI Audio Devices

After you finish using an MCI device, you must use the MCI_CLOSE command messages to close the device. If you are playing a compound device, such as a waveform or MIDI device, and want to play a different device element using the same device, close the device and reopen it using the new device element.

Note   If you're playing multiple device elements with the same device, you'll get better performance if you open the device by explicitly specifying its name, then open, play, and close the individual device elements separately. Don't close the device until you have finished playing all of the device elements. Otherwise, the driver is reloaded each time you open the device.


  72.3.9  Getting Information About Devices and Media

Use the MCI_STATUS command message along with the MCI_STATUS_PARMS structure to get information about the status of an open device and its associated device element.

Before using the MCI_STATUS command message, you must identify the status item to query for by putting a constant in the dwItem member of the structure. Following are the constants and their corresponding status items for the different audio device types.


  All Audio Devices

Constant	Status item
MCI_STATUS_LENGTH	Length of the medium
MCI_STATUS_POSITION	Current position
MCI_STATUS_MODE	Current mode
MCI_STATUS_TIME_FORMAT	Time format
MCI_STATUS_READY	Ready state


  Waveform Devices

Constant	Status item
MCI_WAVE_STATUS_BLOCKALIGN	Block alignment
MCI_WAVE_STATUS_FORMATTAG	Format tag
MCI_WAVE_STATUS_CHANNELS	Number of channels
MCI_WAVE_STATUS_SAMPLESPERSEC	Sample rate
MCI_WAVE_STATUS_AVGBYTESPERSEC	Average bytes per second
MCI_WAVE_STATUS_BITSPERSAMPLE	Bits per sample (in PCM format files)
MCI_WAVE_STATUS_LEVEL	Record level


  Compact Disc Devices

Constant	Status item
MCI_STATUS_NUMBER_OF_TRACKS	Number of tracks
MCI_STATUS_MEDIA_PRESENT	Media present
MCI_STATUS_CURRENT_TRACK	Current track


  MIDI Sequencer Devices

Constant	Status item
MCI_SEQ_STATUS_TEMPO	Tempo
MCI_SEQ_STATUS_PORT	Port
MCI_SEQ_STATUS_OFFSET	SMPTE offset
MCI_SEQ_STATUS_DIVTYPE	Division type of file


  72.3.9.1  Getting Track-Relative Information for Compact Disc Devices

For compact disc devices, you can get the starting position and length of a track by specifying the MCI_TRACK flag and setting the dwTrack member of the MCI_STATUS_PARMS structure to the desired track number. To get the starting position of a track, set the dwItem member to MCI_STATUS_POSITION. To get the length of a track, set dwItem to MCI_STATUS_LENGTH. The following function gets the number of tracks on the disc and the starting position of each track. It then uses the MessageBox function to report the starting positions of the tracks.

/*

 * Uses the MCI_STATUS command to get and

 * display the starting times for the tracks

 * on a compact disc. Returns 0L on success;

 * otherwise, it returns an MCI error code.

 */

DWORD getCDTrackStartTimes(void)

{

    UINT wDeviceID;

    int i, iNumTracks;

    DWORD dwReturn;

    DWORD *pMem;

    char szTempString[64];

    char szTimeString[512] = "\0"; /* enough for 20 tracks */

    MCI_OPEN_PARMS mciOpenParms;

    MCI_SET_PARMS mciSetParms;

    MCI_STATUS_PARMS mciStatusParms;

    /* Open the compact disc device by specifying the device name.

     */

    mciOpenParms.lpstrDeviceType = "cdaudio";

    if (dwReturn = mciSendCommand(NULL, MCI_OPEN,

            MCI_OPEN_TYPE,

            (DWORD)(LPVOID) &mciOpenParms)) {

        /*

         * Failed to open device.

         * Don't have to close it; just return error.

         */

        return dwReturn;

    }

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;

    /* Set the time format to minute/second/frame format. */

    mciSetParms.dwTimeFormat = MCI_FORMAT_MSF;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_SET,

            MCI_SET_TIME_FORMAT,

            (DWORD)(LPVOID) &mciSetParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    /* Get the number of tracks; limit to number

     * we can display (20).

     */

    mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,

            MCI_STATUS_ITEM,

            (DWORD)(LPVOID) &mciStatusParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    iNumTracks = mciStatusParms.dwReturn;

    iNumTracks = min(iNumTracks, 20);

    /* Allocate memory to hold starting positions. */

    pMem = (DWORD *)LocalAlloc(LPTR, iNumTracks * sizeof(DWORD));

    if (pMem == NULL) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return 0xFFFFFFFF;

    }

    /*

     * For each track, get and save the starting position and

     * build a string containing starting positions.

     */

    for(i = 1; i <= iNumTracks; i++) {

        mciStatusParms.dwItem = MCI_STATUS_POSITION;

        mciStatusParms.dwTrack = i;

        if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,

                MCI_STATUS_ITEM | MCI_TRACK,

                (DWORD)(LPVOID) &mciStatusParms)) {

            mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

            return dwReturn;

        }

        pMem[i-1] = mciStatusParms.dwReturn;

        wsprintf(szTempString, "Track %2d - %02d:%02d:%02d\n",

                 i, MCI_MSF_MINUTE(pMem[i-1]),

                 MCI_MSF_SECOND(pMem[i-1]),

                 MCI_MSF_FRAME(pMem[i-1]));

        lstrcat(szTimeString, szTempString);

    }

    /* Use MessageBox to display starting times. */

    MessageBox(hMainWnd, szTimeString, "Track Starting Position",

               MB_ICONINFORMATION);

    /* Free memory and close the device. */

    LocalFree((HANDLE) pMem);

    if (dwReturn = mciSendCommand(wDeviceID,

            MCI_CLOSE, 0, NULL)) {

            return dwReturn;

    }

    return 0;

}


  72.3.10  Recording With Waveform Audio Devices

MCI supports recording with waveform audio devices. You can insert or overwrite recorded information in an existing file or record into a new file. To open an existing file for recording, open a waveform device and device element as you would open them for playback. To record into a new file, open the device but specify a zero-length filename for the device element.

When MCI creates a new file for recording, the waveform data format is set to a default format specified by the device driver. To use a format other than the default format, you can use the MCI_SET command message to change the format.

To begin recording, use the MCI_RECORD command message along with the MCI_RECORD_PARMS structure.

If you record to an existing file, you can use the MCI_TO and MCI_FROM flags to specify beginning and ending points for recording. For example, if you record to an existing file 20 seconds long, and you begin recording at 5 seconds and end recording at 10 seconds, you will have a recording 25 seconds long. It will contain 5 seconds of the original recording followed by the 5 seconds of new recording, and will end with the remaining 15 seconds of the original recording.

If you don't specify an ending position, recording continues until you send an MCI_STOP command message, or until the driver runs out of free disk space. If you record to a new file, you can omit the MCI_FROM flag or set it to 0 to start recording at the beginning of a new file. You can specify an ending position to terminate recording when recording to a new file.

If you record in overwrite mode to an existing file, you can use the MCI_TO and MCI_FROM flags to specify beginning and ending points of the waveform section that is to be overwritten. For example, if you record to an existing file 20 seconds long, and you begin recording at 5 seconds and end recording at 10 seconds, you still have a recording 20 seconds long. However, the section beginning at 5 seconds and ending at 10 seconds has been replaced.


  72.3.10.1  Saving a Recorded File

When recording is complete, use the MCI_SAVE command message along with the MCI_SAVE_PARMS structure to save the recording before closing the device.

If you close the device without saving, the recorded data is lost.


  72.3.10.2  Checking Input Levels on PCM Devices

To get the level of the input signal before recording on a pulse code modulated (PCM) waveform input device, use the MCI_STATUS command message. Specify the MCI_STATUS_ITEM flag and set the dwItem member in the MCI_STATUS_PARMS structure to MCI_WAVE_STATUS_LEVEL. The average input signal level is returned in the dwReturn member of the MCI_STATUS_PARMS structure. The left-channel value is in the high-order word, and the right- or mono-channel value is in the low-order word.

The input level is represented as an unsigned value. For 8-bit samples, this value is in the range 0 through 127 (0x7F). For 16-bit samples, it is in the range 0 through 32,767 (0x7FFF).


  72.3.10.3  Example of Recording With a Waveform Audio Device

The following example function opens a waveform audio device with a new file, records for the specified time, plays the recording, and prompts the user to specify whether the recording should be saved as a file.

/*

 * Uses the MCI_OPEN, MCI_RECORD, MCI_SAVE commands to record and

 * save a waveform audio file. Returns 0L on success; otherwise,

 * returns an MCI error code.

 */

DWORD recordWAVEFile(DWORD dwMilliSeconds)

{

    UINT wDeviceID;

    DWORD dwReturn;

    MCI_OPEN_PARMS mciOpenParms;

    MCI_RECORD_PARMS mciRecordParms;

    MCI_SAVE_PARMS mciSaveParms;

    MCI_PLAY_PARMS mciPlayParms;

    /*

     * Open a waveform device with a new file for recording.

     */

    mciOpenParms.lpstrDeviceType = "waveaudio";

    mciOpenParms.lpstrElementName = "";

    if (dwReturn = mciSendCommand(0, MCI_OPEN,

            MCI_OPEN_ELEMENT | MCI_OPEN_TYPE,

            (DWORD)(LPVOID) &mciOpenParms)) {

        /*

         * Failed to open device. Don't close it; just return

         * error.

         */

        return dwReturn;

    }

    /* Device opened successfully. Get the device ID. */

    wDeviceID = mciOpenParms.wDeviceID;

    /*

     * Begin recording and record for the specified number

     * of milliseconds. Wait for recording to complete before

     * continuing. Assume the default time format for the

     * waveform device (milliseconds).

     */

    mciRecordParms.dwTo = dwMilliSeconds;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_RECORD,

            MCI_TO | MCI_WAIT, (DWORD)(LPVOID) &mciRecordParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    /* Play the recording and query user to save the file. */

    mciPlayParms.dwFrom = 0;

    if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY,

            MCI_FROM | MCI_WAIT,

            (DWORD)(LPVOID) &mciPlayParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    if (MessageBox(hMainWnd, "Do you want to save this recording?",

            "", MB_YESNO) == IDNO) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return 0;

    }

    /*

     * Save the recording to a file named TEMPFILE.WAV. Wait for

     * the operation to finish before continuing.

     */

    mciSaveParms.lpfilename = "tempfile.wav";

    if (dwReturn = mciSendCommand(wDeviceID, MCI_SAVE,

            MCI_SAVE_FILE | MCI_WAIT,

            (DWORD)(LPVOID) &mciSaveParms)) {

        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

        return dwReturn;

    }

    return 0;

}


  72.3.11  Using the MCI MIDI Sequencer

The MCI MIDI sequencer plays standard MIDI files and Resource Interchange File Format (RIFF) MIDI files (RMID files). Standard MIDI files conform to the "Standard MIDI Files 1.0" specification. For information about this specification, see Chapter 71, »Introduction to Audio«. Because RMID files are standard MIDI files with a RIFF header, information about standard MIDI files also applies to RMID files.

There are currently three variations of standard MIDI files. The MCI sequencer plays only two of these: format 0 and format 1 MIDI files.

Note   When the MCI MIDI sequencer encounters a MIDI file not marked as being authored for Windows, it displays a dialog box informing the user. MIDI files authored for Windows should be marked with the MARKMIDI utility program. For additional information about MARKMIDI, see Section 72.5.5, »Using the MARKMIDI Utility«.


  72.3.11.1  Querying for Sequence Division Types

The division type of a MIDI sequence refers to the technique used to represent the time between MIDI events in the sequence. Use the MCI_STATUS command message and set the dwItem member of the MCI_STATUS_PARMS structure to MCI_SEQ_STATUS_DIVTYPE to determine the division type of a sequence.

If the MCI_STATUS command message succeeds, the dwReturn member of the MCI_STATUS_PARMS structure contains one of the following values to indicate the division type.

Value	Division type
MCI_SEQ_DIV_PPQN	PPQN (parts per quarter-note)
MCI_SEQ_DIV_SMPTE_24	SMPTE, 24 frames per second (fps)
MCI_SEQ_DIV_SMPTE_25	SMPTE, 25 fps
MCI_SEQ_DIV_SMPTE_30	SMPTE, 30 fps
MCI_SEQ_DIV_SMPTE_30DROP	SMPTE, 30 fps drop frame
You must know the division type of a sequence to change or query its tempo. You can't change the division type of a sequence by using the MCI sequencer.


  72.3.11.2  Querying and Setting the Tempo

Use the MCI_STATUS command message and set the dwItem member of the MCI_STATUS_PARMS structure to MCI_SEQ_STATUS_TEMPO to get the tempo of a sequence. If the MCI_STATUS command message succeeds, the dwReturn member of the MCI_STATUS_PARMS structure contains the current tempo.

To change tempo, use the MCI_SET command message with the MCI_SEQ_SET_PARMS structure. Specify the MCI_SEQ_SET_TEMPO flag and set the value of the dwTempo member of the structure to the desired tempo.

The way tempo is represented depends on the division type of the sequence. If the division type is PPQN, the tempo is represented in beats per minute. If the division type is one of the SMPTE division types, the tempo is represented in frames per second. For information about determining the division type of a sequence, Section 72.3.11.1, »Querying for Sequence Division Types«.


  72.3.11.3  Changing Sequencer Synchronization

To change the synchronization mode of a sequencer device, use the MCI_SET command message with the MCI_SEQ_SET_MASTER and MCI_SEQ_SET_SLAVE flags. Two members in the MCI_SEQ_SET_PARMS structure, dwMaster and dwSlave, are used to specify the master and slave synchronization modes.

The master synchronization mode controls synchronization information sent by the sequencer to an output port. The slave synchronization mode controls where the sequencer gets its timing information to play a MIDI file. Following are the constants for the dwMaster member and their corresponding master synchronization modes.

Constant	Synchronization mode
MCI_SEQ_MIDI	MIDI Synchronization. Send timing information to output port using MIDI timing clock messages.
MCI_SEQ_SMPTE	SMPTE Synchronization. Send timing information to output port using MIDI quarter-frame messages.
MCI_SEQ_NONE	No Synchronization. Send no timing information.
Following are the constants for the dwSlave member and their corresponding slave synchronization modes.

Constant	Synchronization mode
MCI_SEQ_FILE	File Synchronization. Get timing information from MIDI file.
MCI_SEQ_MIDI	MIDI Synchronization. Get timing information from input port using MIDI timing clock messages.
MCI_SEQ_SMPTE	SMPTE Synchronization. Get timing information from input port using MIDI quarter-frame messages.
MCI_SEQ_NONE	No Synchronization. Get timing information from MCI commands only and ignore timing information (such as tempo changes) that are in the MIDI file.
Note   Currently, for master synchronization, the MCI MIDI sequencer supports only the No Synchronization mode (MCI_SEQ_NONE). For slave synchronization, it supports only the File Synchronization mode (MCI_SEQ_FILE) and the No Synchronization mode (MCI_SEQ_NONE).


  72.4  The MIDI Mapper

The MIDI Mapper's standard patch services provide device-independent MIDI file playback for applications. You don't need to understand exactly how the MIDI Mapper works to use these services. The MIDI Mapper can be used with the MCI MIDI sequencer or with low-level MIDI output services.

To learn more about the MIDI Mapper or about authoring standard MIDI files for Windows, read this section to become familiar with how the MIDI Mapper works. For specific information about how to use the MIDI Mapper, see Section 72.3.11, »Using the MCI MIDI Sequencer« or Chapter 73, »Low-Level Audio«.


  72.4.1  MIDI Notational Conventions

Unless stated otherwise, all references to MIDI channel numbers use the logical channel numbers 1 through 16. These logical channel numbers correspond to the physical channel numbers 0 through 15 that are actually part of the MIDI message. All references to MIDI program-change and key values use the physical values 0 through 127. All numbers are decimal unless preceded by 0x prefix, in which case they are hexadecimal.

In the discussion of the MIDI Mapper, the term source refers to the input side of the MIDI Mapper. The term destination refers to the output side of the MIDI Mapper. For example, a source channel is the MIDI channel of a message sent to the MIDI Mapper, and a destination channel is the MIDI channel of a message sent from the MIDI Mapper to an output device.


  72.4.2  The MIDI Mapper and Windows

The MIDI Mapper is part of the system software. »This illustration«shows how the MIDI Mapper relates to other elements of the audio services.

From the viewpoint of an application, the MIDI Mapper looks like another MIDI output device. The MIDI Mapper receives messages sent to it by the low-level MIDI output functions midiOutShortMsg and midiOutLongMsg. The MIDI Mapper modifies these messages and redirects them to a MIDI output device according to the current MIDI setup map. The current MIDI setup map is selected by the user by means of the MIDI Control Panel option. Only the user can select the current setup map; applications cannot change the current setup map.


  72.4.3  The MIDI Mapper Architecture

The MIDI Mapper uses a MIDI setup map to determine how to translate and redirect messages it receives. A MIDI setup map consists of the following types of maps.

•	Channel map

•	Patch map

•	Key map

»This illustration« shows the roles of channel, patch, and key maps in a MIDI setup map.


  72.4.4  The Channel Map

The channel map affects all MIDI channel messages. MIDI channel messages include note-on, note-off, polyphonic-key-aftertouch, control-change, program- change, channel-aftertouch, and pitch-bend-change messages. The MIDI Mapper uses a single channel map with an entry for each of the 16 MIDI channels. Each channel-map entry specifies the following:

•	A destination channel for the MIDI message

•	A destination output device for the MIDI message

•	An optional patch map specifying other possible modifications for the MIDI message

The destination channel is set to one of the 16 MIDI channels. MIDI messages are modified to reflect each new channel assignment. For example, if the destination channel entry for MIDI channel 4 is set to 6, all MIDI messages sent to channel 4 will be mapped to channel 6, as shown in »this illustration«.

In this example, the MIDI status byte 0x93 is mapped to 0x95. The low-order of a MIDI status byte specify the channel number. Source channels are set to either active or inactive. Messages sent to inactive source channels are ignored, so an inactive channel is in effect muted or turned off.

The destination output device is set to one of the available MIDI output devices. A MIDI output device can be an internal synthesizer or a physical MIDI output port.

MIDI system messages are MIDI messages (with status bytes) from 0xF0 to 0xFF. There is no channel associated with MIDI system messages, so they can't be mapped. MIDI system messages are sent to all MIDI output devices listed in a channel map.


  72.4.5  Patch Maps

Each channel map entry can have an associated patch map. Patch maps affect MIDI program-change and volume-controller messages. Program-change messages tell a synthesizer to change the instrument sound (patch) for a specified channel. Volume-controller messages set the volume for a channel.

A patch map has a translation table with an entry for each of the 128 program-change values. Each patch map specifies the following:

•	A destination program-change value

•	A volume scalar

•	An optional key map

When program-change messages are received by the MIDI Mapper, the destination program-change value is substituted for the program-change value in the message. For example, if the destination program-change value for program-change 16 is 18, the MIDI Mapper modifies the MIDI program-change message as shown in »this illustration«.


  72.4.5.1  The Volume Scalar

The purpose of the volume scalar is to allow adjustments between the relative output levels of different patches on a synthesizer. For example, if the bass patch on a synthesizer is too loud compared with its piano patch, you can change the setup map to scale the bass volume down or the piano volume up.

The volume scalar specifies a percentage value for changing all MIDI main-volume controller messages that follow an associated program-change message. For example, if the volume scalar value is 50%, the MIDI Mapper modifies MIDI main-volume controller messages as shown in »this illustration«:


  72.4.6  Key Maps

Each entry in the patch-map translation table can have an associated key map. Key maps affect note-on, note-off, and polyphonic-key-aftertouch messages. A key map has a translation table with an entry for each of the 128 MIDI key values. For example, if the entry for key value 60 is 72, the MIDI Mapper modifies MIDI note-on messages as shown in »this illustration«.

Key maps are useful with synthesizers that have key-based percussion instruments with a particular percussion sound assigned to each key. Key maps are usually assigned to the first patch in the patch maps on the percussion channels (10 and 16).


  72.4.7  Summary of Maps and MIDI Messages

Following are the status bytes for MIDI messages and the map types that affect each message.

MIDI status	Description	Map types
0x80−0x8F	Note-off	Channel maps, key maps
0x90−0x9F	Note-on	Channel maps, key maps
0xA0−0xAF	Polyphonic-key-aftertouch	Channel maps, key maps
0xB0−0xBF	Control-change	Channel maps, patch maps
0xC0−0xCF	Program-change	Channel maps, patch maps
0xD0−0xDF	Channel-aftertouch	Channel maps
0xE0−0xEF	Pitch-bend-change	Channel maps
0xF0−0xFF	System	Not mapped
•	The high-order four bits represent the status value. The low-order four bits represent the channel information.

•	Patch maps affect only controller 7 (main volume).

•	System messages are sent to all devices listed in a channel map.


  72.5  Authoring MIDI Files

The "MIDI 1.0 Detailed Specification" does not define any standard patch assignments for synthesizers. Therefore, when you create a MIDI file, it won't be reproduced correctly unless it is played back on the same MIDI synthesizer setup used to create it. For example, if you create a piano concerto for your Yamaha® DX7 and try to play it back on a Roland® LAPC-1, it may be played with a flute instead of a piano.

To enable MIDI files to be a viable format for representing music in multimedia computing, Windows provides MIDI authoring guidelines. These guidelines include a list of standard patch assignments and standard key assignments for percussion instruments. Using the MIDI Mapper, MIDI files authored in accordance with these guidelines can be played on any multimedia computer with internal or external MIDI synthesizers.


  72.5.1  About Base-Level and Extended Synthesizers

Although it is difficult to clearly quantify distinctions between synthesizers, it is important to have some guidelines so you can create MIDI files that will play on all multimedia computers. The terms used to distinguish synthesizers for the purpose of authoring MIDI files are base-level synthesizer and extended synthesizer.

The distinctions between base-level and extended synthesizers are made solely on the number of instruments and notes the synthesizer can play, not on the quality or the cost of the synthesizer. Following are the minimum capabilities of base-level and extended synthesizers.

Synthesizer	Melodic instruments		Percussive instruments
	Number	Polyphony	Number	Polyphony
Base-level	3 instruments	6 notes	3 instruments	3 notes
Extended	9 instruments	16 notes	8 instruments	16 notes
Polyphony is the number of notes the synthesizer can play simultaneously. The polyphony expressed above applies to each group of instruments — melodic and percussive. For example, a base-level synthesizer is capable of playing six notes distributed among three melodic instruments and three notes distributed among three percussive instruments. Each melodic instrument is on a different MIDI channel; the percussive instruments are key-based — all on a single MIDI channel.

All multimedia computers provide at least a base-level synthesizer. Users can enhance their computer by adding internal or external synthesizers, which can be either base-level or extended synthesizers. When adding a synthesizer, the user must configure the MIDI Mapper to use the new device. If the MIDI Mapper is not configured, the instrument sounds will be incorrect when MIDI files are played, unless the application has the ability to send output directly to an internal synthesizer or output port. The MIDI Control Panel option allows a user to configure the MIDI Mapper as needed.


  72.5.2  Authoring Guidelines for MIDI Files

Follow these guidelines to author device-independent MIDI files for Windows:

•	Author for both base-level and extended synthesizer setups.

•	Use MIDI channels 13 through 16 for base-level synthesizer data (reserve channel 16 for key-based percussion instruments).

•	Use MIDI channels 1 through 10 for extended synthesizer data (reserve channel 10 for key-based percussion instruments).

•	Prioritize MIDI data by putting crucial data in the lower-numbered channels.

•	Limit the polyphony of nonpercussive channels to a total of 6 notes for base-level data and 16 notes for extended data.

•	Limit the polyphony of percussive channels to a total of 3 notes for base-level data and 16 notes for extended data.

•	Use the standard MIDI patch assignments and key assignments.

•	Always send a program-change message to a channel to select a patch before sending other messages to that channel. For the two percussion channels (10 and 16), select program number 0.

•	Always follow a MIDI program-change message with a MIDI main-volume controller message (controller number 7) to set the relative volume of the patch.

•	Use a value of 80 (0x50) for the main-volume controller for normal listening levels. For quieter or louder levels, you can use lower or higher values.

•	Use only the following MIDI messages: note-on with velocity, note-off, program change, pitch bend, main volume (controller 7), and damper pedal (controller 64). Internal synthesizers are required to respond to these messages and most MIDI musical instruments respond to them as well.

•	Use the MARKMIDI utility program to mark MIDI files authored for Windows.

»This illustration« summarizes the use of the 16 MIDI channels in a standard MIDI file authored for Windows.


  72.5.2.1  Prioritizing MIDI Data

Synthesizers don't always fall cleanly into the base-level and extended designations defined earlier. It's up to the user to determine how to use synthesizers that are capable of more than the base-level requirements but do not fully meet the extended requirements. For this reason, it's important to prioritize the melodic data by putting the most critical data in lower-numbered channels. For example, a user may have a synthesizer capable of playing six melodic instruments with 12-note polyphony. The user can use this device as an extended synthesizer by setting up the MIDI Mapper to play only the first six melodic channels and ignore any information on channels 7, 8, and 9.


  72.5.3  Standard MIDI Patch Assignments

The standard MIDI patch assignments for authoring MIDI files for use with Windows are based on the MIDI Manufacturers Association (MMA) General MIDI Mode specification. Following are the standard MIDI patch assignments.

Piano	Chromatic Percussion	Organ
0 Acoustic grand piano	8 Celesta	16 Hammond organ
1 Bright acoustic piano	9 Glockenspiel	17 Percussive organ
2 Electric grand piano	10 Music box	18 Rock organ
3 Honky-tonk piano	11 Vibraphone	19 Church organ
4 Rhodes piano	12 Marimba	20 Reed organ
5 Chorused piano	13 Xylophone	21 Accordion
6 Harpsichord	14 Tubular bells	22 Harmonica
7 Clavinet	15 Dulcimer	23 Tango accordion
Guitar	Bass	Strings
24 Acoustic guitar (nylon)	32 Acoustic bass	40 Violin
25 Acoustic guitar (steel)	33 Electric bass (finger)	41 Viola
26 Electric guitar (jazz)	34 Electric bass (pick)	42 Cello
27 Electric guitar (clean)	35 Fretless bass	43 Contrabass
28 Electric guitar (muted)	36 Slap bass 1	44 Tremolo strings
29 Overdriven guitar	37 Slap bass 2	45 Pizzicato strings
30 Distortion guitar	38 Synth bass 1	46 Orchestral harp
31 Guitar harmonics	39 Synth bass 2	47 Timpani
Ensemble	Brass	Reed
48 String ensemble 1	56 Trumpet	64 Soprano sax
49 String ensemble 2	57 Trombone	65 Alto sax
50 Synth. strings 1	58 Tuba	66 Tenor sax
51 Synth. strings 2	59 Muted trumpet	67 Baritone sax
52 Choir Aahs	60 French horn	68 Oboe
53 Voice Oohs	61 Brass section	69 English horn
54 Synth voice	62 Synth. brass 1	70 Bassoon
55 Orchestra hit	63 Synth. brass 2	71 Clarinet
Pipe	Synth Lead	Synth Pad
72 Piccolo	80 Lead 1 (square)	88 Pad 1 (new age)
73 Flute	81 Lead 2 (sawtooth)	89 Pad 2 (warm)
74 Recorder	82 Lead 3 (calliope lead)	90 Pad 3 (polysynth)
75 Pan flute	83 Lead 4 (chiff lead)	91 Pad 4 (choir)
76 Bottle blow	84 Lead 5 (charang)	92 Pad 5 (bowed)
77 Shakuhachi	85 Lead 6 (voice)	93 Pad 6 (metallic)
78 Whistle	86 Lead 7 (fifths)	94 Pad 7 (halo)
79 Ocarina	87 Lead 8 (brass + lead)	95 Pad 8 (sweep)
Sound Effects
120 Guitar fret noise
121 Breath noise
122 Seashore
123 Bird tweet
124 Telephone ring
125 Helicopter
126 Applause
127 Gunshot


  72.5.4  Standard MIDI Key Assignments

The standard MIDI key assignments for percussion instruments are based on the MMA General MIDI Mode specification. »This illustration« shows the standard key assignments for MIDI files authored for Windows.


  72.5.5  Using the MARKMIDI Utility

The MARKMIDI utility program marks MIDI files as following the authoring guidelines for Windows MIDI files. The program does not verify that the file is authored correctly; it only marks the file by adding a sequencer-specific meta-event to the first track chunk. MARKMIDI has the following command syntax.

MARKMIDI src-filename dest-filename

If the MCI MIDI sequencer is used to play a MIDI file not marked by MARKMIDI, it displays a dialog box informing the user that the file is not authored for Windows.

Note   Do not use MARKMIDI to mark MIDI files unless the files were authored according to the guidelines presented in this chapter. If your application uses MIDI files not authored to these guidelines, the application must instruct users to install or create the proper maps by using the MIDI Mapper Control Panel application. For example, if your application uses MIDI files following the General MIDI channel recommendations, your users should create or install a General MIDI map for their synthesizers.


Low-Level Audio
  Chapter 73    Low-Level Audio

This chapter explains how to use the low-level audio services of Microsoft Windows to manage playback and recording of waveform and Musical Instrument Digital Interface (MIDI) audio. For an overview of the audio services, see Chapter 71, »Introduction to Audio«.

This chapter covers the following topics:

•	Using low-level audio services

•	Playing waveform audio

•	Recording waveform audio

•	Playing MIDI audio

•	Recording MIDI audio

•	Using auxiliary audio devices

•	Using audio clipboard formats

You should have a basic knowledge of digital audio and MIDI before reading this chapter. If you need additional information on these subjects, see Chapter 71, »Introduction to Audio«.


  73.1  Function Prefixes

Low-level audio function names begin with the following prefixes.

Prefix	Description
aux	Auxiliary audio functions
midi	MIDI audio functions
wave	Waveform audio functions


  73.2  Using Low-Level Audio Services

Low-level audio services control different types of audio devices, including waveform, MIDI, and auxiliary audio devices. Many of the concepts for using low-level services apply to more than one type of device. This section presents general information on using low-level audio services. It covers the following topics:

•	Querying audio devices

•	Opening and closing device drivers

•	Allocating and preparing audio data blocks

•	Managing audio data blocks

•	Using the MMTIME structure

•	Handling errors

Subsequent sections in this chapter discuss the use of specific types of audio devices.


  73.2.1  Querying Audio Devices

Before playing or recording audio, you must determine the capabilities of the audio hardware present in the system. Audio capability can vary from one multimedia computer to the next; applications should not make assumptions about the audio hardware present in a given system.


  73.2.1.1  Getting the Number of Devices

The Win32 application programming interface (API) provides the following functions to determine how many devices of a certain type are available in a given system.

Function	Description
auxGetNumDevs	Retrieves the number of auxiliary audio devices present in the system.
midiInGetNumDevs	Retrieves the number of MIDI input devices present in the system.
midiOutGetNumDevs	Retrieves the number of MIDI output devices present in the system.
waveInGetNumDevs	Retrieves the number of waveform input devices present in the system.
waveOutGetNumDevs	Retrieves the number of waveform output devices present in the system.
Audio devices are identified by a device identifier. The device identifier is determined implicitly from the number of devices present in a given system. Device identifiers range from zero to one less than the number of devices present. For example, if there are two MIDI output devices in a system, valid device identifiers are 0 and 1.


  73.2.1.2  Getting the Capabilities of a Device

After you determine how many devices of a certain type are present in a system, you can inquire about the capabilities of each device. The Win32 API provides the following functions to determine the capabilities of audio devices.

Function	Description
auxGetDevCaps	Retrieves the capabilities of a given auxiliary audio device.
midiInGetDevCaps	Retrieves the capabilities of a given MIDI input device.
midiOutGetDevCaps	Retrieves the capabilities of a given MIDI output device.
waveInGetDevCaps	Retrieves the capabilities of a given waveform input device.
waveOutGetDevCaps	Retrieves the capabilities of a given waveform output device.
Each of these functions takes a pointer to a structure that it fills with information on the capabilities of a specified device. Following are the structures that correspond to each of the device-inquiry functions.

Function	Structure
auxGetDevCaps	AUXCAPS
midiInGetDevCaps	MIDIINCAPS
midiOutGetDevCaps	MIDIOUTCAPS
waveInGetDevCaps	WAVEINCAPS
waveOutGetDevCaps	WAVEOUTCAPS


  73.2.2  Opening and Closing Device Drivers

After getting the capabilities of an audio device, you must open the device before you can use it. Audio devices aren't guaranteed to be shareable, so a particular device might not be available when you request it. If this happens, you should notify the user and allow the user to try to open the device again. When you open an audio device, be sure to close it as soon as you finish using it.

The Win32 API provides the following functions to open and close different types of audio devices.

Function	Description
midiInOpen	Opens a specified MIDI input device for recording.
midiInClose	Closes a specified MIDI input device.
midiOutOpen	Opens a MIDI output device for playback.
midiOutClose	Closes a specified MIDI output device.
waveInOpen	Opens a waveform input device for recording.
waveInClose	Closes a specified waveform input device.
waveOutOpen	Opens a waveform output device for playback.
waveOutClose	Closes a specified waveform output device.
These functions are discussed in detail later in this chapter.


  73.2.2.1  About Device Handles

Each function that opens an audio device takes as parameters a device identifier, a pointer to a memory location, and some parameters unique to each type of device. The memory location is filled with a device handle. Use this device handle of identify the open audio device when calling other audio functions.

The distinction between audio-device identifiers and audio-device handles is subtle, but very important. Don't confuse the two in your application. Following are the differences between device identifiers and device handles.

•	Device identifiers are determined implicitly from the number of devices present in a system, which is obtained by using the device-numbering functions (auxGetNumDevs, midiInGetNumDevs, and so on).

•	Device handles are returned when device drivers are opened by using the device-opening functions (midiInOpen, midiOutOpen, and so on)

•	The only functions that take device identifiers as parameters are the device-capabilities functions (auxGetDevCaps, midiInGetDevCaps, and so on), the device-opening functions, and volume functions (auxGetVolume, auxSetVolume, and so on). All other functions take device handles.

There are no functions for opening and closing auxiliary audio devices. Auxiliary audio devices don't need to be opened and closed like MIDI and waveform devices because there is no continuous data transfer associated with them. All auxiliary audio functions take device identifiers to identify devices.


  73.2.3  Allocating and Preparing Audio Data Blocks

Some low-level audio functions require applications to allocate data blocks to pass to the device drivers for playback or recording purposes. Each of these functions uses a structure (or header) to describe its data block. The following table identifies these functions and their associated header structures. (The MMSYSTEM.H file defines the data structures for these headers.)

Function	Header structure	Purpose
waveOutWrite	WAVEHDR	Waveform playback
waveInAddBuffer	WAVEHDR	Waveform recording
midiOutLongMsg	MIDIHDR	MIDI system-exclusive playback
midiInAddBuffer	MIDIHDR	MIDI system-exclusive recording
Before you use one of the functions listed above to pass a data block to a device driver, you must allocate memory for the data block according to the guidelines discussed in the following sections of this chapter.


  73.2.3.1  Allocating Memory for Audio Data Blocks

Before preparing a data block, you must allocate memory for the data block and the header structure that describes the data block.

To allocate memory, use the GlobalAlloc function with the GMEM_MOVEABLE flag to get a handle of the memory object. Then pass this handle of the GlobalLock function to get a pointer to the memory object.

To free a data block, use GlobalUnlock and GlobalFree.


  73.2.3.2  Preparing Audio Data Blocks

Before you pass an audio data block to a device driver, you must prepare the data block by passing it to a header-preparation function. When the device driver is finished with the data block and returns it, you must clean up this preparation by passing the data block to a header clean-up function before any allocated memory can be freed.

Windows provides the following functions for preparing and cleaning up audio data blocks.

Function	Description
midiInPrepareHeader	Prepares a MIDI-input data block.
midiInUnprepareHeader	Cleans up the preparation on a MIDI-input data block.
midiOutPrepareHeader	Prepares a MIDI-output data block.
midiOutUnprepareHeader	Cleans up the preparation on a MIDI-output data block.
waveInPrepareHeader	Prepares a waveform-input data block.
waveInUnprepareHeader	Cleans up the preparation on a waveform-input data block.
waveOutPrepareHeader	Prepares a waveform-output data block.
waveOutUnprepareHeader	Cleans up the preparation on a waveform-output data block.


  73.2.4  Managing Audio Data Blocks

Unless the audio data is small enough to be contained in a single data block, applications must continually supply the device driver with data blocks until playback or recording is complete. This is true for waveform input and output, and for MIDI system-exclusive input messages. Regular MIDI channel messages don't require data blocks for input or output.

Even if a single data block is used, applications must be able to determine when a device driver is finished with the data block so the application can free the memory associated with the data block and header structure. There are three ways to determine when a device driver is finished with a data block:

•	Specify a window to receive a message sent by the driver when it is finished with a data block.

•	Specify a callback function to receive a message sent by the driver when it is finished with a data block.

•	Poll a bit in the dwFlags member of the WAVEHDR or MIDIHDR data structure sent with each data block.

If an application doesn't get a data block to the device driver when needed, there can be an audible gap in playback or a loss of incoming recorded information. Use a double-buffering scheme to stay at least one data block ahead of the device driver.

Note   To get time-stamped MIDI input data, you must use a callback function.


  73.2.4.1  Using a Window to Process Driver Messages

The easiest type of callback function to use to process driver messages is a window callback. To use a window callback, specify the CALLBACK_WINDOW flag in the dwFlags parameter and a window handle as the dwCallback parameter of the device-opening function. Driver messages will be sent to the window-procedure function for the window identified by the handle in dwCallback.

Messages sent to the window function are specific to the audio device type used. For details on these messages, see the sections later in this chapter on using window messages for each specific audio device type.


  73.2.4.2  Using a Callback Function to Process Driver Messages

You can also write your own low-level callback function to process messages sent by the device driver. To use a low-level callback function, specify the CALLBACK_FUNCTION flag in the dwFlags parameter and the address of the callback in the dwCallback parameter of the device-opening function.

Messages sent to a callback function are similar to messages sent to a window, except that they have two doubleword parameters instead of one unsigned-integer and one doubleword parameter. For details on these messages, see the sections later in this chapter about using low-level callbacks for each specific audio device type.

Callback functions for the low-level audio services are often called from another thread running asynchronously from the application's thread. It is therefore important to use critical sections to protect data shared between the callback routine and the rest of the application. For more information about critical sections, see Chapter 44, »Synchronization«.

To pass instance data from an application to a low-level callback residing in a dynamic-link library (DLL), use one of the following techniques:

•	Pass the instance data using the dwInstance parameter of the function that opens the device driver.

•	Pass the instance data using the dwUser member of the WAVEHDR and MIDIHDR structures that identify an audio data block being sent to a device driver.

If you need more than 32 bits of instance data, pass a pointer to a structure containing the additional information.

The callback function can only call the following Win32 functions:

PostMessage	timeKillEvent,
timeGetSystemTime	midiOutShortMsg,
timeGetTime	midiOutLongMsg,
timeSetEvent	OutputDebugStr.


  73.2.4.3  Managing Data Blocks by Polling

In addition to using a callback function, you can poll the dwFlags member of a WAVEHDR or MIDIHDR structure to determine when an audio device is finished with a data block. There are times when it's better to poll dwFlags rather than wait for a window to receive messages from the drivers. For example, immediately after you call the waveOutReset function to release pending data blocks, you can poll to be sure that the data blocks are indeed done before proceeding to call the waveOutUnprepareHeader function and free the memory for the data block.

MMSYSTEM.H defines two flags for testing the dwFlags member: WHDR_DONE for a WAVEHDR structure, and MHDR_DONE for a MIDIHDR structure.


  73.2.5  Using the MMTIME Structure

Windows uses a structure called MMTIME to represent time. Low-level audio functions that use MMTIME include waveInGetPosition and waveOutGetPosition. The timeGetSystemTime function also uses MMTIME to represent system time.


  73.2.5.1  Setting the Time Format

MMTIME can represent time in one or more different formats including milliseconds, samples, Society of Motion Picture and Television Engineers (SMPTE), and MIDI song-pointer formats. The wType member specifies the format used to represent time. Before calling a function that uses the MMTIME structure, you must set the wType member to indicate your requested time format. Be sure to check wType after the call to see if the requested time format is supported. If the requested time format is not supported, the time is specified in an alternate time format selected by the device driver and the wType member is changed to indicate the selected time format. MMSYSTEM.H defines the following flags for the wType member of the MMTIME structure.

Flag	Description
TIME_MS	Milliseconds
TIME_SAMPLES	Number of waveform audio samples
TIME_BYTES	Number of waveform audio bytes
TIME_SMPTE	SMPTE time
TIME_MIDI	MIDI song-position pointer
For details on using MMTIME with the waveOutGetPosition function, see Section 73.3.6, »Getting the Current Playback Position«.


  73.2.5.2  Getting the System Time

Use the timeGetSystemTime or timeGetTime function to get the system time. System time is defined as the time (in milliseconds) since Windows was started. For more information on timeGetSystemTime and timeGetTime, see Chapter 74, »Multimedia Timers«.


  73.2.6  Handling Errors With Audio Functions

Low-level audio functions return a nonzero error code. The multimedia extensions provide a set of functions that convert these error codes into a textual description of the error. The application must still look at the error value itself to determine how to proceed, but textual descriptions of errors can be used in dialog boxes describing errors to users.

The following functions can be used to get textual descriptions of low-level audio errors.

Function	Description
midiInGetErrorText	Retrieves a textual description of a specified MIDI input error.
midiOutGetErrorText	Retrieves a textual description of a specified MIDI output error.
waveInGetErrorText	Retrieves a textual description of a specified waveform input error.
waveOutGetErrorText	Retrieves a textual description of a specified waveform output error.
The only low-level audio functions that don't return error codes are the device-numbering functions (auxGetNumDevs, midiInGetNumDevs, and so on). These functions return a value of zero if no devices are present in a system, or if any errors are encountered by the function.


  73.3  Playing Waveform Audio

If your application plays waveform audio, you can use the Media Control Interface (MCI) to control waveform output devices. If the MCI waveform playback services don't meet the needs of your application, you can manage waveform playback by using the low-level waveform services.


  73.3.1  Waveform Output Data Types

The MMSYSTEM.H header file defines data types and function prototypes for all of the audio functions. You must include this header file in any source-code module that uses these functions. MMSYSTEM.H defines the following data types for the waveform output functions.

Type	Description
HWAVEOUT	Handle of an open waveform output device.
WAVEOUTCAPS	Structure used to inquire about the capabilities of a particular waveform output device.
WAVEFORMAT	Structure that specifies the data formats supported by a particular waveform output device. This structure is also used for waveform input devices.
WAVEHDR	Structure that is a header for a block of waveform output data. This structure is also used for waveform input devices.


  73.3.2  Querying Waveform Output Devices

Before playing a waveform, call the waveOutGetDevCaps function to determine the waveform output capabilities of the playback device as described earlier in this chapter. This function takes a pointer to a WAVEOUTCAPS structure, which it fills with information about the capabilities of a given device. This information includes the manufacturer and product identifiers, a product name for the device, and the version number of the device driver.

In addition, the WAVEOUTCAPS structure provides information on the standard waveform formats and features supported by the device driver.


  73.3.2.1  Determining Standard Format Support

The dwFormats member of the WAVEOUTCAPS structure specifies the standard waveform formats supported by a device. The MMSYSTEM.H header file defines the following standard waveform format identifiers for the dwFormats member.

Format identifier	Waveform format
WAVE_FORMAT_1M08	8-bit mono at 11.025 kHz
WAVE_FORMAT_1S08	8-bit stereo at 11.025 kHz
WAVE_FORMAT_1M16	16-bit mono at 11.025 kHz
WAVE_FORMAT_1S16	16-bit stereo at 11.025 kHz
WAVE_FORMAT_2M08	8-bit mono at 22.05 kHz
WAVE_FORMAT_2S08	8-bit stereo at 22.05 kHz
WAVE_FORMAT_2M16	16-bit mono at 22.05 kHz
WAVE_FORMAT_2S16	16-bit stereo at 22.05 kHz
WAVE_FORMAT_4M08	8-bit mono at 44.1 kHz
WAVE_FORMAT_4S08	8-bit stereo at 44.1 kHz
WAVE_FORMAT_4M16	16-bit mono at 44.1 kHz
WAVE_FORMAT_4S16	16-bit stereo at 44.1 kHz
The value of the dwFormats member is the result of a logical OR operation on the flags listed above.

This information on standard-format support also applies to the WAVEINCAPS structure used with waveform input devices. For information about the WAVEINCAPS structure, see Section 73.4.2, »Querying Waveform Input Devices«.

To determine whether a specific format is supported by a device, use the waveOutOpen function with the WAVE_FORMAT_QUERY flag as shown in the next section.


  73.3.2.2  Determining Nonstandard Format Support

Waveform devices can support nonstandard formats not listed in the preceding table. To see whether a particular format (standard or nonstandard) is supported by a device, you can call the waveOutOpen function with the WAVE_FORMAT_QUERY flag. The WAVE_FORMAT_QUERY flag tells waveOutOpen to check whether the requested format is supported. The wave device is not actually opened. The requested format is specified by the structure pointed to by the lpFormat parameter passed to waveOutOpen. For information about setting up this structure, see Section 73.3.4, »Specifying Waveform Data Formats«. The following example uses this technique to determine whether a given waveform device supports a given format.

/*

 * Determines whether the given waveform output device supports

 * a given wave-form format. Returns 0 if the format is supported,

 * WAVEERR_BADFORMAT if the format is not supported, and one of

 * the MMSYSERR_ error codes if there are other errors in opening

 * the given waveform device.

 */

UINT IsFormatSupported(LPPCMWAVEFORMAT lpPCMWaveFormat,

    UINT wDeviceID)

{

    return (waveOutOpen(

            NULL,                           // NULL for query

            wDeviceID,                      // device identifier

            (LPWAVEFORMAT)lpPCMWaveFormat,  // requested format

            NULL,                           // no callback

            NULL,                           // no instance data

            WAVE_FORMAT_QUERY));            // query only

}

This technique to determine nonstandard format support also applies to waveform input devices. The only difference is that the waveInOpen function is used in place of waveOutOpen to query for format support.

Note   To determine whether a particular waveform-data format is supported by any of the waveform devices in a system, use the technique illustrated in the previous example, but specify the WAVE_MAPPER constant for the wDeviceID parameter. For more information about using the WAVE_MAPPER constant, see Section 73.3.3.1, »Selecting a Waveform Output Device«.


  73.3.2.3  Determining Capabilities of Waveform Output Devices

Waveform output devices vary in the capabilities they support. The dwSupport member of the WAVEOUTCAPS structure indicates whether a given device supports capabilities such as volume and pitch changes. MMSYSTEM.H defines the following flags for the dwSupport member.

Flag	Description
WAVECAPS_PITCH	Pitch-change support
WAVECAPS_PLAYBACKRATE	Playback-rate-change support
WAVECAPS_VOLUME	Volume-control support
WAVECAPS_LRVOLUME	Individual volume-control support for both left and right channels
The dwSupport member is a logical OR of the flags listed in the preceding table.

For more information about playback volume levels, see Section 73.3.9, »Changing Waveform Playback Volume«. For more information about pitch and playback rates, see Section 73.3.10, »Changing Pitch and Playback Rate«.


  73.3.3  Opening Waveform Output Devices

Use the waveOutOpen function to open a waveform output device for playback. This function opens the device associated with the specified device identifier and returns a handle of the open device by writing the handle of a specified memory location.


  73.3.3.1  Selecting a Waveform Output Device

Some multimedia computers have multiple waveform output devices. Unless you know you want to open a specific waveform output device in a system, you should use the WAVE_MAPPER constant for the device identifier when you open a device. The waveOutOpen function chooses the device in the system best capable of playing the given data format.


  73.3.4  Specifying Waveform Data Formats

When you call the waveOutOpen function to open a device driver for playback or determine whether the driver supports a particular data format, use the lpFormat parameter to specify a pointer to a structure containing the requested waveform data format.

The WAVEFORMAT structure specifies format information common to all types of waveform data formats. Currently the only format supported is pulse code modulated (PCM), but in the future other types such as adaptive differential pulse code modualtion (ADPCM) may be supported.

In addition to the general information in the WAVEFORMAT structure, specific information is needed to describe a PCM waveform data format completely. For PCM waveform data, the PCMWAVEFORMAT structure includes a WAVEFORMAT structure along with an additional member containing PCM-specific information.


  73.3.4.1  Using the PCMWAVEFORMAT Structure

For PCM audio data, use the PCMWAVEFORMAT structure to specify the data format. The following example shows how to set up a PCMWAVEFORMAT structure for 11.025 kilohertz (kHz) 8-bit mono and for 44.1 kHz 16-bit stereo. After setting up PCMWAVEFORMAT, the example calls the IsFormatSupported function to verify that the PCM waveform output device supports the format. The source code for IsFormatSupported is given in an example in Section 73.3.2.2, »Determining Nonstandard Format Support«.

UINT wReturn;

PCMWAVEFORMAT pcmWaveFormat;

/* Set up PCMWAVEFORMAT for 11 kHz 8-bit mono. */

pcmWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;

pcmWaveFormat.wf.nChannels = 1;

pcmWaveFormat.wf.nSamplesPerSec = 11025L;

pcmWaveFormat.wf.nAvgBytesPerSec = 11025L;

pcmWaveFormat.wf.nBlockAlign = 1;

pcmWaveFormat.wBitsPerSample = 8;

/* See if format is supported by any device in system. */

wReturn = IsFormatSupported(&pcmWaveFormat, WAVE_MAPPER);

/* Report results. */

if (wReturn == 0)

     MessageBox(hMainWnd, "11 kHz 8-bit mono is supported.",

       "", MB_ICONINFORMATION);

else if (wReturn == WAVERR_BADFORMAT)

     MessageBox(hMainWnd, "11 kHz 8-bit mono NOT supported.",

       "", MB_ICONINFORMATION);

else

     MessageBox(hMainWnd, "Error opening waveform device.",

       "Error", MB_ICONEXCLAMATION);

/* Set up PCMWAVEFORMAT for 44.1 kHz 16-bit stereo. */

pcmWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;

pcmWaveFormat.wf.nChannels = 2;

pcmWaveFormat.wf.nSamplesPerSec = 44100L;

pcmWaveFormat.wf.nAvgBytesPerSec = 176400L;

pcmWaveFormat.wf.nBlockAlign = 4;

pcmWaveFormat.wBitsPerSample = 32;

/* See if format is supported by any device in the system. */

wReturn = IsFormatSupported(&pcmWaveFormat, WAVE_MAPPER);

/* Report results. */

if (wReturn == 0)

    MessageBox(hMainWnd, "44.1 kHz 16-bit stereo is supported.",

      "", MB_ICONINFORMATION);

else if (wReturn == WAVERR_BADFORMAT)

    MessageBox(hMainWnd, "44.1 kHz 16-bit stereo NOT supported.",

      "", MB_ICONINFORMATION);

else

    MessageBox(hMainWnd, "Error opening waveform device.",

      "Error", MB_ICONEXCLAMATION);


  73.3.4.2  Getting Format Information From a WAVE File

The easiest way to get waveform-format information from a WAVE file is by using the multimedia file input and output (I/O) services. To do this, use the mmioDescend function to locate the "fmt" chunk containing the format information and the mmioRead function to read the format chunk directly into the proper format structure. (Chunks are the basic building blocks of RIFF files.) The following example illustrates this technique. For more information about multimedia file I/O, see Chapter 75, »Multimedia File Input and Output«.

void GetFormatInfo(void)

{

    HMMIO       hmmio;

    MMCKINFO    mmckinfoParent;

    MMCKINFO    mmckinfoSubchunk;

    DWORD       dwFmtSize;

    HANDLE      hFormat;

    WAVEFORMAT  *pFormat;

        .

        .

        .

    /* Open the given file for reading using buffered I/O. */

        ...

    /*

     * Locate a "RIFF" chunk with a "WAVE" form type

     * to make sure it's a WAVE file.

     */

        ...

    /*

     * Now, find the format chunk (form type "fmt "). It should be

     * a subchunk of the "RIFF" parent chunk.

     */

    mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');

    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,

            MMIO_FINDCHUNK)) {

        MessageBox(hwndApp, "WAVE file is corrupted.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        mmioClose(hmmio, 0);

        return;

    }

    /*

     * Get the size of the format chunk;

     * allocate and lock memory for it.

     */

    dwFmtSize = mmckinfoSubchunk.cksize;

    hFormat = LocalAlloc(LMEM_MOVEABLE, dwFmtSize);

    if (hFormat == NULL) {

        MessageBox(hwndApp, "Out of memory.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        mmioClose(hmmio, 0);

        return;

    }

    pFormat = (WAVEFORMAT *) LocalLock(hFormat);

    if (pFormat == NULL) {

        MessageBox(hwndApp, "Failed to lock memory for format chunk.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        LocalFree(hFormat);

        mmioClose(hmmio, 0);

        return;

    }

    /* Read the format chunk. */

    if (mmioRead(hmmio, (LPSTR)pFormat,

                dwFmtSize) != (LRESULT)dwFmtSize) {

        MessageBox(hwndApp, "Failed to read format chunk.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        LocalUnlock(hFormat);

        LocalFree(hFormat);

        mmioClose(hmmio, 0);

        return;

    }

    /* Make sure it's a PCM file. */

    if (pFormat->wFormatTag != WAVE_FORMAT_PCM) {

        LocalUnlock(hFormat);

        LocalFree(hFormat);

        mmioClose(hmmio, 0);

        MessageBox(hwndApp, "The file is not a PCM file.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        return;

    }

    /*

     * Make sure the system has a waveform output

     * device capable of playing this format.

     */

    if (waveOutOpen(&hWaveOut, WAVE_MAPPER, (LPWAVEFORMAT)pFormat,

                NULL, 0L, WAVE_FORMAT_QUERY)) {

        LocalUnlock(hFormat);

        LocalFree(hFormat);

        mmioClose(hmmio, 0);

        MessageBox(hwndApp,

            "The waveform device can't play this format.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        return;

    }

    .

    .

    .

}


  73.3.5  Writing Waveform Data

After successfully opening a waveform output device driver, you can begin waveform playback.

The waveOutWrite function writes a data block to a waveform output device. Use the WAVEHDR structure to specify the waveform data block you are sending. This structure contains a pointer to a locked data block, the length of the data block, and assorted flags.

After you send a data block to an output device by using waveOutWrite, you must wait until the device driver is finished with the data block before freeing it. If you are sending multiple data blocks, you must monitor the system for the completion of each data block so that you know when to send additional blocks. For details about different techniques for monitoring data block completion, see Section 73.2.4, »Managing Audio Data Blocks«.


  73.3.5.1  Example of Writing Waveform Data

The following example illustrates the steps required to allocate and set up a WAVEHDR data structure and write a block of data to a waveform output device.

/*

 * Global variables. Must be visible to window-procedure function

 *  so it can unlock and free the data block after it has been played.

 */

HANDLE hData  = NULL; // handle of waveform data memory

HPSTR  lpData = NULL; // pointer to waveform data memory

void WriteWaveData(void)

{

    HWAVEOUT    hWaveOut;

    HGLOBAL     hWaveHdr;

    LPWAVEHDR   lpWaveHdr;

    HMMIO       hmmio;

    UINT        wResult;

    HANDLE      hFormat;

    WAVEFORMAT  *pFormat;

    DWORD       dwDataSize;

        .

        .

        .

    /* Open a waveform device for output using window callback. */

    if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,

                    (LPWAVEFORMAT)pFormat,

                    (LONG)hwndApp, 0L, CALLBACK_WINDOW)) {

        MessageBox(hwndApp,

                   "Failed to open waveform output device.",

                   NULL, MB_OK | MB_ICONEXCLAMATION);

        LocalUnlock(hFormat);

        LocalFree(hFormat);

        mmioClose(hmmio, 0);

        return;

    }

    /*

     * Allocate and lock memory for the waveform data. The memory

     * for waveform data must be globally allocated with

     * GMEM_MOVEABLE and GMEM_SHARE flags.

     */

    hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, dwDataSize );

    if (!hData)

    {

        MessageBox(hwndApp, "Out of memory.",

                   NULL, MB_OK | MB_ICONEXCLAMATION);

        mmioClose(hmmio, 0);

        return;

    }

    if ((lpData = GlobalLock(hData)) == NULL) {

        MessageBox(hwndApp, "Failed to lock memory for data chunk.",

                   NULL, MB_OK | MB_ICONEXCLAMATION);

        GlobalFree(hData);

        mmioClose(hmmio, 0);

        return;

    }

    /* Read the waveform data subchunk. */

    if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LRESULT)dwDataSize) {

        MessageBox(hwndApp, "Failed to read data chunk.",

                   NULL, MB_OK | MB_ICONEXCLAMATION);

        GlobalUnlock(hData);

        GlobalFree(hData);

        mmioClose(hmmio, 0);

        return;

    }

    /*

     * Allocate and lock memory for the header. This memory must

     * also be globally allocated with GMEM_MOVEABLE and

     * GMEM_SHARE flags.

     */

    hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,

        (DWORD) sizeof(WAVEHDR));

    if (hWaveHdr == NULL) {

        GlobalUnlock(hData);

        GlobalFree(hData);

        MessageBox(hwndApp, "Not enough memory for header.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        return;

    }

    lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);

    if (lpWaveHdr == NULL) {

        GlobalUnlock(hData);

        GlobalFree(hData);

        MessageBox(hwndApp,

            "Failed to lock memory for header.",

            NULL, MB_OK | MB_ICONEXCLAMATION);

        return;

    }

    /* After allocation, set up and prepare header. */

    lpWaveHdr->lpData = lpData;

    lpWaveHdr->dwBufferLength = dwDataSize;

    lpWaveHdr->dwFlags = 0L;

    lpWaveHdr->dwLoops = 0L;

    waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));

    /*

     * Now the data block can be sent to the output device. The

     * waveOutWrite function returns immediately and waveform

     * data is sent to the output device in the background.

     */

    wResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));

    if (wResult != 0) {

        waveOutUnprepareHeader(hWaveOut, lpWaveHdr,

                               sizeof(WAVEHDR));

        GlobalUnlock( hData);

        GlobalFree(hData);

        MessageBox(hwndApp, "Failed to write block to device",

                   NULL, MB_OK | MB_ICONEXCLAMATION);

        return;

    }

    .

    .

    .

}


  73.3.5.2  PCM Waveform Data Format

The lpData member in the WAVEHDR structure points to the waveform data samples. For 8-bit PCM data, each sample is represented by a single unsigned data byte. For 16-bit PCM data, each sample is represented by a 16-bit signed value. The following table summarizes the maximum, minimum, and midpoint values for PCM waveform data.

Data format	Maximum value	Minimum value	Midpoint value
8-bit PCM	255 (0xFF)	0	128 (0x80)
16-bit PCM	32767 (0x7FFF)	-32768 (0x8000)	0
The order of the data bytes varies between 8-bit and 16-bit, and between mono and stereo formats. The following tables show data packing for the first four words of different PCM waveform data formats.

Data packing for 8-bit mono PCM:

Sample 1	Sample 2	Sample 3	Sample 4
Channel 0	Channel 0	Channel 0	Channel 0
Data packing for 8-bit stereo PCM:

Sample 1		Sample 2
Channel 0 (left)	Channel 1 (right)	Channel 0 (left)	"Channel 1 (right)"
Low-order byte	High-order byte	Low-order byte	High-order byte
Data packing for 16-bit mono PCM:

Sample 1		Sample 2
Channel 0 low byte	Channel 0 high byte	Channel 0 low byte	Channel 0 high byte
Data packing for 16-bit stereo PCM:

Sample 1
Channel 0 (left) byte	Channel 0 (left) byte	Channel 1 (right) byte	Channel 1 (right) byte


  73.3.5.3  Waveform Looping

Waveform looping is controlled by the dwLoops and dwFlags members in the WAVEHDR structures passed to the device with waveOutWrite. Use the WHDR_BEGINLOOP and WHDR_ENDLOOP flags in the dwFlags member to specify the beginning and ending data blocks for looping.

To loop on a single block, specify both flags for the same block. To specify the number of loops, use the dwLoops member in the WAVEHDR structure for the first block in the loop.

You can stop waveform looping with the waveOutBreakLoop function. The blocks making up the loop are played to the end before the loop is stopped.


  73.3.5.4  Using Window Messages to Manage Waveform Playback

The following messages can be sent to a window-procedure function for managing waveform playback.

Message	Description
MM_WOM_CLOSE	Sent when the device is closed using waveOutClose.
MM_WOM_DONE	Sent when the device driver is finished with a data block sent using waveOutWrite.
MM_WOM_OPEN	Sent when the device is opened using waveOutOpen.
A wParam and lParam parameter is associated with each of these messages. The wParam parameter always specifies a handle of the open waveform device. For the MM_WOM_DONE message, lParam specifies a pointer to a WAVEHDR structure identifying the completed data block. The lParam parameter is unused for the MM_WOM_CLOSE and MM_WOM_OPEN messages.

The most useful message is MM_WOM_DONE. When this message signals that playback of a data block is complete, you can clean up and free the data block. Unless you need to allocate memory or initialize variables, you probably don't need to process the MM_WOM_OPEN and MM_WOM_CLOSE messages.

The following example shows how to process the MM_WOM_DONE message. The example assumes the application does not play multiple data blocks, so it can close the output device after playing a single data block.

/* WndProc--Main window-procedure function. */

LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

    switch (msg) {

        .

        .

        .

        case MM_WOM_DONE:

        /* A data block has been played and can now be freed. */

            waveOutUnprepareHeader((HWAVEOUT) wParam,

                (LPWAVEHDR) lParam, sizeof(WAVEHDR) );

            GlobalUnlock(hData);

            GlobalFree(hData);

            waveOutClose((HWAVEOUT) wParam);

            break;

    }

    return DefWindowProc(hWnd,msg,wParam,lParam);

}


  73.3.5.5  Using a Low-Level Callback Function to Manage Waveform Playback

The syntax of the low-level callback function for waveform output devices is as follows:

void CALLBACK waveOutCallback(hWaveOut, wMsg,
     dwInstance, dwParam1, dwParam2)

The following messages can be sent in the wMsg parameter of waveform output callback functions.

Message	Description
WOM_CLOSE	Sent when the device is closed using the waveOutClose function.
WOM_DONE	Sent when the device driver is finished with a data block sent using the waveOutWrite function.
WOM_OPEN	Sent when the device is opened using the waveOutOpen function.
These messages are similar to the messages sent to window-procedure functions, the parameters are different. A handle of the open waveform device is passed as a parameter to the callback function, along with the doubleword of instance data that was passed using waveOutOpen.

The callback function has two message-dependent parameters: dwParam1 and dwParam2. For the WOM_DONE message, dwParam1 specifies a pointer to a WAVEHDR structure identifying the completed data block and dwParam2 is not used. For the WOM_OPEN and WOM_CLOSE messages, neither of the parameters is used.

After the driver is finished with a data block, you can clean up and free the data block, as described in Section 73.2.3, »Allocating and Preparing Audio Data Blocks«. Because of the restrictions of low-level audio callbacks, you can't do this within the callback. See Section 73.2.4.2, »Using a Callback Function to Process Driver Messages«, for details about the restrictions on using callback functions.


  73.3.6  Getting the Current Playback Position

While a waveform is playing, you can monitor the current playback position within the waveform. The Win32 API provides the waveOutGetPosition function for this purpose.

This function takes three parameters: a handle of a waveform output device, a pointer to an MMTIME structure, and an unsigned integer specifying the size of the MMTIME structure.

For waveform devices, the preferred time format in which to represent the current position is samples. Thus the current position of a waveform device is specified as the number of samples for one channel from the beginning of the waveform.

To query the current position of a waveform device, set the wType member of the MMTIME structure to TIME_SAMPLES and pass the structure to waveOutGetPosition.


  73.3.7  Stopping, Pausing, and Restarting Playback

You can stop or pause playback while a waveform is playing. Once playback has been paused, you can restart it. The Win32 API provides the following functions for controlling waveform playback.

Function	Description
waveOutPause	Pauses playback on a waveform output device.
waveOutReset	Stops playback on a waveform output device and marks all pending data blocks as done.
waveOutRestart	Resumes playback on a paused waveform output device.
Use the waveOutPause function to pause a waveform device that is currently playing. To resume playback on a paused device, use the waveOutRestart function. These functions take a single parameter: the waveform output device handle returned by the waveOutOpen function. Pausing a waveform device may not be instantaneous — the driver can finish playing the current block before pausing playback.

Typically, as soon as the first waveform data block is sent by using the waveOutWrite function, the waveform device begins playing. If you don't want the waveform to start playing immediately, call waveOutPause before calling waveOutWrite. When you want to begin playing the waveform, call waveOutRestart.

To stop a waveform from playing, use the waveOutReset function. This function differs from waveOutPause in that it also marks all pending data blocks as being done. You can not use waveOutRestart to restart a device that has been stopped by using waveOutReset. You must use waveOutWrite to send the first data block to resume playback on the device.


  73.3.8  Closing Waveform Output Devices

After waveform playback is complete, call the waveOutClose function to close the waveform device. If waveOutClose is called while a waveform is playing, the close operation fails and the function returns an error code indicating that the device was not closed. If you don't want to wait for playback to end before closing the device, call the waveOutReset function before closing. This stops playback and allows the device to be closed. Be sure to clean up the preparation on all data blocks before closing the waveform output device.


  73.3.9  Changing Waveform Playback Volume

Windows provides the following functions to query and set the volume level of waveform output devices.

Function	Description
waveOutGetVolume	Gets the volume level of the specified waveform device.
waveOutSetVolume	Sets the volume level of the specified waveform device.
Not all waveform devices support volume changes. Some devices support individual volume control on both the left and right channels. See Section 73.3.2.3, »Determining Capabilities of Waveform Output Devices« for information about how to determine the volume-control capabilities of waveform devices.

Note   Unless your application is designed to be a master volume-control application providing the user with volume control for all audio devices in a system, be sure that your application opens an audio device before changing its volume. Also, be sure your application queries the volume level before changing it and restores the volume level to its previous level as soon as possible.

Volume is specified in a doubleword value of which the high-order 16 bits specify the relative volume of the right channel, and the low-order 16 bits specify the relative volume of the left (or mono) channel.

For devices that don't support left- and right-channel volume control, the low-order 16 bits specify the volume level, and the high-order 16 bits are ignored. Volume-level values range from 0x0 (silence) to 0xFFFF (maximum volume) and are interpreted logarithmically. The perceived volume increase is the same when increasing the volume level from 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

The waveOutGetVolume function returns the volume as a doubleword value at an address specified by a pointer parameter.


  73.3.10  Changing Pitch and Playback Rate

Some waveform output devices can vary the pitch and the playback rate of waveform data. Not all waveform devices support pitch and playback-rate changes. See Section 73.3.2.3, »Determining Capabilities of Waveform Output Devices« for information about how to determine if a particular waveform device supports pitch and playback-rate changes.

Following are the differences between changing pitch and playback rate:

•	Changing the playback rate is performed by the device driver and does not require specialized hardware. The sample rate is not changed, but the driver interpolates by skipping or synthesizing samples. For example, if the playback rate is changed by a factor of two, the driver skips every other sample.

•	Changing the pitch requires specialized hardware. The playback rate and sample rate are not changed.

Windows provides the following functions to query and set waveform pitch and playback rates.

Function	Description
waveOutGetPitch	Gets the pitch for the specified waveform output device.
waveOutGetPlaybackRate	Gets the playback rate for the specified waveform output device.
waveOutSetPitch	Sets the pitch for the specified waveform output device.
waveOutSetPlaybackRate	Sets the playback rate for the specified waveform output device.
The pitch and playback rates are changed by a factor specified with a fixed-point number packed into a doubleword value. The high-order 16 bits specify the integer part, and the low-order 16 bits specify the fractional part of the number. For example, the value 1.5 is represented as 0x00018000L. The value 0.75 is represented as 0x0000C000L. A value of 1.0 (0x00010000) means the pitch or playback rate is unchanged.


  73.4  Recording Waveform Audio

If the MCI waveform-recording services don't meet the needs of your application, you can handle waveform recording using the low-level waveform services.


  73.4.1  Waveform Input Data Types

The MMSYSTEM.H header file defines data types and function prototypes for all of the audio functions. You must include this header file in any source-code module that uses these functions. MMSYSTEM.H defines the following data types for waveform-input functions.

Type	Description
HWAVEIN	Handle of an open waveform input device.
WAVEINCAPS	Data structure used to inquire about the capabilities of a particular waveform input device.
WAVEFORMAT	Structure that specifies the data formats supported by a particular waveform input device. This structure is also used for waveform output devices.
WAVEHDR	Structure that is a header for a block of waveform input data. This structure is also used for waveform output devices.


  73.4.2  Querying Waveform Input Devices

Before recording a waveform, you should call the waveInGetDevCaps function to determine the waveform input capabilities of the system. This function takes a pointer to a WAVEINCAPS structure that it fills with information about the capabilities of a given device. This information includes the manufacturer and product identifiers, a product name for the device, and the version number of the device driver. In addition, the WAVEINCAPS structure provides information about the standard waveform formats that the device supports.


  73.4.3  Opening Waveform Input Devices

Use the waveInOpen function to open a waveform input device for recording. This function opens the device associated with the specified device identifier and returns a handle of the open device by writing the handle of a specified memory location.


  73.4.3.1  Selecting a Waveform Input Device

Some multimedia computers will have multiple waveform input devices. Unless you know you want to open a specific waveform input device in a system, you should use the WAVE_MAPPER constant for the device identifier when you open a device. The waveOutOpen function will choose the device in the system best able to record in the given data format.


  73.4.4  Managing Waveform Recording

Once you open a waveform input device, you can begin recording waveform data. Waveform data is recorded into application-supplied buffers specified by a WAVEHDR structure. This is the same structure used for waveform playback described in Section 73.3.5, »Writing Waveform Data«. Memory for the WAVEHDR structure and its accompanying data buffer must be allocated and prepared, as shown in Section 73.2.3, »Allocating and Preparing Audio Data Blocks«.

Windows provides the following functions to manage waveform recording:

Function	Description
waveInAddBuffer	Sends a buffer to the device driver so it can be filled with recorded waveform data.
waveInReset	Stops waveform recording and marks all pending buffers as done.
waveInStart	Starts waveform recording.
waveInStop	Stops waveform recording.
Use the waveInAddBuffer function to send data buffers to the device driver. As the buffers are filled with recorded waveform data, the application is notified with either a window message or with a callback message, depending on the flag specified when the device was opened.

Use the waveInStart function to begin recording. Before beginning to record, send at least one buffer to the driver or incoming data may be lost. To stop waveform recording, use the waveInStop function.

Before closing the device by using the waveOutClose function, call the waveOutReset function to mark any pending data blocks as being done.


  73.4.4.1  Using Window Messages to Manage Waveform Recording

The following messages can be sent to a window-procedure function for managing waveform recording.

Message	Description
MM_WIM_CLOSE	Sent when the device is closed using the waveInClose function.
MM_WIM_DATA	Sent when the device driver is finished with a data buffer sent using the waveInAddBuffer function.
MM_WIM_OPEN	Sent when the device is opened using the waveInOpen function.
There is a wParam and lParam parameter associated with each of these messages. The wParam parameter always specifies a handle of the open waveform device. The lParam parameter is unused for the MM_WIM_CLOSE and MM_WIM_OPEN messages.

For the MM_WIM_DATA message, lParam specifies a pointer to a WAVEHDR structure that identifies the data buffer. This data buffer may not be completely filled with waveform data, because recording can stop before the buffer is filled. Use the dwBytesRecorded member of the WAVEHDR structure to determine the amount of valid data present in the buffer.

The most useful message is MM_WIM_DATA. Unless you need to allocate memory or initialize variables, you probably don't need to use the MM_WIM_OPEN and MM_WIM_CLOSE messages. When the device driver is finished with a data block, you can clean up and free the data block as described in Section 73.2.3, »Allocating and Preparing Audio Data Blocks«.


  73.4.4.2  Using a Low-Level Callback Function to Manage Waveform Recording

The syntax of the low-level callback function for waveform input devices is as follows.

void CALLBACK waveInCallback(hWaveIn, wMsg,
    dwInstance, dwParam1, dwParam2)

The following messages can be sent in the wMsg parameter of waveform input callback functions.

Message	Description
WIM_CLOSE	Sent when the device is closed using the waveInClose function.
WIM_DONE	Sent when the device driver is finished with a data block sent using the waveInAddBuffer function.
WIM_OPEN	Sent when the device is opened using the waveInOpen function.
These messages resemble messages sent to window-procedure functions, but their parameters are different. A handle of an open waveform device is passed as a parameter to the callback function, along with the doubleword value of instance data that was passed using waveInOpen.

The callback function has two message-dependent parameters: dwParam1 and dwParam2. For the WIM_CLOSE and WIM_OPEN messages, these parameters are not used. For the WIM_DONE message, dwParam1 specifies a pointer to a WAVEHDR structure identifying the completed data block and dwParam2 is not used.

After the driver is finished with a data block, you can clean up and free the data block. Because of the restrictions of low-level audio callback functions, you can't do this within the callback function. You must set semaphores and do this outside of the callback function. See Section 73.2.4.2, »Using a Callback Function to Process Driver Messages« for detailsabout the restrictions on using callback functions.


  73.5  Playing MIDI Audio

To play MIDI files, use the MCI sequencer. If the MCI sequencer services don't meet the needs of your application, you can manage MIDI playback using the low-level MIDI services.


  73.5.1  MIDI Output Data Types

The MMSYSTEM.H header file defines data types and function prototypes for all low-level audio functions. You must include this header file in any source module that uses these functions. MMSYSTEM.H defines the following data types for low-level MIDI output function:

Type	Description
HMIDIOUT	Handle of a MIDI output device.
MIDIHDR	Structure is a header for a block of MIDI system-exclusive data. This structure is used for input as well as output.
MIDIOUTCAPS	Structure used to inquire about the capabilities of a particular MIDI output device.


  73.5.2  Querying MIDI Output Devices

Before playing MIDI audio, you should call the midiOutGetDevCaps function to determine the capabilities of the MIDI output hardware present in the system. This function takes a pointer to a MIDIOUTCAPS structure that it fills with information about the capabilities of a given device. This information includes the manufacturer and product identifiers, a product name for the device, and the version number of the device driver. In addition, the MIDIOUTCAPS structure provides information on the device technology, the number of voices and notes supported, the MIDI channels that the device responds to, and features supported by the driver.


  73.5.2.1  Determining the Technology of the Device

MIDI output devices can be either internal synthesizers or external MIDI output ports. The wTechnology member specifies the technology of the device. MMSYSTEM.H defines the following flags to identify device technology.

Flag	Description
MOD_MIDIPORT	The device is an external MIDI output port.
MOD_SQSYNTH	Device is an internal square-wave synthesizer.
MOD_FMSYNTH	Device is an internal FM synthesizer.
MOD_SYNTH	Device is an internal synthesizer (generic).
MOD_MAPPER	Device is the MIDI Mapper.


  73.5.2.2  Determining Capabilities of Internal Synthesizers

If the device is an internal synthesizer, additional device information is available in the wVoices, wNotes, and wChannelMask members of the MIDIOUTCAPS structure. If the device is an external output port, these members are unused.

The wVoices member specifies the number of voices the device supports. Each voice can have a different sound or timbre. Voices are differentiated by MIDI channel. For example, a four-voice synthesizer uses four MIDI channels. The wNotes member specifies the polyphony of the device — the maximum number of notes that can be played simultaneously. The wChannelMask member is a bit representation of the MIDI channels that the device responds to. For example, if the device responds to the first eight MIDI channels, wChannelMask is 0x00FF.

The dwSupport member of the MIDIOUTCAPS structure indicates whether the device driver supports volume changes and patch caching. MMSYSTEM.H defines the following flags for the dwSupport member.

Flag	Description
MIDICAPS_VOLUME	Indicates the driver supports volume control.
MIDICAPS_LRVOLUME	Indicates the driver supports individual volume control for the left and right channels.
MIDICAPS_CACHE	Indicates the driver supports patch caching.
Volume changes are only supported by internal synthesizer devices. External MIDI output ports don't support volume changes. For information about changing volume, see Section 73.5.8, »Changing Internal MIDI Synthesizer Volume«.


  73.5.3  Opening MIDI Output Devices

Use the midiOutOpen function to open a MIDI output device for playback. This function opens the device associated with the specified device identifier and returns a handle of the open device by writing the handle of a specified memory location.


  73.5.4  Sending MIDI Messages

Once you open a MIDI output device, you can begin sending it MIDI messages by using the following functions.

Function	Description
midiOutLongMsg	Sends a buffer of MIDI data to the specified MIDI output device. Use this function to send multiple MIDI events, including system-exclusive messages, to a MIDI device.
midiOutShortMsg	Sends a MIDI message to a specified MIDI output device. This function can use running status by omitting the status byte.
midiOutReset	Turns off all notes on all channels for a specified MIDI output device. Any pending system-exclusive buffers are marked as done and returned to the application.
Use midiOutShortMsg to send any MIDI message (except for system-exclusive messages). This function takes an HMIDIOUT parameter specifying the MIDI output device to which to send the message, and a doubleword value for the MIDI message. The message is packed into the doubleword value as follows.

Word	Byte	Contents
High-order word	High-order byte	Not used
	Low-order byte	MIDI data 2 (optional)
Low-order word	High-order Byte	MIDI data 1 (optional)
	Low-order byte	MIDI status
The two MIDI data bytes are optional, depending on the MIDI status byte. The following example uses midiOutShortMsg to send a given MIDI event to a given MIDI output device.

/* Sends a given MIDI event to the given output device */

UINT sendMIDIEvent(hMidiOut, bStatus, bData1, bData2)

HMIDIOUT hMidiOut;      // handle of the output device

BYTE bStatus;           // MIDI status byte

BYTE bData1;            // first MIDI data byte

BYTE bData2;            // second MIDI data byte

{

    union {

        DWORD dwData;

        BYTE bData[4];

    } u;

    /* Construct the MIDI message */

    u.bData[0] = bStatus;

    u.bData[1] = bData1;

    u.bData[2] = bData2;

    u.bData[3] = 0;

    /* Send the message */

    return midiOutShortMsg(hMidiOut, u.dwData);

}

Note   MIDI output drivers are not required to verify data before sending it to an output port. It is up to applications to ensure that only valid data is sent using the midiOutShortMsg function.


  73.5.5  Sending Buffered Messages

MIDI system-exclusive messages are the only MIDI messages that will not fit into a single doubleword value. System exclusive messages can be any length. Windows provides the midiOutLongMsg function for sending one or more messages, including system-exclusive messages, to MIDI output devices.

Use the MIDIHDR structure to specify MIDI system-exclusive data blocks. This structure contains a pointer to a locked data block, the data-block length, and assorted flags.

Memory for the MIDIHDR structure and the data block pointed to by lpData must be allocated and prepared, as shown in Section 73.2.3, »Allocating and Preparing Audio Data Blocks«.

After you send a system-exclusive data block using midiOutLongMsg, you must wait until the device driver is finished with the data block before freeing it. If you are sending multiple data blocks, you must monitor the completion of each data block so you know when to send additional blocks. (If your application uses a callback function or callback window, it will receive the MOM_DONE message when the driver finishes with the data block.) For information on different techniques for monitoring data-block completion, see Section 73.2.4, »Managing Audio Data Blocks«.

Note   Any MIDI status byte other than a system-real-time message will terminate a system-exclusive message. If you are using multiple data blocks to send a single system-exclusive message, do not send any MIDI messages other than system-real-time messages between data blocks.


  73.5.5.1  Using Window Messages to Manage Buffered Playback

The following messages can be sent to a window-procedure function for managing MIDI system-exclusive playback.

Message	Description
MM_MOM_CLOSE	Sent when the device is closed using the midiOutClose function.
MM_MOM_DONE	Sent when the device driver is finished with a data block sent using the midiOutLongMsg function.
MM_MOM_OPEN	Sent when the device is opened using the midiOutOpen function.
A wParam and lParam parameter is associated with each of these messages. The wParam parameter always specifies a handle of the open MIDI device. For the MM_MOM_DONE message, lParam specifies a pointer to a MIDIHDR structure identifying the completed data block. The lParam parameter is unused for the MM_MOM_CLOSE and MM_MOM_OPEN messages.

The most useful message is the MM_MOM_DONE message. Unless you need to allocate memory or initialize variables, you probably don't need to process the MM_MOM_OPEN and MM_MOM_CLOSE messages. When playback of a data block is completed, you can clean up and free the data block as described in Section 73.2.3, »Allocating and Preparing Audio Data Blocks«.


  73.5.5.2  Using a Callback to Manage Buffered Playback

This syntax of the low-level callback function for MIDI output devices is as follows.

void CALLBACK midiOutCallback(hMidiOut, wMsg,
    dwInstance, dwParam1, dwParam2)

The following messages can be sent to the wMsg parameter of MIDI output callback functions.

Message	Description
MOM_CLOSE	Sent when the device is closed using the midiOutClose function.
MOM_DONE	Sent when the device driver is finished with a data block sent using the midiOutLongMsg function.
MOM_OPEN	Sent when the device is opened using the midiOutOpen function.
These messages are similar to those sent to window-procedure functions, but the parameters are different. A handle of the open MIDI device is passed as a parameter to the callback function along with the doubleword value of instance data passed using midiOutOpen.

The callback function has two message-dependent parameters: dwParam1 and dwParam2. For the MOM_OPEN and MOM_CLOSE messages, these parameters are not used. For the MOM_DONE message, dwParam1 specifies a pointer to a MIDIHDR structure identifying the completed data block and dwParam2 is not used.

After the driver is finished with a data block, you can clean up and free the data block. Because of the restrictions of low-level audio callbacks, you can't do this within the callback function. See Section 73.2.4.2, »Using a Callback Function to Process Driver Messages« for details about the restrictions when using callback functions.


  73.5.6  Sending MIDI Messages Using Running-Status

The MIDI 1.0 Specification allows the use of running-status when a message has the same status byte as the previous message. When running status is used, the status byte of subsequent messages can be omitted. You can send MIDI messages using running status by using the midiOutShortMsg function by packing the message into a doubleword value as follows.

Word	Byte	Contents
High-order word	High-order byte	Not used
	Low-order byte	Not used
Low-order word	High-order Byte	MIDI data 2 (optional)
	Low-order byte	MIDI data 1


  73.5.7  Resetting MIDI Output

The midiOutReset function will turn off all notes, and mark any pending system-exclusive buffers as done and return them to the application. It may be useful in an application that uses MIDI output to provide the user with the ability to reset MIDI output.

Note   Terminating a system-exclusive message without sending an EOX (end-of-exclusive) byte may cause problems for the receiving device. The midiOutReset function does not send an EOX byte when it terminates a system-exclusive message; applications are responsible for doing this.


  73.5.8  Changing Internal MIDI Synthesizer Volume

Windows provides the following functions to query and set the volume level of internal MIDI synthesizer devices.

Function	Description
midiOutGetVolume	Gets the volume level of the specified internal MIDI synthesizer device.
midiOutSetVolume	Sets the volume level of the specified internal MIDI synthesizer device.
Not all MIDI output devices support volume changes. Some devices can support individual volume changes on both the left and the right channels. See Section 73.3.2.3, »Determining Capabilities of Waveform Output Devices« for information about how to determine whether a particular device supports volume changes.

Note   Unless your application is designed to be a master volume-control application providing the user with volume control for all audio devices in a system, be sure your application opens an audio device before changing its volume. Also be sure your application queries the volume level before changing it and restore the volume level to its previous level as soon as possible.

Volume is specified in a doubleword value; the high-order 16 bits specify the relative volume of the right channel, and the low-order 16 bits specify the relative volume of the left channel.

For devices that don't support individual volume changes on both the left and right channels, the low-order 16 bits specify the volume level, and the high-order 16 bits are ignored. Values for the volume level range from 0x0 (silence) to 0xFFFF (maximum volume) and are interpreted logarithmically. The perceived volume increase is the same from volume level 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

When querying volume levels using midiOutGetVolume, the volume is returned in a doubleword location specified by a pointer parameter.


  73.5.9  Preloading Patches With Internal MIDI Synthesizers

Some internal MIDI synthesizer devices can't keep all of their patches loaded simultaneously. These devices must preload their patch data.

Windows provides the following functions to request that a synthesizer preload and cache specified patches.

Function	Description
midiOutCachePatches	Requests that an internal MIDI synthesizer device preload and cache specified melodic patches.
midiOutCacheDrumPatches	Requests that an internal MIDI synthesizer device preload and cache specified key-based percussion patches.
The midiOutCachePatches function takes a pointer to a PATCHARRAY to indicate the patches to be cached.

Each element in the array corresponds to a patch with each of the 16 bits representing one of the 16 MIDI channels. Bits are set for each of the channels that use that particular patch. For example, if patch number 0 is used by physical MIDI channels 0 and 8, set element 0 of the array to 0x0101.

The midiOutCacheDrumPatches function takes a pointer to a KEYARRAY to indicate the key-based percussion patches to be cached.

Each element in the array corresponds to a key-based percussion patch with each of the 16 bits representing one of the 16 MIDI channels. Bits are set for each of the channels that use that particular patch. For example, if the percussion patch for key number 60 is used by physical MIDI channels 9 and 15, set element 60 of the array to 0x8200.


  73.5.10  Using the MIDI Mapper With Low-Level MIDI Functions

The MIDI Mapper provides standard patch services for device-independent playback of MIDI files. Applications that use MIDI files for audio should use the MIDI Mapper. For information about the MIDI Mapper and about authoring device-independend MIDI files, see Chapter 72, »High-Level Audio«.

To use the MIDI Mapper, open it by using the midiOutOpen function with the wDeviceID parameter set to the constant MIDIMAPPER. You can then send MIDI messages to the MIDI Mapper by using the midiOutShortMsg or midiOutLongMsg function.


  73.6  Recording MIDI Audio

To record MIDI audio data, you must use low-level MIDI input functions. MCI does not currently provide a device handler for recording MIDI audio.


  73.6.1  MIDI Input Data Types

The MMSYSTEM.H header file defines data types and function prototypes for all of the low-level audio functions. MMSYSTEM.H defines the following data types for low-level MIDI input functions.

Type	Description
HMIDIIN	A handle of a MIDI input device.
MIDIHDR	A structure that is a header for a block of MIDI system-exclusive data. This structure is used for input as well as output.
MIDIINCAPS	A structure used to inquire about the capabilities of a MIDI input device.


  73.6.2  Querying MIDI Input Devices

Before recording MIDI audio, you should call the midiInGetDevCaps function to determine the capabilities of the MIDI input hardware present in the system. This function takes a pointer to a MIDIINCAPS structure that it fills with information about the capabilities of a given device. This information includes the manufacturer and product identifiers, a product name for the device, and the version number of the device driver.


  73.6.3  Opening MIDI Input Devices

Use the midiInOpen function to open a MIDI input device for recording. This function opens the device associated with the specified device identifier and returns a handle of the open device by writing the handle of a specified memory location.


  73.6.4  Managing MIDI Recording

Once you open a MIDI input device, you can begin recording MIDI data. Win32 provides the following functions for managing MIDI recording.

Function	Description
midiInAddBuffer	Sends a buffer to the device driver so it can be filled with recorded MIDI data.
midiInReset	Stops MIDI recording and marks all pending buffers as done.
midiInStart	Starts MIDI recording and resets the time stamp to zero.
midiInStop	Stops MIDI recording.
Use the midiInAddBuffer function to send data buffers to the device driver for recording system-exclusive messages. Before you use midiInAddBuffer, you must allocate and prepare memory for the MIDIHDR data structure and the data block pointed to by the lpData member. For information about allocating and preparing this memory, see Section 73.2.3, »Allocating and Preparing Audio Data Blocks«.

Use the midiInStart function to begin recording. To record system-exclusive messages, send at least one buffer to the driver with midiInAddBuffer before starting to record. As the buffers are filled with recorded data, the application is notified by one of the techniques discussed in Section 73.2.4, »Managing Audio Data Blocks«.

To stop recording, use the midiInStop function. Before closing the device by using the midiInClose function, call midiInReset to mark any pending data blocks as being done. Before freeing the memory used by a data block, call the midiInUnprepareHeader function to clean up the preparation performed previously.

You must use either a window-procedure function or a low-level callback function to receive MIDI data. If you want time-stamped data, you must use a low-level callback function.

To record system-exclusive messages, you must supply the device driver with data buffers. These buffers are specified by a MIDIHDR structure. This is the same structure used for MIDI buffered playback as described in Section 73.5.5, »Sending Buffered Messages«. Memory for the MIDIHDR structure and its accompanying data buffer must be allocated and prepared as shown in Section 73.2.3, »Allocating and Preparing Audio Data Blocks«.


  73.6.4.1  Using Window Messages to Manage MIDI Recording

The following messages can be sent to a window-procedure function for managing MIDI recording.

Message	Description
MM_MIM_CLOSE	Sent when the device is closed using the midiInClose function.
MM_MIM_DATA	Sent when a complete MIDI message is received (this message is used for all MIDI messages except system-exclusive messages).
MM_MIM_ERROR	Sent when an invalid MIDI message is received (this message is used for all MIDI messages except system-exclusive messages).
MM_MIM_LONGDATA	Sent when either a complete MIDI system-exclusive message is received, or when a data buffer sent using the midiInAddBuffer function is filled with system-exclusive data.
MM_MIM_LONGERROR	Sent when an invalid MIDI system-exclusive message is received.
MM_MIM_OPEN	Sent when the device is opened using the midiInOpen function.
A wParam and an lParam parameter are associated with each of these messages. The wParam parameter always specifies a handle of the open MIDI device. The lParam parameter is unused for the MM_MIM_CLOSE and MM_MIM_OPEN messages.

For the MM_MIM_DATA message, lParam specifies the received MIDI data. This data is packed into a doubleword value as follows.

Word	Byte	Contents
High-order word	High-order byte
	Low-order byte	MIDI data 2 (optional)
Low-order word	High-order Byte	MIDI data 1 (optional)
	Low-order byte	MIDI status
For the MM_MIM_LONGDATA message, lParam specifies a pointer to a MIDIHDR structure that identifies the data buffer for system-exclusive messages. The data buffer might not be completely filled — you usually don't know the size of the system-exclusive messages before recording them, so you must allocate a buffer large enough for the largest expected message. Use the dwBytesRecorded member of the MIDIHDR structure to determine the amount of valid data present in the buffer.


  73.6.4.2  Using a Low-Level Callback Function to Manage MIDI Recording

This syntax of the low-level callback function for MIDI input devices is as follows:

void CALLBACK midiInCallback(hMidiIn, wMsg,
    dwInstance, dwParam1, dwParam2)

The following messages can be sent in the wMsg parameter of MIDI input callback functions.

Message	Description
MIM_CLOSE	Sent when the device is closed using the midiInClose function.
MIM_DATA	Sent when a complete MIDI message is received (this message is used for all MIDI messages except system-exclusive messages).
MIM_ERROR	Sent when an invalid MIDI message is received (this message is used for all MIDI messages except system-exclusive messages).
MIM_LONGERROR	Sent when an invalid MIDI system-exclusive message is received.
MIM_LONGDATA	Sent when either a complete MIDI system-exclusive message is received, or when a data buffer is filled with system-exclusive data.
MIM_OPEN	Sent when the device is opened using the midiInOpen function.
These messages are similar to those sent to window-procedure functions, but the parameters are different. A handle of the open MIDI device is passed as a parameter to the callback, along with the doubleword value of instance data that was passed using the midiInOpen value.

The callback has two message-dependent parameters: dwParam1 and dwParam2. For the MIM_OPEN and MIM_CLOSE messages, these parameters are unused.

For the MIM_DATA message, dwParam1 specifies the received MIDI data and dwParam2 specifies a time stamp for the data. The data is packed into a doubleword value, as shown in the previous section on using window messages.

For the MIM_LONGDATA message, dwParam1 specifies a pointer to a MIDIHDR structure that identifies the data buffer for system-exclusive messages. As with the MIM_DATA message, dwParam2 specifies a time stamp for the data. The data buffer may not be completely filled. Use the dwBytesRecorded member of the MIDIHDR structure to determine the amount of valid data present in the buffer.

After the device driver is finished with a data block, you can clean up and free the data block. Because of the restrictions of low-level audio callbacks, you can't do this within the callback function. You must set semaphores and do this outside of the callback function. See Section 73.2.4.2, »Using a Callback Function to Process Driver Messages« for details about the restrictions on using callback functions.


  73.6.5  Receiving Time-Stamped MIDI Messages

Because of the delay between when the device driver receives a MIDI message and the time the application receives the message, MIDI input device drivers time-stamp the MIDI message with the time the message was received. MIDI time stamps are defined as the time the first byte of the message was received and are specified in milliseconds. The midiInStart function resets the time stamps for a device to zero.

As stated earlier, to receive time stamps with MIDI input, you must use a low-level callback function. The dwParam2 parameter of the callback function specifies the time stamp for data associated with the MIM_DATA and MIM_LONGDATA messages.


  73.6.6  Receiving Running-Status Messages

The MIDI 1.0 specification allows the use of running-status when a message has the same status byte as the previous message. When running status is used, the status byte of subsequent messages can be omitted. All MIDI input device drivers are required to expand messages using running status to complete messages — you always receive complete MIDI messages from a MIDI input device driver.


  73.7  Auxiliary Audio Devices

Auxiliary audio devices are audio devices whose output is mixed with the MIDI and waveform output devices in a multimedia computer. An example of an auxiliary audio device is the compact disc audio output from a CD-ROM drive.

Control for auxiliary audio devices is provided by a software-controlled audio mixer. The mixer can reside on the motherboard of a multimedia computer, or it can be on an add-in sound card. »This illustration« shows the conceptual audio-signal routing in a multimedia computer.

In this multimedia computer, there are two auxiliary audio devices: the CD-ROM and the external audio input. The external audio input is an input jack that allows the user to connect other audio devices.


  73.7.1  Querying Auxiliary Audio Devices

Not all multimedia systems have auxiliary audio support. You can use the auxGetNumDevs function to determine the number of controllable auxiliary devices present in a system.

To get information on a particular auxiliary audio device, use the auxGetDevCaps function. This function takes a pointer to an AUXCAPS structure that it fills with information about the capabilities of a given device.


  73.7.1.1  Determining Auxiliary Audio Device Types

The MMSYSTEM.H header file defines the following flags for the wTechnology member of the AUXCAPS structure to determine the device type of an auxiliary audio device.

Flag	Description
AUXCAPS_CDAUDIO	The device is an internal CD-ROM drive.
AUXCAPS_AUXIN	The device is an auxiliary audio input jack.


  73.7.1.2  Determining Capabilities of Auxiliary Audio Devices

The dwSupport member of the AUXCAPS structure indicates whether the device driver supports volume changes. The MMSYSTEM.H header file defines the following flags for the dwSupport member.

Flag	Description
AUXCAPS_VOLUME	Volume-control support
AUXCAPS_LRVOLUME	Individual volume-control support for both the left and right channels


  73.7.2  Changing Auxiliary Audio-Device Volume

Windows provides the following functions to query and set the volume for auxiliary audio devices.

Function	Description
auxGetVolume	Gets the volume level of the specified auxiliary audio device.
auxSetVolume	Sets the volume level of the specified auxiliary audio device.
Not all auxiliary audio devices support volume changes. Some devices can support individual volume changes on both the left and the right channels. See Section 73.3.2.3, »Determining Capabilities of Waveform Output Devices« for information about how to determine whether a particular device supports volume changes.

Note   Unless your application is designed to be a master volume-control application providing the user with volume control for all audio devices in a system, you should open an audio device before changing its volume. Also be sure your application queries the volume level before changing it and restores the volume level to its previous level as soon as possible.

The volume level is specified (as it was in the waveform and MIDI volume-control functions) in a doubleword value with the high-order 16 bits specifying the relative volume of the right channel and the low-order 16 bits specifying the relative volume of the left channel. For devices that don't support individual volume control on both the left and right channels, the low-order 16 bits specify the volume level, and the high-order 16 bits are ignored.

Values for the volume level range from 0x0 (silence) to 0xFFFF (maximum volume) and are interpreted logarithmically. This means the perceived volume increase is the same from volume level 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

When querying volume levels with the auxGetVolume function, the volume is returned in a doubleword location specified by a pointer parameter.


  73.8  Audio Clipboard Formats

In addition to the standard and nonstandard waveform formats previously presented in this chapter, there are two Clipboard formats that can be used to represent audio data: CF_WAVE and CF_RIFF. Use the CF_WAVE format to represent data in one of the standard formats, such as 11 kHz or 22 kHz PCM. Use the CF_RIFF format to represent more complex data formats that cannot be represented as standard wave files.


Multimedia Timers
  Chapter 74    Multimedia Timers

74.1  About Multimedia Timers

This chapter shows you how to add joystick input capabilities to your application and how to control event timing. The joystick services can receive control signals from up to two joysticks. Timer interrupt services provide improved timer resolution and accuracy. Intel-based systems have an accuracy of up to 16 milliseconds and MIPS-based systems have an accuracy of up to 10 milliseconds.

The functions and data structures associated with the joystick and timer-interrupt services are defined in MMSYSTEM.H and WINMM.LIB.


  74.2  Timer Services

The multimedia timer services provided with the Microsoft Win32 application programming interface (API) let applications schedule timed periodic or one-time interrupt events. Unlike the timer services that post WM_TIMER messages to a message queue, the multimedia timer services call a callback function.


  74.2.1  Timer Data Types

The MMSYSTEM.H header file defines new data types and function prototypes for timer functions. You must include this header file in any source-code module that uses timer services. MMSYSTEM.H defines the following new data types.

Type	Description
MMTIME	A structure for representing time in one of several formats.
TIMECAPS	A structure for querying timer capabilities.


  74.2.2  Using Timer Services

Timer services let an application request and receive timer messages at application-specified intervals. Real-time multimedia applications can use the following functions to control the pace of data and synchronized presentations.

Function	Description
timeBeginPeriod	Establishes the minimum timer resolution an application will use.
timeEndPeriod	Clears a minimum timer resolution previously set using timeBeginPeriod.
timeGetDevCaps	Returns information about the capabilities of the timer services.
timeGetTime	Returns the system time in milliseconds.
timeGetSystemTime	Fills an MMTIME structure with the system time in milliseconds.
timeSetEvent	Creates a timer event that executes a specific action at a specific time or at periodic intervals.
timeKillEvent	Cancels a timer event previously created using timeSetEvent.


  74.2.3  Getting the System Time

An application can get the current system time using the timeGetTime or timeGetSystemTime function. The system time is the count of milliseconds since the Microsoft Windows operating system was started. The timeGetTime function returns the system time, and the timeGetSystemTime function fills an MMTIME structure with the system time.


  74.2.4  Determining Maximum and Minimum Event Periods

You can use the timeGetDevCaps function to determine the minimum and maximum timer-event periods provided by the timer services. These values vary across computers and can vary depending on the mode in which Windows is running.


  74.2.5  Establishing Minimum Timer Resolution

Before starting timer events, your application must establish the minimum timer resolution that it intends to use. It must clear this value after finishing with the timer-event services.

Use the timeBeginPeriod and timeEndPeriod functions to set and clear the minimum timer-event resolution for your application. You must match a call to timeBeginPeriod with a corresponding call to timeEndPeriod, specifying the same minimum resolution in both calls. An application can make multiple timeBeginPeriod calls, as long as each call is matched with a call to timeEndPeriod.


  74.2.6  Starting Timer Events

To initialize and start timer events, use the timeSetEvent function. This function returns a timer identifier that can be used to stop or identify timer events.

The timeSetEvent function returns a timer identifier if successful or NULL if unsuccessful. Interrupt timers are a scarce resource, and periodic timers with resolution less than 100 milliseconds consume a significant portion of CPU time. For periodic timers, you must pair calls to timeSetEvent with calls to timeKillEvent. For more information, see Section 74.2.7, »Canceling a Timer Event«.

The lpFunction parameter contains the address of the function to be called when the timer event takes place.

Since the callback function is accessed at interrupt time, it must adhere to strict programming guidelines. Timer-callback functions follow the same programming guidelines as callback functions for the low-level audio services. Chapter 73, »Low-Level Audio«, for information about writing an interrupt callback function.


  74.2.7  Canceling a Timer Event

You can cancel an active timer event at any time. Be sure to cancel any outstanding timers before freeing the module containing the callback function. To cancel a timer event, use the timeKillEvent function.


  74.2.8  Using Timer Callbacks

This section describes how an application can use the timer services. First, the application calls the timeGetDevCaps function to determine the minimum and maximum resolution supported by the timer services. Before setting up any timer events, the application uses the timeBeginPeriod function to establish the minimum timer resolution it will use, as shown in the following example:

#define TARGET_RESOLUTION 1  /* Try for 1-millisecond accuracy. */

TIMECAPS tc;

UINT     wTimerRes;

if(timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {

    /* Error; application can't continue. */

}

wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION),

    tc.wPeriodMax);

timeBeginPeriod(wTimerRes);

To start the timer event, the application specifies the amount of time before the callback occurs, the required resolution, the address of the callback function, and user data to supply with the callback. The application can use a function like the following to start a one-time timer event.

UINT SetTimerCallback(NPSEQ npSeq,           /* Sequencer data */

                      UINT msInterval)       /* Event interval */

{

    npSeq->wTimerID = timeSetEvent(

         msInterval,           /* Delay                        */

         wTimerRes,            /* Resolution (global variable) */

         (LPTIMECALLBACK) OneShotTimer, /* Callback function   */

         (DWORD) npSeq,               /* User data             */

         TIME_ONESHOT);               /* Event type (one-time) */

    if (npSeq->wTimerID != 0)

        return TIMERR_NOCANDO;

    else

        return TIMERR_NOERROR;

}

The following callback function is used for the one-shot timer.

void PASCAL OneShotTimer(UINT wTimerID, UINT msg,

    DWORD dwUser, DWORD dw1, DWORD dw2)

{

    NPSEQ npSeq;            /* Pointer to sequencer data   */

    npSeq = (NPSEQ) dwUser;

    npSeq->wTimerID = 0;    /* Invalidate unused timer id  */

    TimerIntRoutine(npSeq); /* Handle interrupt-time tasks */

    UNREFERENCED_PARAMETER(dw1);

    UNREFERENCED_PARAMETER(dw2);

    UNREFERENCED_PARAMETER(msg);

    UNREFERENCED_PARAMETER(wTimerID);

}

Before freeing the dynamic-link library (DLL) that contains the callback function, the application cancels any outstanding timers. To cancel one timer event, it can call the following function.

void DestroyTimer(NPSEQ npSeq)

{

    if (npSeq->wTimerID) {      /* If timer event is pending */

        timeKillEvent(npSeq->wTimerID);  /* Cancel the event */

        npSeq->wTimerID = 0;

    }

}

Finally, to cancel the minimum timer resolution it established, the application calls timeEndPeriod as follows.

timeEndPeriod(wTimerRes);


  74.3  Joystick Services

The joystick is an input device that provides position information. It is an additional supported input device, not a replacement for the mouse. All absolute-position devices, including touch screens, digitizing tablets, and light pens, can use the joystick services to provide position and button information to applications.

The joystick services are loaded when Windows is started. The joystick services can monitor two joysticks, each with two- or three-axis movement, and up to four buttons. Applications access the joystick services through the set of functions described in this section.

Note   The driver for the IBM® Game Adapter supports two 2-axis joysticks or one 3-axis joystick.


  74.3.1  Joystick Data Types

The MMSYSTEM.H header file defines new data types and function prototypes for joystick functions. MMSYSTEM.H defines the following new data types.

Type	Description
JOYCAPS	A structure that contains joystick capability information.
JOYINFO	A structure that contains joystick position and button information.


  74.3.2  Using Joystick Services

Joystick services include functions to query each joystick for its capabilities, to poll each joystick for position and button information, and to receive messages in response to joystick events. Your application can use the following joystick functions to accept input from one or two joysticks.

Function	Description
joyGetNumDevs	Returns the number of joysticks supported by the joystick services.
joyGetDevCaps	Returns joystick capabilities.
joyGetPos	Returns joystick position and button information.
joySetCapture	Causes joystick input to be sent to a specified window at regular intervals or when the joystick state changes.
joyReleaseCapture	Releases the joystick captured using joySetCapture.
joyGetThreshold	Returns the movement threshold of a joystick.
joySetThreshold	Sets the movement threshold of a joystick.


  74.3.3  Determining Joystick Capabilities

The various joysticks in use today can support two or three axes and a variety of button configurations. Also, joysticks support different ranges of motion and polling frequencies. Joystick drivers can support either one or two joysticks. Two functions allow you to determine the capabilities of the joystick services and joystick devices installed on a system.


  74.3.3.1  Getting the Driver Capabilities

You can use the joyGetNumDevs function to determine the number of joystick devices supported by the joystick services. This function returns the number of supported joysticks, or zero if there is no joystick support. The value returned is not necessarily the number of joysticks attached to the system. To determine whether a joystick is attached, call the joyGetPos function for the device. The function returns JOYERR_UNPLUGGED if the specified device is disconnected.

The following example determines whether the joystick services are available and then determines if a joystick is attached to one of the ports:

JOYINFO joyinfo;

UINT wNumDevs, wDeviceID;

BOOL bDev1Attached, bDev2Attached;

    if((wNumDevs = joyGetNumDevs()) == 0)

        return ERR_NODRIVER;

    bDev1Attached = joyGetPos(JOYSTICKID1,&joyinfo) != JOYERR_UNPLUGGED;

    bDev2Attached = wNumDevs == 2 &&

                     joyGetPos(JOYSTICKID2,&joyinfo) != JOYERR_UNPLUGGED;

    if(bDev1Attached || bDev2Attached) /* Decide which joystick to use */

        wDeviceID = bDev1Attached ? JOYSTICKID1 : JOYSTICKID2;

    else

        return ERR_NODEVICE;


  74.3.3.2  Getting the Joystick Capabilities

You can use the joyGetDevCaps function to obtain the specific capabilities of each joystick attached to a given system. This function fills a JOYCAPS structure with the range of each axis on the joystick, the number of buttons, and the maximum and minimum polling frequency.


  74.3.4  Methods for Checking Joystick Status

An application can receive information from the joystick in one of two ways:

•	By processing joystick messages from a captured joystick

•	By polling the joystick directly

The message-processing method can be simpler to use; your application is sent messages that indicate the position of the stick and the state of the buttons (pressed or released).


  74.3.5  Capturing Joystick Messages to a Window Function

You can capture joystick input to a window function; your application then receives joystick messages at specified intervals or when the user manipulates the joystick. The messages are described in the following section.

Only one application can capture joystick messages from a given joystick. Capturing joystick messages does not, however, prevent your application (or other applications) from polling the joystick using joyGetPos. If joyGetPos is called while joystick input is captured, joystick events occurring close to the time of the joyGetPos call may not be accurately reported to the capture window.

The joySetCapture function captures joystick input to a window function you specify. To release the joystick, call the joyReleaseCapture function.

To capture messages from two joysticks attached to the system, you must call joySetCapture twice, once for each joystick. Your window then receives separate messages for each device.

You cannot capture an unplugged joystick. The joySetCapture function returns zero if successful; it returns JOYERR_UNPLUGGED if the specified device is unplugged.

Note   The joystick services set up a Windows timer event with each call to joySetCapture.

Set the period parameter for joySetCapture to a value that falls within the minimum and maximum resolution range for the joystick. To determine the minimum and maximum resolution of the joystick, call the joyGetDevCaps function, which fills the wPeriodMin and wPeriodMax members in the JOYCAPS structure.

If the specified period value is outside the range of valid resolution values for the joystick, the joystick services use the minimum or maximum resolution value, whichever is closer to the specified period.


  74.3.6  Processing Joystick Messages

The following joystick messages can be sent to a window function. Numerals 1 and 2 in these messages correspond to the joystick initiating the message. MM_JOY1 messages are sent to the window function if your application requests input from the first joystick, and MM_JOY2 messages are sent if your application requests input from the second joystick. All messages report nonexistent buttons as released.

Messages	Description
MM_JOY1MOVE, MM_JOY2MOVE	Report a change in the x-axis and/or y-axis position of the joystick. The wParam parameter contains a combination of JOY_BUTTON bit flags specifying which buttons were pressed. The low-order word of lParam contains the x-position of the joystick, and the high-order word contains the y-position.
MM_JOY1ZMOVE, MM_JOY2ZMOVE	Report a change in the z-axis position of a 3-axis joystick. The wParam parameter contains a combination of JOY_BUTTON bit flags specifying which buttons were pressed. The low-order word of lParam contains the x-position of the joystick, and the high-order word contains the y-position.
MM_JOY1BUTTONUP, MM_JOY2BUTTONUP, MM_JOY1BUTTONDOWN, MM_JOY2BUTTONDOWN	Report that a joystick button has been pressed or released. The wParam parameter contains one JOY_BUTTONCHG bit flag specifying which button changed state and a combination of JOY_BUTTON bit flags specifying the current button states. The low-order word of lParam contains the x-position of the joystick, and the high-order word contains the y-position.
The joystick services use the following bit flags, passed in the wParam parameter of the window function, to report the state of the joystick buttons.

Flag	Description
JOY_BUTTON1	Set when button 1 is pressed.
JOY_BUTTON1CHG	Set when button 1 has changed state.
JOY_BUTTON2	Set when button 2 is pressed.
JOY_BUTTON2CHG	Set when button 2 has changed state.
JOY_BUTTON3	Set when button 3 is pressed.
JOY_BUTTON3CHG	Set when button 3 has changed state.
JOY_BUTTON4	Set when button 4 is pressed.
JOY_BUTTON4CHG	Set when button 4 has changed state.
The MM_JOYMOVE messages use the JOY_BUTTON flags to report the state (pressed or released) of all buttons on the specified joystick.

The MM_JOYBUTTONUP and MM_JOYBUTTONDOWN messages use the JOY_BUTTON flags to report the state (pressed or released) of all buttons on the specified joystick. Also, they use JOY_BUTTONCHG flags to indicate which button changed state, thereby generating the message.

For example, if the user presses and holds buttons 1 and 2 and then moves the stick, a window function may receive the following messages.

Message	wParam Flags
MM_JOY1BUTTONDOWN	JOY_BUTTON1 | JOY_BUTTON1CHG
MM_JOY1BUTTONDOWN	JOY_BUTTON1 | JOY_BUTTON2 | JOY_BUTTON2CHG
MM_JOY1MOVE	JOY_BUTTON1 | JOY_BUTTON2
A window function may receive the following messages when the user presses and releases button 3 without moving the stick.

Message	wParam Flags
MM_JOY1BUTTONDOWN	JOY_BUTTON3 | JOY_BUTTON3CHG
MM_JOY1BUTTONUP	JOY_BUTTON3CHG


  74.3.7  Releasing the Joystick

When your application no longer needs to receive periodic joystick messages, it should release the joystick by using the joyReleaseCapture function. If your application does not release the joystick before ending, the joystick is released shortly after the capture window is destroyed.


  74.3.8  Setting the Movement Threshold

You can change the movement threshold of the joystick by calling the joySetThreshold function. The movement threshold is the number of device units that the stick must be moved before an MM_JOYMOVE message is sent to the window that has captured the device.


  74.3.9  Polling the Joystick

You can poll the joystick for position and button information. For example, an application may poll the joystick to get baseline position values; the Joystick Control Panel application uses this technique when calibrating the joystick. The joyGetPos function allows you to poll the joystick for position and button information.

Note   Calling joyGetPos while joystick input is captured can prevent the joystick services from accurately reporting joystick events to the capture window.


  74.3.10  Using Joystick Messages

The remainder of this chapter presents examples from a simple joystick game that performs the useful function of shooting holes in the desktop: it gets position and button-state information from the joystick services and, when a user presses the joystick buttons, plays waveform resources and paints bullet holes on the screen.

Most of the joystick-control code is in the main window function. In the following WM_CREATE case of the message handler, the application captures input from joystick 1.

case WM_CREATE:

    if(joySetCapture(hWnd, JOYSTICKID1,  NULL, FALSE)) {

        MessageBeep(MB_ICONEXCLAMATION);

        MessageBox(hWnd, "Couldn't capture the joystick.", NULL,

                        MB_OK | MB_ICONEXCLAMATION);

        PostMessage(hWnd,WM_CLOSE,0,0L);

    }

    break;

In response to the MM_JOY1MOVE messages, the application changes the position of the cursor and, if either button is pressed, draws a hole in the desktop.

case MM_JOY1MOVE :

    if((UINT) wParam & (JOY_BUTTON1 | JOY_BUTTON2))

        DrawFire(hWnd);

    DrawSight(lParam);  /* Calculate new cursor position */

    break;

In response to the MM_JOY1BUTTONDOWN messages, the application uses sndPlaySound to play a waveform audio file.

case MM_JOY1BUTTONDOWN :

    if((UINT) wParam & JOY_BUTTON1) {

        sndPlaySound(lpButton1,

                     SND_LOOP | SND_ASYNC | SND_MEMORY);

        DrawFire(hWnd);

    }

    else if(wParam & JOY_BUTTON2) {

        sndPlaySound(lpButton2,

                     SND_ASYNC | SND_MEMORY |  SND_LOOP);

        DrawFire(hWnd);

    }

    break;

By specifying the SND_LOOP and SND_ASYNC flags with sndPlaySound, the JOYTOY application repeats the waveform playback until the button is released.

When a button is released, the window function receives a MM_JOY1BUTTONUP message, and handles it with the following statement.

case MM_JOY1BUTTONUP:

    sndPlaySound(NULL, 0);

    break;

This sequence stops the waveform-audio playback.


Multimedia File Input/Output
  Chapter 75    Multimedia File Input/Output

75.1  About the Multimedia File Input/Output Services

Most multimedia applications require file input/output (I/O) — the ability to create, read, and write disk files. The multimedia file I/O services provided by the Microsoft Win32 application programming interface (API) offer buffered and unbuffered file I/O and support for standard Resource Interchange File Format (RIFF) files. The services are extensible with custom I/O procedures that can be shared among applications.

This chapter covers the following topics:

•	Using basic file I/O services

•	Performing buffered file I/O

•	Working with RIFF files

•	Directly accessing a file I/O buffer

•	Using memory files

•	Writing a custom I/O procedure

The multimedia file I/O services provide support for the following file I/O operations:

•	Basic unbuffered and buffered file I/O

•	RIFF file I/O

•	Direct access to the file I/O buffer

•	Memory files

•	Custom storage system I/O using application-supplied I/O procedures

Most applications only need the basic file I/O services and the RIFF file I/O services. Applications sensitive to file I/O performance, such as applications that stream data from a CD-ROM in real time, can optimize performance by using services to directly access the file I/O buffer. Applications that access custom storage systems can provide their own I/O procedure that reads and writes elements of the storage system. A storage system is a method of physically storing data in a file, such as a file-archival system or a database storage system.


  75.1.1  Comparison With Other File I/O

You might ask why you need another set of file I/O services, when you already have the services of the C run-time and Win32 API libraries. The multimedia file I/O services offer the following advantages over other file I/O services:

•	They are a part of the system software, so they don't increase the size of your application, like linking to the C run-time libraries

•	They provide more functionality than the Win32 services, such as support for buffered I/O, RIFF files, memory files, and custom storage systems

In addition, the multimedia file I/O services are optimized for performance-intensive applications.


  75.1.2  Function Prefixes

All multimedia file I/O function names begin with the mmio prefix. Similarly, all multimedia file I/O message names begin with the MMIOM_ prefix.


  75.1.3  Data Types

The MMSYSTEM.H header file defines data types and function prototypes for all multimedia file I/O functions. You must include this header file in any source-code module that uses these functions. MMSYSTEM.H depends on declarations made in WINDOWS.H, so you must first include the WINDOWS.H header file. MMSYSTEM.H defines the following data types for the multimedia file I/O functions.

Type	Description
FOURCC	A four-character code identifying an element of a RIFF file.
HMMIO	A handle of an open file.
MMCKINFO	A structure containing information about a chunk in a RIFF file.
MMIOINFO	A structure used to maintain the current state of a file accessed using the multimedia file I/O services.
MMIOPROC	A custom multimedia file I/O procedure.


  75.2  Performing Basic File Input/Output

Using the basic I/O services is similar to using the C run-time file I/O services. Files must be opened before they can be read or written. After reading or writing, the file must be closed. You can change the current read/write location by seeking to a specified position in an open file. The following table lists the basic file I/O functions.

Function	Description
mmioClose	Closes an open file.
mmioOpen	Opens a file for reading or writing or both and returns a handle of the open file.
mmioRead	Reads a specified number of bytes from an open file.
mmioSeek	Changes the current position for reading or writing in an open file.
mmioWrite	Writes a specified number of bytes to an open file.
These file I/O functions provide the core of the multimedia file I/O services — you can use them for buffered and unbuffered I/O, as well as for I/O to RIFF files, memory files, and custom storage systems.


  75.2.1  Opening a File

Before doing any I/O operations to a file, you must first open the file by using the mmioOpen function. The mmioOpen function returns a file handle that you use to identify the open file when calling other file I/O functions.

Note   Do not use HMMIO file handles with Windows or C run-time file I/O functions.

There are options you can use with the mmioOpen function for operations beyond basic file I/O. By specifying an MMIOINFO structure with the lpmmioinfo parameter you can open memory files, specify a custom I/O procedure, or supply a buffer for buffered I/O. These topics are discussed later in this chapter. First, this chapter discusses the most basic use of mmioOpen — opening files for basic unbuffered file I/O.

To open a file for basic I/O operations, set the lpmmioinfo parameter of mmioOpen to NULL. For example, the following example opens a file named C:\SAMPLES\SAMPLE1.TXT for reading, and checks the return value for errors.

HMMIO hFile;

    .

    .

    .

if ((hFile = mmioOpen("C:\\SAMPLES\\SAMPLE1.TXT",

        NULL, MMIO_READ)) != NULL) /* File opened successfully */

    return TRUE;

else

        /* File cannot be opened. */

    return FALSE;


  75.2.1.1  Options for Opening a File

When you open a file, you must specify whether you are opening the file for reading, writing, or both reading and writing. In addition, you can specify other options, such as to create or delete a new file. Use the dwFlags parameter of mmioOpen to specify options for opening a file.

Following are the basic options for opening a file using mmioOpen:

Flag	Description
MMIO_READ	Opens a file for reading only.
MMIO_WRITE	Opens a file for writing only.
MMIO_READWRITE	Opens a file for reading and writing.
MMIO_CREATE	Creates a new file (if the file already exists, it truncates it to zero length).
MMIO_DELETE	Deletes a file.
MMIO_ALLOCBUF	Opens a file for buffered I/O.
The MMIO_READ, MMIO_WRITE, and MMIO_READWRITE flags are read/write privilege flags. These flags are mutually exclusive — specify only one when opening a file. If you don't specify one of these flags, mmioOpen opens the file for reading only.

The MMIO_CREATE and MMIO_DELETE flags are also mutually exclusive. You can specify one of the read/write privilege flags with the MMIO_CREATE flag. You can't specify any additional flags with the MMIO_DELETE flag.

For information on using the MMIO_ALLOCBUF flag, see Section 75.3, »Performing Buffered File Input/Output«, later in this chapter.

In addition to the basic options for opening a file, there are sharing options you can use for opening files so they can be opened and accessed by more than one process. Following are the sharing options for opening a file using mmioOpen.

Flag	Description
MMIO_COMPAT	Opens a file in compatibility mode.
MMIO_EXCLUSIVE	Opens a file in exclusive mode.
MMIO_DENYWRITE	Opens a file and denies other processes write access to the file.
MMIO_DENYREAD	Opens a file and denies other processes read access to the file.
MMIO_DENYNONE	Opens a file without denying other processes read or write access to the file.


  75.2.2  Creating and Deleting Files

To create a new file, specify the MMIO_CREATE option with the mmioOpen function. For example, the following example creates a new file and opens it for both reading and writing.

HMMIO hFile;

    .

    .

    .

hFile = mmioOpen("NEWFILE.TXT",

                  NULL, MMIO_CREATE | MMIO_READWRITE);

if (hFile != NULL)

        /* File created successfully. */

    return TRUE;

else

        /* File could not be created. */

    return FALSE;

Note   If the file you are creating already exists, it will be truncated to zero length.

To delete a file, specify the MMIO_DELETE flag with the mmioOpen function. Once you delete a file, it can't be recovered. If the file deletion is the result of a request from a user, always query the user to be sure the user wants to delete the specified file before you actually delete it.


  75.2.3  Reading and Writing a File

To read and write to open files, use the mmioRead and mmioWrite functions. Each of these functions takes an HMMIO file handle, a pointer to a buffer, and a parameter specifying the number of bytes to read or write.

See Section 75.4.5, »Example of RIFF File I/O«, later in this chapter, for an example using mmioRead to read from a file.


  75.2.4  Seeking to a New Position in a File

The current position or file pointer in a file is the location where the next read or write operation will occur. To change the current position in an open file, use the mmioSeek function.

The return value is the new position, specified in bytes from the beginning of the file. If an error occurs, the return value is −1. If you seek to an invalid location in a file, such as past the end of the file, mmioSeek may not return an error, but subsequent I/O operations can fail.


  75.3  Performing Buffered File Input/Output

Most of the overhead in file I/O involves accessing the media (the physical device). If you are reading or writing many small blocks of information, the media device can spend a lot of time seeking the physical location on the media for each read or write operation. In this case, better performance is achieved by using buffered file I/O. With buffered I/O, the file I/O manager maintains an intermediate buffer larger than the blocks of information you are reading or writing. It only accesses the media when the buffer must be filled from or written to the disk.


  75.3.1  Deciding When to Use Buffered File I/O

It's difficult to provide exact metrics telling you when you need to use buffered I/O. It depends on how many read and write operations you perform on a file, and on the size of these read and write operations. A general guideline is to use buffered I/O if you are doing many small I/O operations (less than 2 kilobytes each). But this rule isn't absolute — it's best to understand exactly how your program uses file I/O and experiment to optimize file I/O for your program's requirements.


  75.3.2  Opening a File for Buffered File I/O

The multimedia file I/O manager provides several ways to set up and use buffered file I/O. The main distinction between these different approaches is whether the file I/O manager or the application allocates the buffer — either the file I/O manager or the application can allocate the I/O buffer. Unless you want to access the I/O buffer directly or open a memory file, let the file I/O manager allocate the buffer. For more information about accessing an I/O buffer directly and using memory files, see Section 75.5, »Directly Accessing a File Input/Output Buffer«, and Section 75.6, »Performing File Input/Output on Memory Files«, both later in this chapter.

A buffer allocated by the file I/O manager is called an internal buffer. To open a file for buffered I/O using an internal buffer, specify the MMIO_ALLOCBUF flag with the mmioOpen function when you open the file. Once a file is opened for buffered I/O, the buffer is essentially transparent to the application. You can read, write, and seek the same way as with unbuffered I/O.


  75.3.3  I/O Buffer Control Functions

The multimedia file I/O services also include some functions that give you more control over the file I/O buffer. Using the following functions, you can force the contents of an I/O buffer to be written to disk, enable buffered I/O on a file opened for unbuffered I/O, change the size of an I/O buffer, and supply your own I/O buffer.

Function	Description
mmioFlush	Writes the contents of the I/O buffer to disk.
mmioSetBuffer	Changes the size of the I/O buffer, and allows applications to supply their own buffer.


  75.3.3.1  Flushing an I/O Buffer

Flushing an I/O buffer means writing the contents of the buffer to disk. You don't have to call the mmioFlush function to flush an I/O buffer — the buffer is automatically flushed when you close a file using the mmioClose function. If you don't close a file immediately after writing to it, you flush the buffer to ensure the information is written to disk.

Note   If you run out of disk space, mmioFlush may fail, even if the preceding mmioWrite calls were successful. Similarly, mmioClose may fail when it is flushing its I/O buffer.


  75.3.3.2  Changing the Size of the Internal I/O Buffer

The default size of the internal I/O buffer is 8K. If this size is not adequate, you can use the mmioSetBuffer function to change the size of the buffer. You can also use mmioSetBuffer to enable buffering on a file opened for unbuffered I/O.

The following example opens a file named SAMPLE.TXT for unbuffered I/O, and then enables buffered I/O with an internal 16K buffer.

HMMIO hFile;

    .

    .

    .

if ((hFile = mmioOpen("SAMPLE.TXT", NULL, MMIO_READ)) != NULL) {

    /* File opened successfully; request an I/O buffer */

    if (mmioSetBuffer(hFile, NULL, 16384L, 0))

            /* Buffer cannot be allocated. */

        return FALSE;

    else

            /* Buffer allocated successfully. */

        return TRUE;

}

else

        /* File cannot be opened. */

    return FALSE;


  75.3.3.3  Supplying Your Own I/O Buffer

You can also use mmioSetBuffer to supply your own buffer for use as a memory file. For details on using memory files, see Section 75.6, »Performing File Input/Output on Memory Files«.


  75.4  Working With RIFF Files

The preferred format for multimedia files is the Resource Interchange File Format (RIFF). The RIFF format is a tagged-file structure.

The multimedia file I/O services provide the following functions to support file I/O to RIFF files.

Function	Description
mmioAscend	Ascends out of a RIFF file chunk to the next chunk in the file.
mmioCreateChunk	Creates a new chunk in a RIFF file.
mmioDescend	Descends into a RIFF file chunk beginning at the current file position, or searches for a specified chunk.
mmioFOURCC	Converts four individual characters into a four-character code.
mmioStringToFOURCC	Converts a null-terminated string into a four-character code.
These functions work with the basic buffered and unbuffered file I/O services — you can open, read, and write RIFF files the same as other file types.


  75.4.1  About RIFF Files

The basic building block of a RIFF file is called a chunk. Each chunk consists of the following fields:

•	A four-character code specifying the chunk identifier

•	A doubleword specifying the size of the data field in the chunk

•	A data field

The only chunks allowed to contain other chunks (subchunks) are those with a chunk identifier of "RIFF" or "LIST". The first chunk in a RIFF file must be a "RIFF" chunk. All other chunks in the file are subchunks of the "RIFF" chunk.


75.4.1.1  RIFF Chunks
  75.4.1.1  "RIFF" Chunks

"RIFF" chunks include an additional field in the first four bytes of the data field. This additional field provides the form type of the field. The form type is a four-character code identifying the format of the data stored in the file. For example, Microsoft waveform audio files (WAVE files) have a form type of "WAVE". »This illustration« shows a "RIFF" chunk containing two subchunks.


75.4.1.2  LIST Chunks
  75.4.1.2  "LIST" Chunks

"LIST" chunks also include an additional field in the first four bytes of the data field. This additional field contains the list type of the field. The list type is a four-character code identifying the contents of the list. For example, a "LIST" chunk with a list type of "INFO" can contain "ICOP" and "ICRD" chunks providing copyright and creation date information. »This illustration« shows a "RIFF" chunk containing a "LIST" chunk and one other subchunk (the "LIST" chunk contains two subchunks).


  75.4.2  Generating Four-Character Codes

A four-character code is a 32-bit quantity representing a sequence of one to four ASCII alphanumeric characters, padded on the right with blank characters. The data type for a four-character code is FOURCC. Use the mmioFOURCC function to convert four characters to a four-character code, as shown in the following example, which generates a four-character code for "WAVE":

FOURCC fourccID;

    .

    .

    .

fourccID = mmioFOURCC('W', 'A', 'V', 'E');

To convert a null-terminated string into a four-character code, use the mmioStringToFOURCC function, as shown in the following example, which also generates a four-character code for "WAVE":

FOURCC fourccID;

    .

    .

    .

fourccID = mmioStringToFOURCC("WAVE", 0);

The second parameter in mmioStringToFOURCC specifies options for converting the string to a four-character code. If you specify the MMIO_TOUPPER flag, mmioStringToFOURCC converts all alphabetic characters in the string to uppercase. This is useful when you need to specify a four-character code to identify a custom I/O procedure (four-character codes identifying file-extension names must be all uppercase).


  75.4.3  Creating RIFF Chunks

To create a new chunk, use the mmioCreateChunk function to write a chunk header at the current position in an open file.

The following example creates a new chunk with a chunk ID of "RIFF" and a form type of "RDIB".

HMMIO    hmmio;

MMCKINFO mmckinfo;

    .

    .

    .

mmckinfo.fccType = mmioFOURCC('R', 'D', 'I', 'B');

mmioCreateChunk(hmmio, &mmckinfo, MMIO_CREATERIFF);

If you're creating a "RIFF" or "LIST" chunk, you must specify the form type in the fccType field of the MMCKINFO structure. In the previous example, the form type is "RDIB".

If you know the size of the data field in a new chunk, you can set the cksize member in the MMCKINFO structure when you create the chunk. This value will be written to the data size field in the new chunk. If this value is not correct when you call the mmioAscend function to mark the end of the chunk, it will be rewritten automatically to reflect the correct size of the data field.

After you create a new chunk using mmioCreateChunk, the file position is set to the data field of the chunk (8 bytes from the beginning of the chunk). If the chunk is a "RIFF" or "LIST" chunk, the file position is set to the location following the form type or list type (12 bytes from the beginning of the chunk).


  75.4.4  Navigating RIFF Files

RIFF files consist of nested chunks of data. Multimedia file I/O services include two functions you can use to navigate between chunks in a RIFF file: mmioAscend and mmioDescend. You might think of these functions as high-level seek functions. When you descend into a chunk, the file position is set to the data field of the chunk (8 bytes from the beginning of the chunk). For "RIFF" and "LIST" chunks, the file position is set to the location following the form type or list type (12 bytes from the beginning of the chunk). When you ascend out of a chunk, the file position is set to the location following the end of the chunk.


  75.4.4.1  Descending Into a Chunk

The mmioDescend function descends into a chunk or searches for a chunk, beginning at the current file position.

The mmioDescend function fills an MMCKINFO structure with information on the chunk. This information includes the chunk identifier, the size of the data field, and the form type, or list type if the chunk is a "RIFF" or "LIST" chunk.


  75.4.4.2  Searching for a Chunk

To search for a chunk in an open RIFF file, specify the MMIO_FINDCHUNK flag in the wFlags parameter of mmioDescend. Set the ckid member of the MMCKINFO structure referenced by lpck to the four-character code of the chunk you want to search for.

If you are searching for a "RIFF" or "LIST" chunk, you don't need to set the ckid member of the MMCKINFO structure — mmioDescend sets this member for you. Set the fccType member to the four-character code of the form type or list type of the chunk.

The following example searches for a "RIFF" chunk with a form type of "WAVE" to verify that the file that has just been opened is a WAVE waveform audio file.

HMMIO    hmmio;

MMCKINFO mmckinfoParent;

MMCKINFO mmckinfoSubchunk;

    .

    .

    .

/*

 * Locate a "RIFF" chunk with a "WAVE" form type

 * to make sure the file is a WAVE file.

 */

mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');

if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent,

                NULL, MMIO_FINDRIFF))

        /* The file is not a WAVE file. */

    return FALSE;

else

        /* The file is a WAVE file. */

    return TRUE;

If the chunk you are searching for is a subchunk enclosed by a parent chunk (as are all chunks other than "RIFF" chunks), you should identify the parent chunk with the lpckParent parameter. In this case, mmioDescend will only search within the specified parent chunk.

The following example searches for the "fmt " chunk in the "RIFF" chunk descended into by the previous example.

/*

 * Find the format chunk (form type "fmt "); it should be

 * a subchunk of the "RIFF" parent chunk.

 */

mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');

if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,

        MMIO_FINDCHUNK)) {

        /* Error, cannot find the "fmt " chunk. */

    return FALSE;

}

else {

        /* "fmt " chunk found. */

    return TRUE;

}

If you do not specify a parent chunk, the current file position should be at the beginning of a chunk before you call mmioDescend to search for a chunk. If you do specify a parent chunk, the current file position can be anywhere in the parent chunk.

If the search for a subchunk fails, the current file position is undefined. You can use the mmioSeek function and the dwDataOffset field of the MMCKINFO structure for the enclosing parent chunk to seek back to the beginning of the parent chunk, as in the following example:

mmioSeek(hmmio, mmckinfoParent.dwDataOffset + 4, SEEK_SET);

Since the dwDataOffset member specifies the offset to the beginning of the data portion of the chunk, you must seek four bytes past dwDataOffset to set the file position to be after the form type.


  75.4.4.3  Ascending Out of a Chunk

After you descend into a chunk and read the data in the chunk, you can move the file position to the beginning of the next chunk by ascending out of the chunk by using the mmioAscend function.

For example, the following statement ascends out of the "fmt " subchunk descended into by the previous example, illustrating searching for a subchunk:

/* Ascend out of the "fmt " subchunk.

 */

mmioAscend(hmmio, &mmckinfoSubchunk, 0);


  75.4.5  Example of RIFF File I/O

The following example shows how to open a RIFF file for buffered I/O, as well as how to descend, ascend, and read RIFF chunks.

/* ReversePlay--Plays a WAVE waveform audio file backwards. */

void ReversePlay(void)

{

    char        szFileName[128];  /* filename of file to open           */

    HMMIO       hmmio;            /* file handle for open file          */

    MMCKINFO    mmckinfoParent;   /* parent chunk information structure */

    MMCKINFO    mmckinfoSubchunk; /* subchunk information structure     */

    DWORD       dwFmtSize;        /* size of "fmt" chunk                */

    DWORD       dwDataSize;       /* size of "data" chunk               */

    WAVEFORMAT  *pFormat;         /* pointer to memory for "fmt" chunk  */

    ...

    /* Get the filename from the edit control. */

     ...

    /*

     * Open the given file for reading with buffered I/O

     * using the default internal buffer.

     */

    hmmio = mmioOpen(szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF);

    if(hmmio == NULL){

        Error("Failed to open file.");

        return;

    }

    /*

     * Locate a "RIFF" chunk with a "WAVE" form type

     * to make sure the file is a WAVE file.

     */

    mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');

    if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL,

                    MMIO_FINDRIFF)) {

        Error("This is not a WAVE file.");

        mmioClose(hmmio, 0);

        return;

    }

    /*

     * Find the "fmt " chunk (form type "fmt "); it must be

     * a subchunk of the "RIFF" parent chunk.

     */

    mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');

    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,

                    MMIO_FINDCHUNK)) {

        Error("WAVE file has no \"fmt\" chunk");

        mmioClose(hmmio, 0);

        return;

    }

    /*

     * Get the size of the "fmt " chunk--allocate and lock memory for it.

     */

    dwFmtSize = mmckinfoSubchunk.cksize;

    ...

    /* Read the "fmt " chunk. */

    if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != (LRESULT)dwFmtSize){

        Error("Failed to read format chunk.");

        ...

        mmioClose(hmmio, 0);

        return;

    }

    /* Ascend out of the "fmt " subchunk. */

    mmioAscend(hmmio, &mmckinfoSubchunk, 0);

    /*

     * Find the data subchunk. The current file position

     * should be at the beginning of the data chunk.

     */

    mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');

    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,

                    MMIO_FINDCHUNK)) {

        Error("WAVE file has no data chunk.");

        ...

        mmioClose(hmmio, 0);

        return;

    }

    /* Get the size of the data subchunk. */

    dwDataSize = mmckinfoSubchunk.cksize;

    if (dwDataSize == 0L) {

        Error("The data chunk contains no data.");

        ...

        mmioClose(hmmio, 0);

        return;

    }

    /* Open a waveform output device. */

    ...

    /* Allocate and lock memory for the waveform data. */

    ...

    /* Read the waveform data subchunk. */

    if(mmioRead(hmmio, (HPSTR) lpData,

            dwDataSize) != (LRESULT)dwDataSize) {

        Error("Failed to read data chunk.");

        ...

        mmioClose(hmmio, 0);

        return;

    }

    /* Close the file. */

    mmioClose(hmmio, 0);

    /* Reverse the sound and play it. */

    ...

}


  75.5  Directly Accessing a File Input/Output Buffer

Applications that are performance sensitive, such as applications that must stream data in real time from a CD-ROM, can optimize file I/O performance by accessing the file I/O buffer directly. Exercise care if you choose to do this — by accessing the file I/O buffer directly, you bypass some of the safeguards and error checking provided by the file I/O manager.

The multimedia file I/O services provide the following functions to support direct I/O buffer access.

Function	Description
mmioAdvance	Fills and/or flushes the I/O buffer of a file set up for direct I/O buffer access.
mmioGetInfo	Retrieves information on the file I/O buffer of a file opened for buffered I/O.
mmioSetInfo	Changes information on the file I/O buffer of a file opened for buffered I/O.
To access a file I/O buffer directly, open the file for buffered I/O as described in "Performing Buffered File I/O." You can use the internal file I/O buffer or supply your own buffer by using the mmioSetBuffer function.


  75.5.1  Getting Information on the File I/O Buffer

Use the mmioGetInfo function to get information on a file I/O buffer, such as the buffer size and address.


  75.5.2  Reading and Writing the File I/O Buffer

There are three members in the MMIOINFO structure used for reading and writing the file I/O buffer: pchNext, pchEndRead, and pchEndWrite. The pchNext field points to the next location in the buffer to read or write. You must increment pchNext as you read and write the buffer. The pchEndRead field identifies the last valid character you can read from the buffer. Likewise, pchEndWrite identifies the last location in the buffer you can write. To be precise, both pchEndRead and pchEndWrite point to the memory location following the last valid data in the buffer.


  75.5.3  Advancing the File I/O Buffer

When you reach the end of the file I/O buffer, you must advance the buffer to fill it from the disk (if you are reading), and flush it to the disk (if you are writing). Use the mmioAdvance function to advance a file I/O buffer.

The mmioAdvance function advances the buffer by (pchNext − cchBuffer) bytes. All data in the buffer before pchNext is assumed to have been read already, while all data from pchNext to pchEndRead will be considered unread. So, when mmioAdvance is called, all data before pchNext will be overwritten. The buffer must not be treated as an array and pchNext must be incremented until pchNext equals pchEndRead.

»This illustration« shows how the file I/O buffer is advanced as a file is read or written.

»This illustration« continues the example.


  75.5.3.1  Using the mmioAdvance Function

To fill a file I/O buffer from disk, call mmioAdvance with the MMIO_READ flag. If there is not enough data remaining in the file to fill the buffer, the pchEndRead member in the MMIOINFO structure points to the location following the last valid byte in the buffer.

To flush a buffer to disk, first set the MMIO_DIRTY flag in the dwFlags member of the MMIOINFO structure. Then call mmioAdvance with the MMIO_WRITE flag.


  75.5.4  Example of Accessing a File I/O Buffer

The following example is based on the ReversePlay example function discussed earlier in this chapter. In this example, direct-buffer access is used to read waveform data from a file.

HMMIO    hmmio;

MMIOINFO mmioinfo;

DWORD    dwDataSize;

DWORD    dwCount;

HPSTR    hptr;

    .

    .

    .

/* Get information on the file I/O buffer. */

if (mmioGetInfo(hmmio, &mmioinfo, 0)) {

    Error("Failed to get I/O buffer info");

    mmioClose(hmmio, 0);

    return FALSE;

}

/*

 * Read the entire file by directly reading the file I/O buffer.

 * When the end of the I/O buffer is reached, advance the buffer.

 */

for (dwCount = dwDataSize, hptr = lpData; dwCount > 0; dwCount--) {

    /* Check to see if the I/O buffer must be advanced. */

    if (mmioinfo.pchNext == mmioinfo.pchEndRead) {

        if(mmioAdvance(hmmio, &mmioinfo, MMIO_READ)) {

            Error("Failed to advance buffer.");

            mmioClose(hmmio, 0);

            return FALSE;

        }

    }

    /* Get a character from the buffer. */

    *hptr++ = *mmioinfo.pchNext++;

}

/* End direct buffer access and close the file. */

mmioSetInfo(hmmio, &mmioinfo, 0);

mmioClose(hmmio, 0);


  75.5.5  Ending Direct Access of a File I/O Buffer

When you finish accessing a file I/O buffer, pass the MMIOINFO structure filled by the mmioGetInfo function to the mmioSetInfo function to stop direct-buffer access. If you wrote to the buffer, set the MMIO_DIRTY flag in the dwFlags member of the MMIOINFO structure before calling mmioSetInfo. Otherwise, the buffer will not be flushed to disk.


  75.6  Performing File Input/Output on Memory Files

The multimedia file I/O services let you to treat a block of memory as a file. This can be useful if you already have a file image in memory. Memory files let you reduce the number of special-case conditions in your code because, for I/O purposes, you can treat file memory images as if they were disk-based files. You can also use memory files with the Clipboard.


  75.6.1  Opening Memory Files

Like I/O buffers, memory files can use memory allocated by the application or by the file I/O manager. In addition, memory files can be either expandable or non-expandable. When the file I/O manager reaches the end of an expandable memory file, it expands the memory file by a predefined increment.

To open a memory file, use mmioOpen with the szFileName parameter set to NULL and the MMIO_READWRITE flag set in the dwOpenFlags parameter. Set the lpmmioinfo parameter to point to an MMIOINFO structure as follows:

•	Set the pIOProc member to NULL.

•	Set the fccIOProc member to FOURCC_MEM.

•	Set the pchBuffer member to point to the memory block. To request that the file I/O manager allocate the memory block, set pchBuffer to NULL.

•	Set the cchBuffer member to the initial size of the memory block.

•	Set the adwInfo[0] member to the minimum expansion size of the memory block. For a non-expandable memory file, set adwInfo[0] to NULL.

•	Set all other members to zero.


  75.6.1.1  Allocating Memory for Memory Files

There are no restrictions on allocating memory for use as a non-expandable memory file. You can use static memory or stack memory, or you can use locally allocated or globally allocated memory. For expandable memory files, you must use memory allocated using the GlobalAlloc function and locked using the GlobalLock function.


  75.7  Using Custom Input/Output Procedures

Multimedia file I/O services use I/O procedures to handle the physical input and output associated with reading and writing to different types of storage systems, such as file-archival systems and database-storage systems. There are predefined I/O procedures for standard Microsoft Windows files and for memory files. In the future, there will be a predefined I/O procedure for accessing elements of compound files. Compound files consist of a number of individual files, called file elements, bound together in one physical file.

You can supply a custom I/O procedure for accessing a unique storage system such as a database or file archive. This I/O procedure can be private to your application or it can be shared with other applications.

The multimedia file I/O services provide the following functions to support custom I/O procedures:

Function	Description
mmioInstallIOProc	Installs, removes, or locates an I/O procedure.
mmioSendMessage	Sends a custom message to the I/O procedure associated with a file.


  75.7.1  Opening a File Using a Custom I/O Procedure

Before learning about how to write an I/O procedure, it's helpful to understand how to use one. To open a file using a custom I/O procedure, use the mmioOpen function as you would to open any other file. Use a plus sign (+) in the filename to separate the name of the physical file from the name of the element of the file you want to open. For example, the following statement opens a file element named "element" from a file named filename.arc:

mmioOpen("filename.arc+element", NULL, MMIO_READ);

When the file I/O manager encounters a plus sign in a filename, it looks at the preceding filename extension to determine which I/O procedure to associate with the file. In the previous example, the file I/O manager will attempt to use the I/O procedure associated with the .ARC filename extension. If no I/O procedure is installed, the mmioOpen function returns an error.


  75.7.2  Writing an I/O Procedure

An I/O procedure is a message-processing function supplied by an application. An I/O procedure function has the following syntax:

LRESULT IOProc(lpmmioinfo, wMsg, lParam1, lParam2)

The lpmmioinfo parameter specifies a pointer to an MMIOINFO structure associated with the file being accessed.

The wMsg parameter is of type UINT and specifies the message being sent by the file I/O manager to the I/O procedure.

The lParam1 parameter is of type LPARAM and specifies 32 bits of message-dependent information.

The lParam2 parameter is of type LPARAM and specifies 32 bits of message-dependent information.

The return value is message-dependent. If the I/O procedure does not recognize a message, it should return zero.


  75.7.2.1  I/O Procedure Messages

I/O procedures must respond to the MMIOM_CLOSE, MMIOM_OPEN, MMIOM_READ, MMIOM_WRITE, MMIOM_SEEK, MMIOM_RENAME, and MMIOM_WRITEFLUSH messages. Each of these messages has two parameters.

You can also create custom messages and send them to your I/O procedure using the mmioSendMessage function. If you define your own messages, be sure they are defined at or above the MMIOM_USER message. For example, the following example defines a message named MMIOM_MYMESSAGE:

#define   MMIOM_MYMESSAGE         MMIOM_USER + 0


  75.7.2.2  Using the MMIOINFO Structure

In addition to processing messages, an I/O procedure must maintain the lDiskOffset member in the MMIOINFO structure referenced by the lpmmioinfo parameter. The lDiskOffset member must always contain the file offset to the location that the next MMIOM_READ or MMIOM_WRITE message will access. The offset is specified in bytes and is relative to the beginning of the file. The I/O procedure can use the adwInfo[] member to maintain any required state information. The I/O procedure should not modify any other members in the MMIOINFO structure.


  75.7.3  Installing an I/O Procedure

Use mmioInstallIOProc to install, remove, or locate an I/O procedure.

For example, to install an I/O procedure associated with the filename extension ARC, use the following statement:

mmioInstallIOProc (mmioFOURCC('A', 'R', 'C', ' '),

                   (LPMMIOPROC)lpmmioproc, MMIO_INSTALLPROC);

Note   Be sure to remove any I/O procedures you've installed before closing your application.


  75.7.3.1  Installing an I/O Procedure Using MmioOpen

When you install an I/O procedure by using the mmioInstallIOProc function, the procedure remains installed until you remove it. The I/O procedure will be used for any file you open if the file has the appropriate filename extension. You can also temporarily install an I/O procedure by using the mmioOpen function. In this case, the I/O procedure is only used with a file opened by mmioOpen and is removed when the file is closed by using the mmioClose function.

To specify an I/O procedure when you open a file using mmioOpen, use the lpmmioinfo parameter to reference an MMIOINFO structure as follows:

•	Set the fccIOProc member to NULL.

•	Set the pIOProc member to the procedure-instance address of the I/O procedure.

•	Set all other members to zero (unless you are opening a memory file, or directly reading or writing to the file I/O buffer).


  75.7.4  Sharing an I/O Procedure With Other Applications

To share an I/O procedure with other applications, follow these guidelines:

•	Put the code for the I/O procedure in a dynamic-link library (DLL).

•	Create a function in the DLL that calls the mmioInstallIOProc function to install the I/O procedure.

•	Export this function in the module-definition file of the DLL.

To use the shared I/O procedure, an application must first call the function in the DLL to install the I/O procedure.


Common Dialog Box Library
  Chapter 76    Common Dialog Box Library

76.1  About Common Dialog Boxes

Common dialog boxes make it easier to develop applications for the Microsoft Windows operating system. A common dialog box is a dialog box an application displays by calling a single function rather than by supplying a dialog box procedure and a resource file containing a dialog box template. The dynamic-link library COMDLG32.DLL provides a default procedure and a template for each type of common dialog box. Each default dialog box procedure processes messages and notifications for a common dialog box and its controls. A default dialog box template defines the appearance of a common dialog box and its controls.

Common dialog boxes, in addition to simplifying the development of Windows applications, are helpful to users because they provide a standard set of controls for performing certain operations. As Windows developers begin using common dialog boxes in their applications, users will find that after they master common dialog boxes in one application, they can easily perform the same operations in other applications.

This chapter describes the various common dialog boxes and includes example code to help you use common dialog boxes in your Windows-based applications.

Following are the types of common dialog boxes in the order in which they are presented in this chapter:

Name	Description
Color	Displays available colors as well as controls that allow the user to define custom colors.
Font	Displays lists of fonts and point sizes that correspond to available fonts; after the user selects a font, the dialog box displays sample text rendered with that font.
Open	Displays a list of filenames matching any specified extensions, directories, and drives. By selecting one of the listed filenames, the user indicates the file an application should open.
Save As	Displays a list of filenames matching any specified extensions, directories, and drives. By selecting one of the listed filenames, the user indicates the file an application should save.
Print	Displays information about the installed printer and its configuration. By altering and selecting controls in this dialog box, the user specifies how output should be printed and starts the printing process.
Print Setup	Displays the current printer configuration and provides options for setting the paper orientation, size, and source (when the printer driver supports these options). The Print Setup dialog box can be called directly, or opened from within the Print dialog box.
Find	Displays an edit control in which the user can type a string for which the application should search. The user can specify the direction of the search, whether the application should match the case of the specified string, and whether the string to match is an entire word.
Replace	Displays two edit controls in which the user can type strings: The first string identifies a word or value that the application should replace, and the second string identifies the replacement word or value.


  76.1.1  The Color Dialog Box

The Color dialog box contains controls that enable a user to select and create colors.

»This illustration« shows a Color dialog box.

The Basic Colors control displays up to 48 colors. The actual number of colors displayed is determined by the display driver. For example, a VGA driver displays 48 colors, and a monochrome display driver displays only 16. With the Basic Colors control, the user can select a displayed color.

To display the Custom Colors control, the user clicks the Define Custom Colors button. The Custom Colors control displays custom colors. The user can select one of the 16 rectangles in this control and then create a new color by using one of the following methods:

•	Specifying red, green, and blue (RGB) values by using the Red, Green, and Blue edit controls, and then choosing the Add to Custom Colors button to display the new color in the selected rectangle.

•	Moving the cursor in the color spectrum control (at the upper right of the dialog box) to select hue and saturation values; moving the cursor in the luminosity control (the rectangle to the right of the spectrum control); and then choosing the Add to Custom Colors button to display the new color in the selected rectangle.

•	Specifying hue, saturation, and luminosity (HSL) values by using the Hue, Sat, and Lum edit controls and then choosing the Add to Custom Colors button to display the new color in the selected rectangle.

The Color|Solid control displays the dithered and solid colors that correspond to the user's selection. (A dithered color is a color created by combining one or more pure or solid colors.) The Flags member of the CHOOSECOLOR structure contains a flag bit that, when set, displays a Help button.

An application can display the Color dialog box in one of two ways: fully open or partially open. When the Color dialog box is displayed partially open, the user cannot change the custom colors.


  76.1.1.1  Color Models Used by the Color Dialog Box

The Color dialog box uses two models for specifying colors: the RGB model and the HSL model. Regardless of the model used, internal storage is accomplished by use of the RGB model.

RGB Color Model

The RGB model is used to designate colors for displays and other devices that emit light. Valid red, green, and blue values are in the range 0 through 255, with 0 indicating minimum intensity and 255 indicating maximum intensity. »This illustration« shows how the primary colors red, green, and blue can be combined to produce four additional colors. (With display devices, the color black results when the red, green, and blue values are set to 0; in display technology, black is the absence of all colors.)

Following are eight colors and their associated RGB values.

Color	RGB values
Red	255, 0, 0
Green	0, 255, 0
Blue	0, 0, 255
Cyan	0, 255, 255
Magenta	255, 0, 255
Yellow	255, 255, 0
White	255, 255, 255
Black	0, 0, 0
Windows stores internal colors as 32-bit RGB values. The high-order byte of the high-order word is reserved; the low-order byte of the high-order word specifies the intensity of the blue component; the high-order byte of the low-order word specifies the intensity of the green component; and the low-order byte of the low-order word specifies the intensity of the red component.

HSL Color Model

The Color dialog box provides controls for specifying HSL values. »This illustration« shows the color spectrum control and the vertical luminosity control that appear in the Color dialog box and shows the ranges of values the user can specify with these controls.

In the Color dialog box, the saturation and luminosity values must be in the range 0 through 240 and the hue value must be in the range 0 through 239.

Converting HSL Values to RGB Values

The dialog box procedure provided in COMDLG32.DLL for the Color dialog box contains code that converts HSL values to the corresponding RGB values. Following are several colors and their associated HSL and RGB values:

Color	HSL values	RGB values
Red	(0, 240, 120)	(255, 0, 0)
Yellow	(40, 240, 120)	(255, 255, 0)
Green	(80, 240, 120)	(0, 255, 0)
Cyan	(120, 240, 120)	(0, 255, 255)
Blue	(160, 240, 120)	(0, 0, 255)
Magenta	(200, 240, 120)	(255, 0, 255)
White	(0, 0, 240)	(255, 255, 255)
Black	(0, 0, 0)	(0, 0, 0)


  76.1.2  The Font Dialog Box

The Font dialog box contains controls that allow a user to choose a font, a font style (such as bold, italic, or regular), a point size, and an effect (such as underline, strikeout, or a text color).

»This illustration« shows a Font dialog box.


  76.1.3  The Open and Save As Dialog Boxes

The Open dialog box and the Save As dialog box are similar in appearance. Each contains controls that enable a user to specify the location and name of a file or a set of files. In the case of the Open dialog box, the user selects the file or files to be opened; in the case of the Save As dialog box, the user selects the file or files to be saved.

»This illustration« shows an Open dialog box.

»This illustration« shows a Save As dialog box.


  76.1.4  The Print and Print Setup Dialog Boxes

A Print dialog box contains controls that allow a user to configure a printer for a particular print job. The user can make such selections as print quality, page range, and number of copies (if the printer supports multiple copies).

»This illustration« shows a Print dialog box.

Choosing the Setup button in the Print dialog box displays the Print Setup dialog box for a PostScript printer, as shown in »this illustration«.

The Print Setup dialog box provides controls that enable the user to reconfigure the selected printer.


  76.1.4.1  Device Drivers and the Print Dialog Box

The Print dialog box differs from other common dialog boxes in that part of its dialog box procedure resides in COMDLG32.DLL and part in a printer driver. A printer driver is a program that configures a printer, converts graphics device interface (GDI) commands to low-level printer commands, and stores commands for a particular print job in a printer's queue.

A printer driver exports a function called ExtDeviceMode that displays a dialog box and its controls. In previous versions of Windows, an application called the LoadLibrary function to load a device driver and the GetProcAddress function to obtain the address of the ExtDeviceMode function. This is no longer necessary with the Windows common dialog box interface. Instead of calling LoadLibrary and GetProcAddress, a Windows application can call a single function, PrintDlg, to display the Print dialog box and begin a print job. The code for PrintDlg resides in COMDLG32.DLL. The dialog box that appears when an application calls PrintDlg differs slightly from the dialog box that appears when the application calls directly into the device driver. The functionality is very similar in spite of the different appearance.


  76.1.5  The Find and Replace Dialog Boxes

The Find dialog box and the Replace dialog box are similar in appearance. You can use the Find dialog box to add string-search capabilities to your application and the Replace dialog box to add both string-search and string-substitution capabilities.

The Find and the Replace dialog boxes differ from the other common dialog boxes in that they are modeless. This means the user can switch between the dialog box and the window that created that dialog box.

»This illustration« shows the Find dialog box.

»This illustration« shows the Replace dialog box.


  76.2  Using the Common Dialog Boxes

This section explains how to perform the following tasks:

•	Set the required stack size for applications using common dialog boxes.

•	Display the Color dialog box so the user can select basic colors.

•	Display the Color dialog box so the user can select custom colors.

•	Display the Font dialog box so the user can select a font, a point size, and a text color.

•	Display the Open dialog box so the user can specify the name of a file to be opened.

•	Display the Save As dialog box so the user can specify the name of the file to be saved.

•	Display the Print dialog box so the user can configure a printer before printing a job.

•	Display the Find dialog box so the user can specify a string of text to be found in a document or file.

•	Display the Replace dialog box so the user can specify a string of text to be replaced (as well as the replacement string).

•	Customize a common dialog box.


  76.2.1  Setting the Required Stack Size

Applications using the common dialog boxes should specify at least 8K for the stack size, as shown in the following example:

NAME         Generic

DESCRIPTION  'Sample Application for Microsoft Windows'

EXETYPE      WINDOWS

STUB         'WINSTUB.EXE'

CODE  PRELOAD MOVEABLE DISCARDABLE

DATA  PRELOAD MOVEABLE MULTIPLE

HEAPSIZE     1024

STACKSIZE    8192 ; increased stack size for common dialog boxes

EXPORTS

        MainWndProc   @1

        About         @2


  76.2.2  Using the Color Dialog Box to Display Basic Colors

You can have your application display the Color dialog box so a user can select one color from a list of basic screen colors. This section describes how you can provide code and structures in your application that make this possible.


  76.2.2.1  Initializing the CHOOSECOLOR Structure

Before displaying a Color dialog box, an application must initialize a CHOOSECOLOR structure. This structure should be global or declared as a static variable. The members of this structure contain information about such items as the following:

•	Structure size

•	Which window owns the dialog box

•	Whether the application is customizing the common dialog box

•	The hook function and custom dialog box template to use for a customized version of the Color dialog box

•	RGB values for the selected basic color

If your application does not customize the dialog box and you want the user to be able to select a single color from the basic colors, initialize the CHOOSECOLOR structure in the following manner:

/* Color variables */

CHOOSECOLOR cc;     /* common dialog box structure */

COLORREF acrCustClr[16] = { RGB(255, 255, 255), RGB(239, 239, 239),

                            RGB(223, 223, 223), RGB(207, 207, 207),

                            RGB(191, 191, 191), RGB(175, 175, 175),

                            RGB(159, 159, 159), RGB(143, 143, 143),

                            RGB(127, 127, 127), RGB(111, 111, 111),

                            RGB(95, 95, 95), RGB(79, 79, 79),

                            RGB(63, 63, 63), RGB(47, 47, 47),

                            RGB(31, 31, 31), RGB(15, 15, 15)

                           }; /* array of gray colors */

                    /* Initialize necessary members. */

                    cc.lStructSize = sizeof(CHOOSECOLOR);

                    cc.hwndOwner = hwnd;

                    cc.lpCustColors = (LPDWORD) acrCustClr;

                    cc.Flags = CC_PREVENTFULLOPEN;

                    /* Call the ChooseColor function. */

                    if (ChooseColor(&cc)){

.

.   /* Use cc.lpCustColors to select the user's requested color. */

.

                    }

In the previous example, the array pointed to by the lpCustColors member contains 16 doubleword RGB values that specify the color white, and the CC_PREVENTFULLOPEN flag is set in the Flags member to disable the Define Custom Colors button and prevent the user from selecting a custom color.


  76.2.2.2  Calling the ChooseColor Function

After you initialize the structure, call the ChooseColor function. If the function succeeds and the user chooses the OK button to close the dialog box, the rgbResult member contains the RGB values for the basic color the user selected.


  76.2.3  Using the Color Dialog Box to Display Custom Colors

You can have your application display the Color dialog box so the user can create and select a custom color. This section describes how you can provide code and structures in your application that make this possible.


  76.2.3.1  Initializing the CHOOSECOLOR Structure

Before displaying a Color dialog box, an application must initialize a CHOOSECOLOR structure. This structure should be global or declared as a static variable. The members of this structure contain information about such items as the following:

•	Structure size

•	Which window owns the dialog box

•	Whether the application is customizing the common dialog box

•	The hook function and custom dialog box template to use for a customized version of the Color dialog box

•	RGB values for the custom color control

If your application does not customize the dialog box and you want the user to be able to create and select custom colors, initialize the CHOOSECOLOR structure in the following manner.

/* Color variables */

CHOOSECOLOR cc;     /* common dialog box structure */

COLORREF acrCustClr[16] = { RGB(255, 255, 255), RGB(239, 239, 239),

                            RGB(223, 223, 223), RGB(207, 207, 207),

                            RGB(191, 191, 191), RGB(175, 175, 175),

                            RGB(159, 159, 159), RGB(143, 143, 143),

                            RGB(127, 127, 127), RGB(111, 111, 111),

                            RGB(95, 95, 95), RGB(79, 79, 79),

                            RGB(63, 63, 63), RGB(47, 47, 47),

                            RGB(31, 31, 31), RGB(15, 15, 15)

                           }; /* array of gray colors */

                    /* Initialize the necessary members. */

                    cc.lStructSize = sizeof(CHOOSECOLOR);

                    cc.hwndOwner = hwnd;

                    cc.lpCustColors = (LPDWORD) acrCustClr;

                    cc.Flags = CC_FULLOPEN;

In the previous example, the array pointed to by lpCustColors contains sixteen 32-bit RGB values that specify 16 scales of gray, and the CC_FULLOPEN flag is set in the Flags member to display the complete Color dialog box.


  76.2.3.2  Calling the ChooseColor Function

After you initialize the structure, you should call ChooseColor, as shown in the following code:

                    /* Call the ChooseColor() function. */

                    if (ChooseColor(&cc)){

.

.   /* Use cc.lpCustColors to select the user's requested color. */

.

                    }

If the function succeeds and the user chooses the OK button to close the dialog box, the lpCustColors member points to an array that contains the RGB values for the custom colors requested by the user.

You can give your application more control over custom colors by creating a new message identifier for the string defined by the COLOROKSTRING constant. The application creates the new message identifier by calling the RegisterWindowMessage function and passing this constant as the single parameter. After calling RegisterWindowMessage, the application receives a message immediately before the dialog box closes. The lParam parameter of this message contains a pointer to the CHOOSECOLOR structure. The application can use the lpCustColors member of this structure to check the current color. If the application returns a nonzero value when it processes this message, the dialog box does not close.

Similarly, you can have your application create a new message identifier for the string defined by the SETRGBSTRING constant. The application's hook function can use the message identifier returned by calling RegisterWindowMessage with the SETRGBSTRING constant to set a color in the dialog box. For example, the following line of code sets the color selection to blue.

SendMessage(hwndDlg, wSetRGBMsg, 0, (LPARAM) RGB(0, 0, 255));

In this example, wSetRGBMsg is the message identifier returned by RegisterWindowMessage. The lParam parameter of the SendMessage function is set to the RGB values of the desired color. The wParam parameter is not used.

You can have your application specify any valid RGB values in this call to SendMessage. If the RGB values match one of the basic colors, the operating system selects the basic color and updates the spectrum and luminosity controls. If the RGB values do not match one of the basic colors, the system updates the spectrum and luminosity controls, but the basic color selection remains unchanged.

Note that if the Color dialog box is not fully open and the application sends RGB values that do not match one of the basic colors, the operating system does not update the dialog box. Updates are unnecessary because the spectrum and luminosity controls are not visible when the dialog box is only partially open.

For more information about processing registered window messages, see Section 76.2.10, »Displaying the Find Dialog Box«.


  76.2.4  Displaying the Font Dialog Box in Your Application

The Font dialog box appears after you initialize the members in a CHOOSEFONT structure and call the ChooseFont function. This structure should be global or declared as a static variable. The members of the CHOOSEFONT structure contain information about the following items:

•	The attributes of the font that initially appears in the dialog box.

•	The attributes of the font the user selected.

•	The point size of the font the user selected.

•	Whether the list of fonts corresponds to a printer, a screen, or both.

•	Whether the available fonts listed are TrueType only.

•	Whether the Effects box should appear in the dialog box.

•	Whether dialog box messages should be processed by an application-defined hook function.

•	Whether the point sizes of the selectable fonts should be limited to a specified range.

•	Whether the dialog box displays only what-you-see-is-what-you-get (WYSIWYG) fonts. (These fonts are resident on both the screen and the printer.)

•	The color ChooseFont uses to render text in the Sample box the first time the application displays the dialog box.

•	The color the user selected for text output.

To display the Font dialog box, include the following steps in your application:

1.	If the application requires printer fonts, retrieve a device-context (DC) handle for the printer and use this handle of set the hDC member of the CHOOSEFONT structure. (If the Font dialog box displays only screen fonts, this member should be set to NULL.)

2.	Set the appropriate flags in the Flags member of the CHOOSEFONT structure. This setting must include CF_SCREENFONTS, CF_PRINTERFONTS, or CF_BOTH.

3.	Set the rgbColors member of the CHOOSEFONT structure if the default color (black) is not appropriate.

4.	Set the nFontType member of the CHOOSEFONT structure by using the appropriate constant.

5.	Set the nSizeMin and nSizeMax members of the CHOOSEFONT structure if the CF_LIMITSIZE value is specified in the Flags member.

6.	Call the ChooseFont function.

The following example initializes the CHOOSEFONT structure structure, calls ChooseFont, and uses the requested font to draw text on the display.

/* Font variables */

CHOOSEFONT cf;      /* common dialog box structure  */

LOGFONT lf;         /* logical-font structure       */

HDC hdc;            /* display DC handle            */

HFONT hfont;        /* new logical-font handle      */

HFONT hfontOld;     /* original logical-font handle */

COLORREF crOld;     /* original text color          */

                    /* Initialize the necessary members. */

                    cf.lStructSize = sizeof (CHOOSEFONT);

                    cf.hwndOwner = hwnd;

                    cf.lpLogFont = &lf;

                    cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

                    cf.rgbColors = RGB(0, 255, 255);

                    cf.nFontType = SCREEN_FONTTYPE;

                    /*

                     * Display the dialog box, allow the user to

                     * choose a font, and render the text in the

                     * window with that selection.

                     */

                    if (ChooseFont(&cf)){

                        hdc = GetDC(hwnd);

                        hfont = CreateFontIndirect(cf.lpLogFont);

                        hfontOld = SelectObject(hdc, hfont);

                        crOld = SetTextColor(hdc, cf.rgbColors);

                        TextOut(hdc, 50, 150,

                            "AaBbCcDdEeFfGgHh", 16);

                        SetTextColor(hdc, crOld);

                        SelectObject(hdc, hfontOld);

                        DeleteObject(hfont);

                        ReleaseDC(hwnd, hdc);

                        }

An application can also use the WM_CHOOSEFONT_GETLOGFONT message to retrieve the current LOGFONT structure for the Font dialog box before the user closes the dialog box.


  76.2.5  Displaying the Open Dialog Box in Your Application

The Open dialog box appears after you initialize the members of an OPENFILENAME structure and call the GetOpenFileName function.

Before you call GetOpenFileName, structure members contain such data as the name of the directory and the filter that appears in the dialog box. (A filter is a filename extension. The common dialog box code uses the extension to filter appropriate filenames from a directory.) After the call, structure members contain such data as the name of the selected file and the number of characters in that filename.

To display an Open dialog box, include the following steps in your application:

1.	Store the valid filters in a character array.

2.	Set the lpstrFilter member to point to this array.

3.	Set the nFilterIndex member to the value of the index that identifies the default filter.

4.	Set the lpstrFile member to point to an array that contains the initial filename and receives the selected filename.

5.	Set the nMaxFile member to the value that specifies the length of the filename array.

6.	Set the lpstrFileTitle member to point to a buffer that receives the title of the selected file.

7.	Set the nMaxFileTitle member to specify the length of the buffer.

8.	Set the lpstrInitialDir member to point to a string that specifies the initial directory. (If this member does not point to a valid string, it must be set to 0 or point to a string set to NULL.)

9.	Set the lpstrTitle member to point to a string specifying the name that appears in the title bar of the dialog box. (If this pointer is NULL, the title is Open.)

10.	Initialize the lpstrDefExt member to point to the default extension. (This extension can be 0, 1, 2, or 3 characters long.)

11.	Call the GetOpenFileName function.

The following example initializes an OPENFILENAME structure, calls GetOpenFileName, and opens the file by using the lpstrFile member of the structure. The OPENFILENAME structure should be global or declared as a static variable.

OPENFILENAME ofn;       /* common dialog box structure   */

char szDirName[256];    /* directory string              */

char szFile[256];       /* filename string               */

char szFileTitle[256];  /* file-title string             */

char szFilter[256];     /* filter string                 */

char chReplace;         /* string separator for szFilter */

int i, cbString;        /* integer count variables       */

HANDLE hf;              /* file handle                   */

.

.

.

                    /*

                     * Retrieve the system directory name and

                     * store it in szDirName.

                     */

                     GetSystemDirectory(szDirName, sizeof(szDirName));

                    /* Place the terminating null character in the

                     * szFile.

                     */

                     szFile[0] = '\0';

                    /* Load the filter string from the .RC file. */

                     cbString = LoadString(hinst, IDS_FILTERSTRING,

                                    szFilter, sizeof(szFilter));

                    /*

                     * Add a terminating null character to the filter

                     * string.

                     */

                     chReplace = szFilter[cbString - 1];

                     for (i = 0; szFilter[i] != '\0'; i++){

                         if (szFilter[i] == chReplace)

                            szFilter[i] = '\0';

                        }

                    /* Set the members of the OPENFILENAME structure. */

                    ofn.lStructSize = sizeof(OPENFILENAME);

                    ofn.hwndOwner = hwnd;

                    ofn.lpstrFilter = szFilter;

                    ofn.nFilterIndex = 1;

                    ofn.lpstrFile = szFile;

                    ofn.nMaxFile = sizeof(szFile);

                    ofn.lpstrFileTitle = szFileTitle;

                    ofn.nMaxFileTitle = sizeof(szFileTitle);

                    ofn.lpstrInitialDir = szDirName;

                    ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |

                        OFN_FILEMUSTEXIST;

                    /* Display the Open dialog box. */

                    if (GetOpenFileName(&ofn)) {

                        /* Open the file. */

                        hf = CreateFile(ofn.lpstrFile, GENERIC_READ,

                                 0, (LPSECURITY_ATTRIBUTES) NULL,

                                 OPEN_EXISTING,

                                 FILE_ATTRIBUTE_NORMAL,

                                 (HANDLE) NULL);

.

.   /* Perform the necessary file operations. */

.

                        /* Close the file. */

                        CloseHandle(hf);

                       } /* end if */

The string referred to by the IDS_FILTERSTRING constant in the preceding example is defined as follows in the resource-definition file:

STRINGTABLE

BEGIN

    IDS_FILTERSTRING "Bitmap File(*.BMP)|*.bmp|"

END

The vertical bars in this string are used as wildcards. After the LoadString function is used to retrieve the string, the wildcards are replaced with NULL. The wildcard can be any unique character and must be included as the last character in the string. Initializing strings in this manner guarantees that the parts of the string are contiguous in memory and that the string is terminated with two null characters.

An application that can open files over a network can create a new message identifier for the string defined by the SHAREVISTRING constant. The application creates the new message identifier by calling the RegisterWindowMessage function and passing this constant as the single parameter. After calling RegisterWindowMessage, the application is notified whenever a sharing violation occurs during a call to the OpenFile function. For more information about processing registered window messages, see Section 76.2.10, »Displaying the Find Dialog Box«.


  76.2.6  Displaying the Save As Dialog Box in Your Application

The Save As dialog box appears after you initialize the members of an OPENFILENAME structure and call the GetSaveFileName function.

Before you call GetSaveFileName, structure members contain such data as the name of the initial directory and a filter string. After the call, structure members contain such data as the name of the file to be saved and the number of characters in that filename.

The following example initializes an OPENFILENAME structure, calls GetSaveFileName, and saves the file. The OPENFILENAME structure should be global or declared as a static variable.

OPENFILENAME ofn;       /* common dialog box structure   */

char szDirName[256];    /* directory string              */

char szFile[256];       /* filename string               */

char szFileTitle[256];  /* file-title string             */

char szFilter[256];     /* filter string                 */

char chReplace;         /* string separator for szFilter */

int i, cbString;        /* integer count variables       */

HANDLE hf;              /* file handle                   */

                    /*

                     * Retrieve the system directory name and

                     * store it in szDirName.

                     */

                     GetSystemDirectory(szDirName, sizeof(szDirName));

                    /* Place the terminating null character in

                     * szFile.

                     */

                     szFile[0] = '\0';

                    /* Load the filter string from the .RC file. */

                     cbString = LoadString(hinst, IDS_FILTERSTRING,

                         szFilter, sizeof(szFilter));

                    /*

                     * Add a terminating null character to the filter

                     * string.

                     */

                     chReplace = szFilter[cbString - 1];

                     for (i = 0; szFilter[i] != '\0'; i++){

                         if (szFilter[i] == chReplace)

                            szFilter[i] = '\0';

                        }

                    /* Set the members of the OPENFILENAME structure. */

                    ofn.lStructSize = sizeof(OPENFILENAME);

                    ofn.hwndOwner = hwnd;

                    ofn.lpstrFilter = szFilter;

                    ofn.nFilterIndex = 1;

                    ofn.lpstrFile = szFile;

                    ofn.nMaxFile = sizeof(szFile);

                    ofn.lpstrFileTitle = szFileTitle;

                    ofn.nMaxFileTitle = sizeof(szFileTitle);

                    ofn.lpstrInitialDir = szDirName;

                    ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;

                    /* Display the Save As dialog box. */

                    if (GetSaveFileName(&ofn)) {

.

.   /* Perform the necessary file operations. */

.

                        /* Close the file. */

                        CloseHandle(hf);

                       } /* end if */

The string referred to by the IDS_FILTERSTRING constant in the preceding example is defined in the resource-definition file. It is used in exactly the same way as the IDS_FILTERSTRING constant discussed in Section 76.2.5, »Displaying the Open Dialog Box in Your Application«.


  76.2.7  Monitoring List Box Controls in an Open or Save As Dialog Box

An application can monitor list box selections to process and display data in custom controls. For example, an application can use a custom control to display the total length, in bytes, of all files selected in the File Name box. One method the application can use to obtain this value is to recompute the total count of bytes each time the user selects a file or cancels the selection of a file. A faster method is for the application to use the LBSELCHSTRING message to identify a new selection and add the corresponding file length to the value that appears in the custom control. (Note that, in this example, the custom control is a standard Windows control that you identify in a resource file template for one of the common dialog boxes.)

An application registers the selection-change message with the RegisterWindowMessage function. After the application registers the message, it uses this function's return value to identify messages from the dialog box. The message is processed in the application-defined hook function for the common dialog box. The wParam parameter of each message identifies the list box in which the selection occurred. The low-order word of the lParam parameter identifies the list box item. The high-order word of the lParam parameter is one of the following values.

Value	Meaning
CD_LBSELCHANGE	The item identified by the low-order word of lParam was the item in a single-selection list box.
CD_LBSELSUB	The item identified by the low-order word of lParam is no longer selected in a multiple-selection list box.
CD_LBSELADD	The item identified by the low-order word of lParam was selected from a multiple-selection list box.
CD_LBSELNOITEMS	No items exist in a multiple-selection list box.
For an example that registers a common dialog box message, see Section 76.2.10, »Displaying the Find Dialog Box«.


  76.2.8  Monitoring Filenames in an Open or Save As Dialog Box

An application can alter the normal processing of an Open or Save As dialog box by monitoring the filename the user types and by performing other unique operations. For example, one application could prevent the user from closing the dialog box if the selected filename is prohibited; another application could enable the user to select multiple filenames.

To monitor filenames, register the FILEOKSTRING message. Do this by calling the RegisterWindowMessage function and passing the message name as its single parameter. After the message has been registered, the dialog box procedure in COMDLG32.DLL uses it to signal that the user has selected a filename and chosen the OK button and that the dialog box has checked the filename and is ready to return. The dialog box procedure signals these actions by sending the message to the application's hook function. After receiving the message, the hook function should return a value to the dialog box procedure that called it. If the hook function did not process the message, it should return 0; if the hook function did process the message and the dialog box should close, the hook function should return 0; if the hook function did process the message but the dialog box should not close, the hook function should return 1. All other return values are reserved.


  76.2.9  Displaying a Print Dialog Box for the Default Printer

To display a Print dialog box for the default printer, initialize a PRINTDLG structure and then call the PrintDlg function.

The members of the PRINTDLG structure can contain information about the following items:

•	The printer device context

•	Values that should appear in the dialog box controls

•	The hook function and custom dialog box template to use for a customized version of the Print dialog box or Print Setup dialog box

To display a Print dialog box for the currently installed printer, include the following steps in your application:

1.	Set the PD_RETURNDC flag in the Flags member of the PRINTDLG structure. (This flag should be set only if the application requires a device-context handle.)

2.	Initialize the lStructSize, hDevMode, and hDevNames members.

3.	Call the PrintDlg function and pass a pointer to the PRINTDLG structure just initialized.

Setting the PD_RETURNDC flag causes PrintDlg to display the Print dialog box and return a handle identifying a printer device context in the hDC member of the PRINTDLG structure. (The application passes the device-context handle as the first parameter to the graphics device interface (GDI) functions that render output on the printer.)


  76.2.10  Displaying the Find Dialog Box

The Find dialog box contains controls that allow a user to specify the following:

•	The string that the application should find

•	Whether the string specifies a complete word or part of a word

•	Whether the application should match the case of the specified string

•	The direction the application should search (preceding or following the current cursor location)

•	Whether the application should resume the search, searching for the next occurrence of the string

To display the Find dialog box, initialize a FINDREPLACE structure and call the FindText function. Members of the FINDREPLACE structure contain information about the following items:

•	Which window owns the dialog box

•	How the application should perform the search

•	A character buffer to receive the string

To initialize the FINDREPLACE structure, perform the following tasks:

1.	Set the lStructSize member by using the sizeof operator.

2.	Set the hwndOwner member by using the handle that identifies the owner window of the dialog box.

3.	If you are customizing the Find dialog box, set the hInstance member to identify the instance of the module that contains your custom dialog box template.

4.	Set the Flags member to indicate the selection state of the dialog box options. (For example, setting the FR_NOUPDOWN flag disables the Up and Down buttons, setting the FR_NOWHOLEWORD flag disables the Match Whole Word Only check box, and setting the FR_NOMATCHCASE flag disables the Match Case check box.)

5.	If you are supplying a custom dialog box template or hook function, set additional flags in the Flags member.

6.	Set the lpstrFindWhat member to point to the buffer receiving the string to be found.

7.	Set the wFindWhatLen member to specify the size, in bytes, of the buffer pointed to by lpstrFindWhat.

8.	Set the lCustData member with any custom data your application may need to access.

9.	If your application customizes the Find dialog box, set the lpfnHook member to point to your hook function.

10.	If your application uses a custom dialog box template, set the lpTemplateName member to point to the string that identifies the template.

The following example initializes the FINDREPLACE structure and then calls FindText. This structure should be global or declared as a static variable.

/* Find/Replace variables */

FINDREPLACE fr;         /* common dialog box structure            */

FINDREPLACE FAR* lpfr;  /* pointer to common dialog box structure */

CHAR szFindWhat[80];    /* buffer receiving string to be found    */

HWND hdlg;              /* handle identifying dialog window       */

UINT uFindReplaceMsg;   /* value returned by RegisterMessage()    */

                    /* Initialize the necessary members. */

                    fr.lStructSize = sizeof(FINDREPLACE);

                    fr.hwndOwner = hwnd;

                    fr.lpstrFindWhat = szFindWhat;

                    fr.wFindWhatLen = sizeof(szFindWhat);

                    /* Display the modeless Find dialog box. */

                    hdlg = FindText(&fr);


  76.2.11  Displaying the Replace Dialog Box

The Replace dialog box is similar to the Find dialog box. However, the Replace dialog box has no Direction check box and has three additional controls that enable the user to specify the following:

•	The replacement string

•	Whether the application should replace the occurrence of the string currently highlighted

•	Whether the application should replace all occurrences of the string

To display the Replace dialog box, initialize a FINDREPLACE structure and call the ReplaceText function.


  76.2.12  Processing Dialog Box Messages for a Find or Replace Dialog Box

The Find and Replace dialog boxes differ from the other common dialog boxes in two respects: First, they are modeless; and second, their respective dialog box procedures send messages to the application that calls the FindText or ReplaceText function. These messages contain data specified by the user in the dialog box controls, such as the direction the application should search for a string, whether the application should match the case of the specified string, and whether the application should match the entire string.

To process messages from a Find or Replace dialog box, an application must register the dialog box's unique message, FINDMSGSTRING.

The application registers this message with the RegisterWindowMessage function. After the application registers the message, it uses the function's return value to identify messages from the Find or Replace dialog box. The following example registers the message with RegisterWindowMessage:

/* Register the FindReplace message. */

uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);

After the application registers this message, it can process messages for the Find or Replace dialog box by using the RegisterWindowMessage return value. The following example processes messages for the Find dialog box and then calls its own SearchFile function to locate the string of text. If the user is closing the dialog box (that is, if the Flags member of the FINDREPLACE structure is FR_DIALOGTERM), the handle is invalidated and the procedure returns zero.

if (message == uFindReplaceMsg){

    /*

     * Extract a pointer to the FINDREPLACE

     * structure from lParam.

     */

     lpfr = (FINDREPLACE FAR*) lParam;

    /*

     * If the system has set the FR_DIALOGTERM

     * flag, invalidate the handle identifying

     * the dialog box.

     */

     if (lpfr->Flags & FR_DIALOGTERM){

        hdlg = NULL;

        return 0;

        }

    /*

     * If the dialog box is still valid, call the

     * application-defined search routine (SearchFile) to

     * search for the requested string.

     */

     SearchFile((BOOL) (lpfr->Flags & FR_DOWN),

        (BOOL) (lpfr->Flags & FR_MATCHCASE));

     return 0;

     }


  76.3  Customizing Common Dialog Boxes

A custom common dialog box is a common dialog box altered to suit a particular Windows-based application. The customization may be complex and include the hiding of original controls, the addition of new controls, or a change in the size of the original dialog box; or it may be simple, involving the alteration of a single existing control.

If you want to customize a common dialog box, you must provide a special hook function and, in most cases, a custom dialog box template. Customizations of this kind require a significant amount of additional code — displaying a customized common dialog box is not as simple as initializing the members of a structure and calling a single function.

Applications that subclass controls in any of the common dialog boxes must do so while processing the WM_INITDIALOG message in the application's hook function. This allows the application to receive the control-specific messages first, because it will have subclassed the control after the common dialog box has installed its subclassing procedures. (The previous hook function should be called for all messages not handled by the application's subclass function, as is standard for subclassing.)

An application cannot subclass a control by defining a local class to override a specific control type. This is because the data segment would not be initialized correctly when the class was called — the data segment would be the common dialog box's data segment, not the application's data segment.


  76.3.1  Appropriate and Inappropriate Customizations

From the user's perspective, the chief benefit of the common dialog box is its consistent appearance and functionality from application to application. Therefore, it becomes important that you customize a common dialog box only when it is absolutely necessary for an application. Otherwise, the consistent appearance and simple coding interface are lost. Appropriate customizations leave intact as many of the original controls as possible. Increasing the size of the dialog box or adding new controls in available space that already appears in the dialog box would be an appropriate customization. Hiding original controls or otherwise changing the intended functionality of the original controls would be less appropriate customization.


  76.3.2  Hook Functions and Custom Dialog Box Templates

Each common dialog box uses the dialog box procedure and dialog box template provided for it in COMDLG32.DLL. The dialog box procedure processes messages and notifications for the common dialog box and its controls. The dialog box template defines the appearance of the dialog box — its dimensions, its location, and the dimensions and locations of controls that appear within it.

In addition to the procedure and template provided, a custom dialog box requires a hook function that you provide and, usually, a custom version of the dialog box template.


  76.3.2.1  The Hook Function

The dialog box procedure provided in COMDLG32.DLL for a common dialog box calls the application's hook function if the application sets the appropriate flag and pointer in the structure for that common dialog box. The structure for each common dialog box contains a Flags member that specifies whether the application defines a hook function and contains an lpfnHook member that points to the hook function, if one exists. If the application sets the Flags member to indicate that a hook function exists, it must also set the lpfnHook member. The following example sets the Flags and lpfnHook members of an OPENFILENAME structure to support an application's hook function.

#include <windows.h>    /* required for all Windows applications        */

#include <commdlg.h>    /* required for all common dialog box functions */

#include <dlgs.h>

#include "generic.h"    /* specific to this application                 */

OPENFILENAME ofn;       /* common dialog box structure       */

char szDirName[256];    /* directory string                  */

char szFile[256];       /* filename string                   */

char szFileTitle[256];  /* file-title string                 */

char szFilter[256];     /* filter string                     */

char chReplace;         /* string separator for szFilter     */

int i, cbString;        /* integer count variables           */

DWORD cBufLen;          /* dword count                       */

DWORD cTmp;             /* dword count                       */

HANDLE hf;              /* original file handle              */

HANDLE hfBackup;        /* backup file handle                */

char szBuffer[256];     /* character buffer                  */

char szChar[256];       /* character buffer                  */

char* pszBackupFile;    /* pointer to backup filename        */

BOOL fBackup;           /* TRUE if user checked "backup" box */

/* Retrieve the system directory name. */

GetSystemDirectory((LPSTR)szDirName, sizeof(szDirName));

/* Place the terminating null character in the szFile. */

szFile[0] = '\0';

/* Load the filter string from the .RC file. */

cbString = LoadString(hinst, IDS_FILTERSTRING,

               szFilter, sizeof(szFilter));

/* Add a terminating null character to the string. */

chReplace = szFilter[cbString - 1];

for (i = 0; szFilter[i] != '\0'; i++) {

    if (szFilter[i] == chReplace)

        szFilter[i] = '\0';

    }

/* Initialize the required OPENFILENAME members. */

ofn.lStructSize = sizeof(OPENFILENAME);

ofn.hwndOwner = hwnd;

ofn.hInstance = hinst;

ofn.lpstrFilter = szFilter;

ofn.nFilterIndex = 1;

ofn.lpstrFile = szFile;

ofn.nMaxFile = sizeof(szFile);

ofn.lpstrFileTitle = szFileTitle;

ofn.nMaxFileTitle = sizeof(szFileTitle);

ofn.lpstrInitialDir = szDirName;

ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |

            OFN_FILEMUSTEXIST | OFN_ENABLEHOOK |

            OFN_ENABLETEMPLATE;

ofn.lpfnHook = FileOpenHookProc;

ofn.lpTemplateName = "FILEOPEN";

In the previous example, the address of the application-defined hook function is assigned to the lpfnHook member of the OPENFILENAME structure. The hook function processes any messages or notifications the custom dialog box requires. With the exception of one message (WM_INITDIALOG), the hook function receives messages and notifications before the dialog box procedure provided in COMDLG32.DLL receives them. In the case of WM_INITDIALOG, the hook function receives the message after the dialog box procedure. When the hook function finishes processing a message, it returns a value that indicates whether the dialog box procedure provided in COMDLG32.DLL should also process the message. If the dialog box procedure should process the message, the return value is FALSE; if the dialog box procedure should ignore the message, the return value is TRUE.

To process the message from the OK button after the dialog box procedure processes it, an application must post a message to itself when the OK message is received. When the application receives the message it has posted, the common dialog box procedure will have finished processing messages for the dialog box. This technique is particularly useful when working with the Find and Replace dialog boxes, because the Flags member of the FINDREPLACE structure does not reflect changes to the dialog box until after the messages have been processed by COMDLG32.DLL.

The following example shows a hook function for a custom Open dialog box.

UINT FAR PASCAL FileOpenHookProc(HWND hdlg, UINT msg, WPARAM wParam,

    LPARAM lParam)

{

    switch (msg) {

        case WM_INITDIALOG: /* Received <after> commdlg is processed. */

            return TRUE;

        case WM_COMMAND:

            /* Use IsDlgButtonChecked to set lCustData. */

            if (wParam == IDOK)

                /* Set the "backup file" flag. */

                fBackup = (DWORD) IsDlgButtonChecked(hdlg, ID_CUSTCHX);

            return FALSE; /* Allow standard processing. */

            break;

        default:

            return FALSE;

    } /* end switch */

    return FALSE;

}

This hook function tests a custom check box when the user chooses the OK button. If the check box is selected, the hook function sets a global variable to a nonzero value; otherwise it sets this variable to zero.

A hook function should never call the EndDialog function. Instead, if a hook function contains code that abnormally terminates a common dialog box, this code should pass the IDABORT value to the dialog box procedure by using the PostMessage function, as shown in the following example.

PostMessage(hDlg, WM_COMMAND, IDABORT, (LONG) FALSE);

When a hook function posts the IDABORT value, the common dialog box function returns the value contained in the low-order word of the lParam parameter. For example, if the hook function for GetOpenFileName called the PostMessage function with (LONG) 100 as the last parameter, GetOpenFileName would return 100.

A hook function must be exported in an application's module-definition (.DEF) file, as shown in the following example.

NAME         Generic       ; application's module name

DESCRIPTION  'Sample Microsoft Windows Application'

EXETYPE      WINDOWS       ; required for all Windows applications

STUB         'WINSTUB.EXE' ; Generates error message if the

                           ; application is run without Windows

CODE  PRELOAD MOVEABLE DISCARDABLE

DATA  PRELOAD MOVEABLE MULTIPLE

HEAPSIZE     1024

STACKSIZE    8192

EXPORTS

        MainWndProc   @1   ; name of window processing function

        About         @2   ; name of "About" processing function

        FileOpenHookProc @3; name of common dialog box callback


  76.3.2.2  Customizing a Dialog Box Template

The dialog box template provided in COMDLG32.DLL for each common dialog box contains the data the dialog box procedure uses to display that common dialog box. Most applications that customize a common dialog box also need to create a custom dialog box template to use instead of the dialog box template in COMDLG32.DLL. (A custom dialog box template is not required for all custom dialog boxes. A template would not be necessary, for instance, if an application changed a dialog box in a relatively minor way and only in an unusual situation.)

A developer should create a custom dialog box template by modifying the appropriate dialog box template in COMDLG32.DLL. Following are the template filenames and the names of their corresponding common dialog boxes.

Template filename	Corresponding dialog box
COLOR.DLG	Color
FILEOPEN.DLG	Open (single selection)
FILEOPEN.DLG	Open (multiple selection)
FINDTEXT.DLG	Find
FINDTEXT.DLG	Replace
FONT.DLG	Font
PRNSETUP.DLG	Print
PRNSETUP.DLG	Print Setup
The following example is from a custom dialog box template created for an Open dialog box.

FILEOPEN DIALOG LOADONCALL MOVEABLE DISCARDABLE

36, 24,  264, 134

CAPTION "Open"

STYLE WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_MODALFRAME

FONT 8, "Helv"

BEGIN

    LTEXT "File &Name:", stc3,    6,    6,  76,  10

    CONTROL "", edt1, "edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER |

            WS_TABSTOP | WS_CHILD | ES_OEMCONVERT | ES_LOWERCASE,

            6,    16,  90,  12

    CONTROL "", lst1, "listbox", LBS_SORT | LBS_NOTIFY | LBS_DISABLENOSCROLL |

              WS_VSCROLL | WS_BORDER | WS_TABSTOP | LBS_EXTENDEDSEL

            | LBS_HASSTRINGS | LBS_OWNERDRAWFIXED,

            6,   32,  90,  68

    LTEXT "&Directories:", -1, 110,   6,  92,   9

    LTEXT "", stc1,            110,  16,  92,   9, SS_NOPREFIX

    CONTROL "", lst2, "listbox",

            LBS_SORT | LBS_HASSTRINGS | LBS_NOTIFY | LBS_DISABLENOSCROLL

            | WS_VSCROLL | WS_CHILD | WS_BORDER | WS_TABSTOP

            | LBS_OWNERDRAWFIXED,

            110,  32,  92,  68

    LTEXT "List Files of &Type:", stc2, 6,  102,  90,   9

    CONTROL "", cmb1, "combobox", CBS_DROPDOWNLIST | CBS_AUTOHSCROLL |

            WS_BORDER | WS_VSCROLL | WS_TABSTOP | WS_CHILD,

            6,  112,  90,  36

    LTEXT "Dri&ves:", stc4,      110, 102,  92,  9

    CONTROL "", cmb2, "combobox",

            CBS_SORT | CBS_HASSTRINGS | CBS_OWNERDRAWFIXED | CBS_DROPDOWNLIST

            | WS_CHILD | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL

            | WS_TABSTOP,

            110, 112,  92, 68

    DEFPUSHBUTTON "OK", IDOK,      208,   6,  50,  14, WS_GROUP

    PUSHBUTTON "Cancel", IDCANCEL, 208,  24,  50,  14, WS_GROUP

    PUSHBUTTON "&Help", pshHelp,   208,  46,  50,  14, WS_GROUP

    PUSHBUTTON "Net&work...", psh14,   208,  114,  50,  14, WS_GROUP

    AUTOCHECKBOX "&Read Only", chx1,   208,  68,  50,  12,

                        WS_TABSTOP | WS_GROUP

    AUTOCHECKBOX "&Backup File", ID_CUSTCHX, 208, 86, 50, 12,

                        BS_AUTOCHECKBOX | WS_CHILD | WS_TABSTOP | WS_GROUP

END

The last entry supports the addition of a new Backup File check box immediately below the existing Read Only check box.

The custom template should be added to the application's resource file. You must use all of the unique control identifiers (that is, all identifiers whose values are other than −1) in the template, even if the dialog box does not use those controls. If you do not want to display all of the controls, you can specify coordinates for them outside the dialog box. You should also disable the unwanted buttons and remove unnecessary tab stops.


  76.3.3  Displaying the Custom Dialog Box

After your application creates the hook function and the dialog box template, it should set the members of the structure for the common dialog box being customized and call the appropriate function to display the custom dialog box.

The following example calls the GetOpenFileName function and creates a backup file if the user selected the Backup File check box in the custom Open dialog box.

/* Process the requested file. */

if (GetOpenFileName(&ofn)) {

    /*

     * If the user checked the Backup File Check box,

     * create a backup file.

     */

    if (fBackup) {

    /* Open the requested file. */

    hf = CreateFile(ofn.lpstrFile, GENERIC_READ,

             0, (LPSECURITY_ATTRIBUTES) NULL,

             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,

             (HANDLE) NULL);

        /* Process the extension (if it exists). */

        if (ofn.nFileExtension) {

            for(i = 0; i < (int)ofn.nFileExtension;

                i++)

                szChar[i] = *ofn.lpstrFile++;

            } /* end if */

        else {

            i = 0;

            while (*ofn.lpstrFile != '\0')

                szChar[i++] = *ofn.lpstrFile++;

            szChar[i] = '.';

            } /* end else */

        /* Create the backup filename string. */

        pszBackupFile = lstrcat(szChar, "BAK");

        /* Create the backup file. */

        hfBackup = CreateFile(pszBackupFile, GENERIC_WRITE,

                       0, (LPSECURITY_ATTRIBUTES) NULL,

                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,

                       (HANDLE) NULL);

        /*

         * Copy the contents of the original file

         * to the new file.

         */

        ReadFile(hf, szBuffer, 256, &cBufLen,

            NULL);

        while (cBufLen == 256) {

            WriteFile(hfBackup, szBuffer, 256, &cBufLen,

               NULL);

            ReadFile(hf, szBuffer, 256, &cBufLen,

               NULL);

            }

        WriteFile(hfBackup, szBuffer, cBufLen, &cTmp,

            NULL);

        /* Close the files. */

        CloseHandle(hfBackup);

        CloseHandle(hf);

     } /* end if */

 } /* end if */


  76.4  Supporting and Processing Help for the Common Dialog Boxes

An application can display a Help button in any of the common dialog boxes by setting the appropriate flag in the Flags member of the structure for a specific common dialog box. Following are the structures for the common dialog boxes and the Help flag that corresponds to each structure.

Structure	Flag value
OPENFILENAME	OFN_SHOWHELP
CHOOSECOLOR	CC_SHOWHELP
FINDREPLACE	FR_SHOWHELP
CHOOSEFONT	CF_SHOWHELP
PRINTDLG	PD_SHOWHELP
If an application displays the Help button, it must process the user's request for help. This can be done either in one of the application's window procedures or in a hook function.

If the application processes the request for help in one of the application's window procedures, it must first create a new message identifier for the string defined by the HELPMSGSTRING constant. The application creates the new message identifier by calling the RegisterWindowMessage function and passing this constant as the single parameter. (For more information about processing registered window messages, see Section 76.2.10, »Displaying the Find Dialog Box«.) In addition to creating a new message identifier, the application must set the hwndOwner member of the appropriate structure for the common dialog box so this member contains the handle of the dialog box's owner window. After the message identifier is created and the hwndOwner member is set, the dialog box procedure notifies the window procedure of the owner window whenever the user chooses the Help button.

The following example processes a user's request for help in the window procedure of its owner window. The if statement should be in the default: section of the switch statement that processes messages.

  MyHelpMsg = RegisterWindowMessage(HELPMSGSTRING);

            .

            .

            .

  if (message == MyHelpMsg)

     WinHelp(hWnd, "appfile.hlp", HELP_CONTEXT, ID_MY_CONTEXT);

If the application processes the request for help in a hook function, it should test for the following condition in the WM_COMMAND message.

wParam == pshHelp

When this condition is true, the hook function should call the WinHelp function, as shown in the preceding example. (To process Help in a hook function, you must include the header file DLGS.H in the source file that contains the hook-function code.)


  76.5  Error Detection

Whenever a common dialog box function fails, an application can call the CommDlgExtendedError function to find out the cause of the failure. CommDlgExtendedError returns an error value that identifies the cause of the most recent error.

Six constants are defined in the CDERR.H header file that identify the ranges of error values for categories of errors returned by CommDlgExtendedError. Following are these constants in ascending order by value range.

Constant	Description
CDERR_GENERALCODES	General error codes for common dialog boxes. These errors are in the range 0x0000 through 0x0FFF.
PDERR_PRINTERCODES	Error codes for the Print common dialog box. These errors are in the range 0x1000 through 0x1FFF.
CFERR_CHOOSEFONTCODES	Error codes for the Font common dialog box. These errors are in the range 0x2000 through 0x2FFF.
FNERR_FILENAMECODES	Error codes for the Open and Save As common dialog boxes. These errors are in the range 0x3000 through 0x3FFF.
FRERR_FINDREPLACECODES	Error codes for the Find and Replace common dialog boxes. These errors are in the range 0x4000 through 0x4FFF.
CCERR_CHOOSECOLORCODES	Error codes for the Color common dialog box. These errors are in the range 0x5000 through 0x5FFF.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Dynamic Data Exchange Management Library
  Chapter 77    Dynamic Data Exchange Management Library

77.1  About DDEML

In Microsoft Windows, dynamic data exchange (DDE) is a form of interprocess communications that uses shared memory to exchange data between applications. Applications can use DDE for one-time data transfers and for ongoing exchanges between applications sending updates to one another as new data becomes available.

DDE differs from the clipboard data-transfer mechanism that is also part of the Windows operating system. One difference is that the clipboard is almost always used as a one-time response to a specific action by the user — such as choosing the Paste command from a menu. Although DDE may also be initiated by a user, it typically continues without the user's further involvement.

The DDEML provides an application programming interface (API) that simplifies the task of adding DDE capability to a Windows application. Instead of sending, posting, and processing DDE messages directly, an application uses the functions provided by the DDEML to manage DDE conversations. A DDE conversation is the interaction between client and server applications. The DDEML also provides a facility for managing the strings and data shared among DDE applications. Instead of using atoms and pointers to shared memory objects, DDE applications create and exchange string handles, which identify strings, and data handles, which identify DDE objects. The DDEML provides a service that enables a server application to register the service names it supports. The service names are broadcast to other applications in the system, which use the names to connect to the server. The DDEML also ensures compatibility among DDE applications by requiring them to implement the DDE protocol in a consistent manner.

Existing applications using the message-based DDE protocol are fully compatible with those that use the DDEML. That is, an application using message-based DDE can establish conversations and perform transactions with applications using the DDEML. Instead of using DDE messages in your new application, take advantage of the DDEML and the many improvements it offers.

To use the API elements of the DDEML, you must include the DDEML.H header file in your source files, link with USER32.LIB, and ensure that DDEML.DLL resides in the system's path.


  77.2  Basic Concepts

The concepts in this section are key to understanding DDE and the DDEML.


  77.2.1  Client and Server Interaction

DDE always occurs between a client application and a server application. The DDE client application initiates the exchange by establishing a conversation with the server to send transactions to the server. A transaction is a request for data or services. The DDE server application responds to transactions by providing data or services to the client. A server can have many clients at the same time, and a client can request data from multiple servers. An application can also be both a client and a server. Either the client or the server can terminate the conversation at any time.

For example, a graphics application might contain a bar graph that represents a corporation's quarterly profits, and the data for the bar graph might be contained in a spreadsheet application. To obtain the latest profit figures, the graphics application (the client) establishes a conversation with the spreadsheet application (the server). The graphics application then sends a transaction to the spreadsheet application, requesting the latest profit figures.


  77.2.2  Transactions and the DDE Callback Function

The DDEML notifies an application about DDE activity that affects the application by sending transactions to the application's DDE callback function. A DDE transaction is similar to a message — it is a named constant accompanied by other parameters that contain additional information about the transaction.

The DDEML passes a transaction to an application-defined DDE callback function that carries out an action appropriate to the type of transaction. For example, when a client application attempts to establish a conversation with a server application, the client calls the DdeConnect function. This causes the DDEML to send an XTYP_CONNECT transaction to the server's DDE callback function. The callback function can allow the conversation by returning TRUE to the DDEML, or it can deny the conversation by returning FALSE.

For a detailed discussion of transactions, see Section 77.9, »Transaction Management«.


  77.2.3  Service Names, Topic Names, and Item Names

A DDE server uses a three-level hierarchy — service name (called "application name" in previous DDE documentation), topic name, and item name — to uniquely identify a unit of data the server can exchange during a conversation.

A service name is a string a server application responds to when a client attempts to establish a conversation with the server. A client must specify this service name to establish a conversation with the server. Although a server can respond to many service names, most servers respond to only one name.

A topic name is a string that identifies a logical data context. For servers that operate on file-based documents, topic names are typically filenames; for other servers, they are other application-specific strings. A client must specify a topic name along with a server's service name when it attempts to establish a conversation with a server.

An item name is a string that identifies a unit of data a server can pass to a client during a transaction. For example, an item name might identify an integer, a string, several paragraphs of text, or a bitmap.

These names enable the client to establish a conversation with a server and to receive data from the server.


  77.2.4  System Topic

The System topic provides a context for information of general interest to any DDE client. It is recommended that server applications support the System topic at all times. The System topic is defined in the DDEML header file as SZDDESYS_TOPIC.

To determine which servers are present and the kinds of information they can provide, a client application can, upon starting, request a conversation on the System topic, setting the device name to NULL. Such wildcard conversations are costly in terms of system performance; keep them to a minimum.

For more information about initiating DDE conversations, see Section 77.7, »Conversation Management«.

A server must support the following item names within the System topic and any other item names useful to a client.

Item	Description
SZDDE_ITEM_ITEMLIST	A list of the items supported under a non-System topic. (This list may vary from moment to moment and from topic to topic.)
SZDDESYS_ITEM_FORMATS	A tab-delimited list of strings representing all clipboard formats potentially supported by the service application. Strings that represent predefined clipboard formats are equivalent to the CF_ constant names with the "CF_" prefix removed. For example, the CF_TEXT format is represented by the string "TEXT". These strings must be in uppercase letters to further identify them as predefined formats. The list of formats must appear in the order of most rich in content to least rich in content.
	For more information about clipboard formats and rendering data, see Programmer's Reference, Volume 1, Chapter 25, "Clipboard."
SZDDESYS_ITEM_HELP	User-readable information of general interest. It must contain, at a minimum, information on how to use the server application's DDE features. This may include, but is not limited to, how to specify items within topics, what execute strings the server can perform, what poke transactions are allowed, and pointers to help on other System topic items.
SZDDESYS_ITEM_RTNMSG	Supporting detail for the most recently used WM_DDE_ACK message. This is useful when more than 8 bits of application-specific return data are required.
SZDDESYS_ITEM_STATUS	An indication of the current status of the server. Typically, this item supports only the CF_TEXT format and contains the Ready or Busy string.
SZDDESYS_ITEM_SYSITEMS	A list of the items supported under the System topic by this server.
SZDDESYS_ITEM_TOPICS	A list of the topics supported by the server at the current time. (This list may vary from moment to moment.)
These item names are string constants defined in the DDEML header files. To obtain string handles for these strings, an application must use the DDEML string-management functions, just as it would for any other string in a DDEML application. For more information about managing strings, see Section 77.5, »String Management«.


  77.3  Initialization

Before calling any other DDEML function, an application must call the DdeInitialize function. DdeInitialize obtains an instance identifier for the application, registers the application's DDE callback function with the DDEML, and specifies the transaction-filter flags for the callback function.

Each instance of an application or a dynamic-link library (DLL) must pass its instance identifier as the idInst parameter to any other DDEML function that requires it. The purpose of multiple DDEML instances is to support DLLs that must use the DDEML at the same time an application is using it. An application must not use more than one instance of the DDEML.

Transaction filters optimize system performance by preventing the DDEML from passing unwanted transactions to the application's DDE callback function. An application sets the transaction filters when it calls DdeInitialize. An application must specify a transaction-filter flag for each type of transaction that it does not process in its callback function. An application can change its transaction filters with a subsequent call to DdeInitialize. For a complete list of transaction-filter flags, see the description of DdeInitialize in the Microsoft Win32 Programmer's Reference, Volume 2.

For more information about transactions, see Section 77.9, »Transaction Management«.

The following example shows how to initialize an application to use the DDEML:

DWORD idInst = 0;

HINSTANCE hinst;

.

.

.

DdeInitialize(&idInst,         /* receives instance identifier */

    (PFNCALLBACK) DdeCallback, /* address of callback function */

    CBF_FAIL_EXECUTES |        /* filter XTYPE_EXECUTE         */

    CBF_SKIP_ALLNOTIFICATIONS, /* filter notifications         */

    0);

.

.

.

An application must call the DdeUninitialize function when it must no longer use the DDEML. This function terminates any conversations currently open for the application and frees the DDEML resources the system allocated for the application.


  77.4  Callback Function

An application that uses the DDEML must provide a callback function that processes the DDE events affecting the application. The DDEML notifies an application of such events by sending transactions to the application's DDE callback function. The transactions a callback function receives depend on the callback-filter flags the application specified in DdeInitialize and whether the application is a client, a server, or both. The following example shows the general structure of a callback function for a typical client application.

HDDEDATA CALLBACK DdeCallback(uType, uFmt, hconv, hsz1,

    hsz2, hdata, dwData1, dwData2)

UINT uType;       /* transaction type                 */

UINT uFmt;        /* clipboard data format            */

HCONV hconv;      /* handle of conversation           */

HSZ hsz1;         /* handle of string                 */

HSZ hsz2;         /* handle of string                 */

HDDEDATA hdata;   /* handle of global memory object   */

DWORD dwData1;    /* transaction-specific data        */

DWORD dwData2;    /* transaction-specific data        */

{

    switch (uType) {

        case XTYP_REGISTER:

        case XTYP_UNREGISTER:

            .

            .

            .

            return (HDDEDATA) NULL;

        case XTYP_ADVDATA:

            .

            .

            .

            return (HDDEDATA) DDE_FACK;

        case XTYP_XACT_COMPLETE:

            .

            .

            .

            return (HDDEDATA) NULL;

        case XTYP_DISCONNECT:

            .

            .

            .

            return (HDDEDATA) NULL;

        default:

            return (HDDEDATA) NULL;

    }

}

The uType parameter specifies the transaction type sent to the callback function by the DDEML. The values of the remaining parameters depend on the transaction type. The transaction types and the events that generate them are described in the following sections of this chapter. For detailed information about each transaction type, see Section 77.9, »Transaction Management«.


  77.5  String Management

To carry out a DDE task, many DDEML functions require access to strings. For example, a client must specify a service name and a topic name when it calls the DdeConnect function to request a conversation with a server. An application specifies a string by passing a string handle rather than a pointer in a DDEML function. A string handle is a doubleword value, assigned by the system, that identifies a string.

An application can obtain a string handle for a particular string by calling the DdeCreateStringHandle function. This function registers the string with the system and returns a string handle to the application. The application can pass the handle to DDEML functions that must access the string. The following example obtains string handles for the System topic string and the service-name string.

HSZ hszServName;

HSZ hszSysTopic;

.

.

.

hszServName = DdeCreateStringHandle(

    idInst,         /* instance identifier    */

    "MyServer",     /* string to register     */

    CP_WINANSI);    /* Windows ANSI code page */

hszSysTopic = DdeCreateStringHandle(

    idInst,         /* instance identifier    */

    SZDDESYS_TOPIC, /* System topic           */

    CP_WINANSI);    /* Windows ANSI code page */

.

.

.

The idInst parameter in the preceding example specifies the instance identifier obtained by the DdeInitialize function.

An application's DDE callback function receives one or more string handles during most DDE transactions. For example, a server receives two string handles during the XTYP_REQUEST transaction: One identifies a string specifying a topic name; the other identifies a string specifying an item name. An application can obtain the length of the string that corresponds to a string handle and copy the string to an application-defined buffer by calling the DdeQueryString function, as the following example demonstrates.

DWORD idInst;

DWORD cb;

HSZ hszServ;

PSTR pszServName;

.

.

.

cb = DdeQueryString(idInst, hszServ, (LPSTR) NULL, 0,

    CP_WINANSI) + 1;

pszServName = (PSTR) LocalAlloc(LPTR, (WORD) cb);

DdeQueryString(idInst, hszServ, pszServName, cb, CP_WINANSI);

.

.

.

An instance-specific string handle cannot be mapped from string handle to string and back to string handle. For instance, in the following example, DdeQueryString creates a string from a string handle and then DdeCreateStringHandle creates a string handle from that string, but the two handles are not the same.

DWORD idInst;

DWORD cb;

HSZ hszInst, hszNew;

PSZ pszInst;

.

.

.

DdeQueryString(idInst, hszInst, pszInst, cb, CP_WINANSI);

hszNew = DdeCreateStringHandle(idInst, pszInst, CP_WINANSI);

/* hszNew != hszInst ! */

.

.

.

A string handle passed to an application's DDE callback function becomes invalid when the callback function returns. An application can save a string handle for use after the callback function returns by using the DdeKeepStringHandle function.

When an application calls DdeCreateStringHandle, the system enters the specified string into a string table and generates a handle that it uses to access the string. The system also maintains a usage count for each string in the string table.

When an application calls DdeCreateStringHandle and specifies a string that already exists in the table, the system increments the usage count rather than adding another occurrence of the string. (An application can also increment the usage count by using DdeKeepStringHandle.) When an application calls the DdeFreeStringHandle function, the system decrements the usage count.

A string is removed from the table when its usage count equals zero. Because more than one application can obtain the handle of a particular string, an application must not free a string handle more times than it has created or retained the handle. Otherwise, the application could cause the string to be removed from the table, denying other applications access to the string.

The DDEML string-management functions are based on the Windows atom manager and are subject to the same size restrictions as are atoms.


  77.6  Name Service

The DDEML makes it possible for a server application to register the service names that it supports and to prevent the DDEML from sending XTYP_CONNECT transactions for unsupported service names to the server's DDE callback function. The remaining topics in this section describe this service.


  77.6.1  Service-Name Registration

By registering its service names with the DDEML, a server informs other DDE applications in the system that a new server is available. A server registers a service name by calling the DdeNameService function and specifying a string handle that identifies the name. In response, the DDEML sends an XTYP_REGISTER transaction to the callback function of each DDEML application in the system (except those that specified the CBF_SKIP_REGISTRATIONS filter flag in the DdeInitialize function). The XTYP_REGISTER transaction passes two string handles to a callback function: The first identifies the string specifying the base service name; the second identifies the string specifying the instance-specific service. A client typically uses the base service name in a list of available servers, so the user can select a server from the list. The client uses the instance-specific service name to establish a conversation with a specific instance of a server application, if more than one instance is running.

A server can use DdeNameService to unregister a service name. This causes the DDEML to send XTYP_UNREGISTER transactions to the other DDE applications in the system, informing them that they can no longer use the name to establish conversations.

A server must call DdeNameService to register its service names soon after calling DdeInitialize. A server must unregister its service names just before calling the DdeUninitialize function.


  77.6.2  Service-Name Filter

DdeNameService, in addition to registering service names, enables a server to turn its service-name filter on or off. When a server turns off its service-name filter, the DDEML sends the XTYP_CONNECT transaction to the server's DDE callback function whenever any client calls the DdeConnect function, regardless of the service name specified in the function. When a server turns on its service-name filter, the DDEML sends the XTYP_CONNECT transaction to the server only when DdeConnect specifies a service name the server has specified in a call to DdeNameService.

By default, the service-name filter is on when an application calls DdeInitialize. This prevents the DDEML from sending the XTYP_CONNECT transaction to a server before the server has created the string handles it needs. A server can turn off its service-name filter by specifying the DNS_FILTEROFF flag in a call to DdeNameService. The DNS_FILTERON flag turns on the filter.


  77.7  Conversation Management

A conversation between a client and a server is always established at the request of the client. When a conversation is established, each partner receives a handle that identifies the conversation. The partners use this handle in other DDEML functions to send transactions and manage the conversation. A client can request a conversation with a single server, or it can request multiple conversations with one or more servers.

The remaining topics in this section describe how an application establishes new conversations and gets information about existing conversations.


  77.7.1  Single Conversations

A client application requests a single conversation with a server by calling the DdeConnect function and specifying string handles that identify the strings containing the service name of the server and the topic name of interest. The DDEML responds by sending the XTYP_CONNECT transaction to the DDE callback function of each server application that either has registered a service name that matches the one specified in DdeConnect or has turned service-name filtering off by calling DdeNameService. A server can also filter the XTYP_CONNECT transactions by specifying the CBF_FAIL_CONNECTIONS filter flag in the DdeInitialize function. During the XTYP_CONNECT transaction, the DDEML passes the service name and the topic name to the server. The server must examine the names and return TRUE if it supports the service name and topic name pair or FALSE if it does not.

If no server responds positively to the client's request to connect, the client receives NULL from DdeConnect and no conversation is established. If a server does return TRUE, a conversation is established and the client receives a conversation handle — a doubleword value that identifies the conversation. The client uses the handle in subsequent DDEML calls to obtain data from the server. The server receives the XTYP_CONNECT_CONFIRM transaction (unless the server specified the CBF_FAIL_CONFIRMS filter flag). This transaction passes the conversation handle to the server.

The following example requests a conversation on the System topic with a server that recognizes the service name MyServer. The hszServName and hszSysTopic parameters are previously created string handles.

HCONV hConv;

HWND hwndParent;

HSZ hszServName;

HSZ hszSysTopic;

.

.

.

hConv = DdeConnect(

    idInst,               /* instance identifier        */

    hszServName,          /* service-name string handle */

    hszSysTopic,          /* System-topic string handle */

    (PCONVCONTEXT) NULL); /* use default context        */

if (hConv == NULL) {

    MessageBox(hwndParent, "MyServer is unavailable.",

        (LPSTR) NULL, MB_OK);

    return FALSE;

}

.

.

.

In the preceding example, DdeConnect causes the DDE callback function of the MyServer application to receive an XTYP_CONNECT transaction.

In the following example, the server responds to the XTYP_CONNECT transaction by comparing the topic-name string handle the DDEML passed to the server with each element in the array of topic-name string handles the server supports. If the server finds a match, it establishes the conversation.

#define CTOPICS 5

HSZ hsz1;                  /* string handle passed by DDEML  */

HSZ ahszTopics[CTOPICS];   /* array of supported topics      */

int i;                     /* loop counter                   */

.

. /* Use switch statement to examine transaction types. */

.

case XTYP_CONNECT:

    for (i = 0; i < CTOPICS; i++) {

        if (hsz1 == ahszTopics[i])

            return TRUE;   /* establish a conversation       */

    }

    return FALSE; /* topic not supported; deny conversation  */

.

. /* Process other transaction types. */

.

If the server returns TRUE in response to the XTYP_CONNECT transaction, the DDEML sends an XTYP_CONNECT_CONFIRM transaction to the server's DDE callback function. The server can obtain the handle for the conversation by processing this transaction.

A client can establish a wildcard conversation by specifying NULL for the service-name string handle, the topic-name string handle, or both in a call to DdeConnect. If at least one of the string handles is NULL, the DDEML sends the XTYP_WILDCONNECT transaction to the callback functions of all DDE applications (except those that filter the XTYP_WILDCONNECT transaction). Each server application should respond by returning a data handle that identifies a null-terminated array of HSZPAIR structures. If the server application has not called DdeNameService to register its service names, and if filtering is on, the server does not receive XTYP_WILDCONNECT transactions. For more information about data handles, see Section 77.8, »Data Management«.

The array must contain one structure for each service name and topic name pair that matches the pair specified by the client. The DDEML selects one of the pairs to establish a conversation and returns to the client a handle that identifies the conversation. The DDEML sends the XTYP_CONNECT_CONFIRM transaction to the server (unless the server filters this transaction). The following example shows a typical server response to the XTYP_WILDCONNECT transaction.

#define CTOPICS 2

UINT uType;

HSZPAIR ahszp[(CTOPICS + 1)];

HSZ ahszTopicList[CTOPICS];

HSZ hszServ, hszTopic;

WORD i, j;

if (uType == XTYP_WILDCONNECT) {

     /*

      * Scan the topic list and create an array of HSZPAIR

      * structures.

      */

    j = 0;

    for (i = 0; i < CTOPICS; i++) {

        if (hszTopic == (HSZ) NULL ||

                hszTopic == ahszTopicList[i]) {

            ahszp[j].hszSvc = hszServ;

            ahszp[j++].hszTopic = ahszTopicList[i];

        }

    }

    /*

     * End the list with an HSZPAIR structure that contains NULL

     * string handles as its members.

     */

    ahszp[j].hszSvc = NULL;

    ahszp[j++].hszTopic = NULL;

    /*

     * Return a handle to a global memory object containing the

     * HSZPAIR structures.

     */

    return DdeCreateDataHandle(

        idInst,          /* instance identifier     */

        (LPBYTE) &ahszp, /* points to HSZPAIR array */

        sizeof(HSZ) * j, /* length of the array     */

        0,               /* start at the beginning  */

        (HSZ) NULL,      /* no item-name string     */

        0,               /* return the same format  */

        0);              /* let the system own it   */

}

Either the client or the server can terminate a conversation at any time by calling the DdeDisconnect function. This causes the callback function of the partner in the conversation to receive the XTYP_DISCONNECT transaction (unless the partner specified the CBF_SKIP_DISCONNECTS filter flag). Typically, an application responds to the XTYP_DISCONNECT transaction by using the DdeQueryConvInfo function to obtain information about the conversation that terminated. After the callback function returns from processing the XTYP_DISCONNECT transaction, the conversation handle is no longer valid.

A client application that receives an XTYP_DISCONNECT transaction in its DDE callback function can attempt to reestablish the conversation by calling the DdeReconnect function. The client must call DdeReconnect from within its DDE callback function.


  77.7.2  Multiple Conversations

A client application can use the DdeConnectList function to determine whether any servers of interest are available in the system. A client specifies a service name and topic name when it calls DdeConnectList, causing the DDEML to broadcast the XTYP_WILDCONNECT transaction to the DDE callback functions of all servers that match the service name (except those that filter the transaction). A server's callback function should return a data handle that identifies a null-terminated array of HSZPAIR structures. The array should contain one structure for each service name and topic name pair that matches the pair specified by the client. The DDEML establishes a conversation for each HSZPAIR structure filled by the server and returns a conversation-list handle to the client. The server receives the conversation handle by way of the XTYP_CONNECT_CONFIRM transaction (unless the server filters this transaction).

A client can specify NULL for the service name, topic name, or both when it calls DdeConnectList. If the service name is NULL, all servers in the system that support the specified topic name respond. A conversation is established with each responding server, including multiple instances of the same server. If the topic name is NULL, a conversation is established on each topic recognized by each server that matches the service name.

A client can use the DdeQueryNextServer and DdeQueryConvInfo functions to identify the servers that respond to DdeConnectList. DdeQueryNextServer returns the next conversation handle in a conversation list; DdeQueryConvInfo fills a CONVINFO structure with information about the conversation. The client can keep the conversation handles that it needs and discard the rest from the conversation list.

The following example uses DdeConnectList to establish conversations with all servers that support the System topic and then uses the DdeQueryNextServer and DdeQueryConvInfo functions to obtain the servers' service-name string handles and store them in a buffer.

    HCONVLIST hconvList; /* conversation list       */

    DWORD idInst;        /* instance identifier     */

    HSZ hszSystem;       /* System topic            */

    HCONV hconv = NULL;  /* conversation handle     */

    CONVINFO ci;         /* holds conversation data */

    UINT cConv = 0;      /* count of conv. handles  */

    HSZ *pHsz, *aHsz;    /* point to string handles */

    /* Connect to all servers that support the System topic. */

    hconvList = DdeConnectList(idInst, NULL, hszSystem, NULL, NULL);

    /* Count the number of handles in the conversation list. */

    while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL)

        cConv++;

    /* Allocate a buffer for the string handles. */

    hconv = NULL;

    aHsz = (HSZ *) LocalAlloc(LMEM_FIXED, cConv * sizeof(HSZ));

    /* Copy the string handles to the buffer. */

    pHsz = aHsz;

    while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL) {

        DdeQueryConvInfo(hconv, QID_SYNC, (PCONVINFO) &ci);

        DdeKeepStringHandle(idInst, ci.hszSvcPartner);

        *pHsz++ = ci.hszSvcPartner;

    }

    .

    . /* Use the handles; converse with the servers. */

    .

    /* Free the memory and terminate the conversations. */

    LocalFree((HANDLE) aHsz);

    DdeDisconnectList(hconvList);

An application can terminate an individual conversation in a conversation list by calling the DdeDisconnect function. An application can terminate all conversations in a conversation list by calling the DdeDisconnectList function. Both functions cause the DDEML to send XTYP_DISCONNECT transactions to each partner's DDE callback function. DdeDisconnectList sends an XTYP_DISCONNECT transaction for each conversation handle in the list.

A client can use DdeConnectList to retrieve a list of the conversation handles in a conversation list by passing an existing conversation-list handle to DdeConnectList. The enumeration process removes the handles of terminated conversations from the list, and nonduplicate conversations that fit the specified service name and topic name are added.

If DdeConnectList specifies an existing conversation-list handle, the function creates a new conversation list that contains the handles of any new conversations and the handles from the existing list.

If duplicate conversations exist, DdeConnectList attempts to prevent duplicate conversation handles in a conversation list. A duplicate conversation is a second conversation with the same server on the same service name and topic name. Two such conversations would have different handles, yet they would identify the same conversation.


  77.8  Data Management

Because DDE uses memory objects to pass data from one application to another, the DDEML provides a set of functions that DDE applications can use to create and manage DDE objects.

All transactions that involve the exchange of data require the application supplying the data to create a local buffer containing the data and then to call the DdeCreateDataHandle function. This function allocates a DDE object, copies the data from the buffer to the object, and returns a data handle of the application. A data handle is a doubleword value that the DDEML uses to provide access to data in the DDE object. To share the data in a DDE object, an application passes the data handle to the DDEML, and the DDEML passes the handle to the DDE callback function of the application that is receiving the data transaction.

The following example shows how to create a DDE object and obtain a handle of the object. During the XTYP_ADVREQ transaction, the callback function converts the current time to an ASCII string, copies the string to a local buffer, and then creates a DDE object that contains the string. The callback function returns the handle of the DDE object to the DDEML, which passes the handle to the client application.

typedef struct tagTIME

  {

    INT     hour;   /* 0 - 11 hours for analog clock */

    INT     hour12; /* 12-hour format */

    INT     hour24; /* 24-hour format */

    INT     minute;

    INT     second;

    INT     ampm;   /* 0 - AM , 1 - PM */

  } TIME;

HDDEDATA EXPENTRY DdeCallback(uType, uFmt, hconv, hsz1, hsz2,

    hdata, dwData1, dwData2)

UINT uType;

UINT uFmt;

HCONV hconv;

HSZ hsz1;

HSZ hsz2;

HDDEDATA hdata;

DWORD dwData1;

DWORD dwData2;

{

    CHAR szBuf[32];

    switch (uType) {

    case XTYP_ADVREQ:

    case XTYP_REQUEST:

        if ((hsz1 == hszTime && hsz2 == hszNow) &&

                (uFmt == CF_TEXT)) {

            /* Copy the formatted string to a buffer. */

            itoa(tmTime.hour, szBuf, 10);

            lstrcat(szBuf, ":");

            if (tmTime.minute < 10)

                lstrcat(szBuf, "0");

            itoa(tmTime.minute, &szBuf[lstrlen(szBuf)], 10);

            lstrcat(szBuf, ":");

            if (tmTime.second < 10)

                strcat(szBuf, "0");

            itoa(tmTime.second, &szBuf[lstrlen(szBuf)], 10);

            szBuf[lstrlen(szBuf)] = '\0';

            /* Create a global object and return its data handle. */

            return (DdeCreateDataHandle(

                idInst,

                (LPBYTE) szBuf,     /* instance identifier   */

                lstrlen(szBuf) + 1, /* source buffer         */

                0,                  /* offset from beginning */

                hszNow,             /* item-name string      */

                CF_TEXT,            /* clipboard format      */

                0));                /* no creation flags     */

        } else

            return (HDDEDATA) NULL;

    .

    . /* Process other transactions. */

    .

    }

}

The receiving application obtains a pointer to the DDE object by passing the data handle to the DdeAccessData function. The pointer returned by DdeAccessData provides read-only access. The application should use the pointer to review the data and then call the DdeUnaccessData function to invalidate the pointer. The application can copy the data to a local buffer by using the DdeGetData function.

The following example obtains a pointer to the DDE object identified by the hData parameter, copies the contents to a local buffer, and then invalidates the pointer.

HDDEDATA hdata;

LPBYTE lpszAdviseData;

DWORD cbDataLen;

DWORD i;

char szData[32];

.

.

.

case XTYP_ADVDATA:

    lpszAdviseData = DdeAccessData(hdata, &cbDataLen);

    for (i = 0; i < cbDataLen; i++)

        szData[i] = *lpszAdviseData++;

    DdeUnaccessData(hdata);

    return (HDDEDATA) TRUE;

.

.

.

Usually, when an application that created a data handle passes that handle to the DDEML, the handle becomes invalid in the creating application. This is fine if the application must share data with only a single application. If an application must share the same data with multiple applications, however, the creating application should specify the HDATA_APPOWNED flag in DdeCreateDataHandle. Doing so gives ownership of the DDE object to the creating application and prevents the DDEML from invalidating the data handle. The application can pass the data handle any number of times, but must call DdeCreateDataHandle only once.

If an application specifies the HDATA_APPOWNED flag in the afCmd parameter of DdeCreateDataHandle, it must call the DdeFreeDataHandle function to free the memory handle, regardless of whether it passed the handle to the DDEML. Before it terminates, an application must call DdeFreeDataHandle to free any data handle that it created but did not pass to the DDEML.

If an application has not yet passed the handle of a DDE object to the DDEML, the application can add data to the object or overwrite data in the object by using the DdeAddData function. Typically, an application uses DdeAddData to fill an uninitialized DDE object. After an application passes a data handle to the DDEML, the DDE object identified by the handle cannot be changed; it can only be freed.


  77.9  Transaction Management

After establishing a conversation with a server, a client can send transactions to obtain data and services from the server. The remaining topics in this section describe the types of transactions that clients can use to interact with a server.


  77.9.1  Request Transaction

A client application can use the XTYP_REQUEST transaction to request a data item from a server application. The client calls the DdeClientTransaction function, specifying XTYP_REQUEST as the transaction type and specifying the data item the application needs.

The DDEML passes the XTYP_REQUEST transaction to the server, specifying the topic name, item name, and data format requested by the client. If the server supports the requested topic, item, and format, the server should return a data handle that identifies the current value of the item. The DDEML passes this handle to the client as the return value from DdeClientTransaction. The server should return NULL if it does not support the topic, item, or format requested.

DdeClientTransaction uses the lpdwResult parameter to return a transaction-status flag to the client. If the server does not process the XTYP_REQUEST transaction, DdeClientTransaction returns NULL, and lpdwResult points to the DDE_FNOTPROCESSED or DDE_FBUSY flag. If the DDE_FNOTPROCESSED flag is returned, the client cannot determine why the server did not process the transaction.

If a server does not support the XTYP_REQUEST transaction, it should specify the CBF_FAIL_REQUESTS filter flag in the DdeInitialize function. This prevents the DDEML from sending this transaction to the server.


  77.9.2  Poke Transaction

A client can send unsolicited data to a server by using DdeClientTransaction to send an XTYP_POKE transaction to a server's callback function.

The client application first creates a buffer that contains the data to send to the server and then passes a pointer to the buffer as a parameter to DdeClientTransaction. Alternatively, the client can use the DdeCreateDataHandle function to obtain a data handle that identifies the data and then pass the handle to DdeClientTransaction. In either case, the client also specifies the topic name, item name, and data format when it calls DdeClientTransaction.

The DDEML passes the XTYP_POKE transaction to the server, specifying the topic name, item name, and data format that the client requested. To accept the data item and format, the server should return DDE_FACK. To reject the data, the server should return DDE_FNOTPROCESSED. If the server is too busy to accept the data, the server should return DDE_FBUSY.

When DdeClientTransaction returns, the client can use the lpdwResult parameter to access the transaction-status flag. If the flag is DDE_FBUSY, the client should send the transaction again later.

If a server does not support the XTYP_POKE transaction, it should specify the CBF_FAIL_POKES filter flag in DdeInitialize. This prevents the DDEML from sending this transaction to the server.


  77.9.3  Advise Transaction

A client application can use the DDEML to establish one or more links to items in a server application. When such a link has been established, the server sends periodic updates about the linked item to the client (typically, whenever the value of the item associated with the server application changes). This establishes an advise loop between the two applications that remains in place until the client ends it.

There are two kinds of advise loops: "hot" and "warm." In a hot advise loop, the server immediately sends a data handle that identifies the changed value. In a warm advise loop, the server notifies the client that the value of the item has changed but does not send the data handle until the client requests it.

A client can request a hot advise loop with a server by specifying the XTYP_ADVSTART transaction type in a call to DdeClientTransaction. To request a warm advise loop, the client must combine the XTYPF_NODATA flag with the XTYP_ADVSTART transaction type. In either event, the DDEML passes the XTYP_ADVSTART transaction to the server's DDE callback function. The server's DDE callback function should examine the parameters that accompany the XTYP_ADVSTART transaction (including the requested format, topic name, and item name) and then return TRUE to allow the advise loop or FALSE to deny it.

After an advise loop has been established, the server application should call the DdePostAdvise function whenever the value of the item associated with the requested item name changes. This results in an XTYP_ADVREQ transaction being sent to the server's own DDE callback function. The server's DDE callback function should return a data handle that identifies the new value of the data item. The DDEML then notifies the client that the specified item has changed by sending the XTYP_ADVDATA transaction to the client's DDE callback function.

If the client requested a hot advise loop, the DDEML passes the data handle for the changed item to the client during the XTYP_ADVDATA transaction. Otherwise, the client can send an XTYP_REQUEST transaction to obtain the data handle.

It is possible for a server to send updates faster than a client can process the new data. This can be a problem for a client that must perform lengthy processing operations on the data. In this case, the client should specify the XTYPF_ACKREQ flag when it requests an advise loop. This causes the server to wait for the client to acknowledge that it has received and processed a data item before the server sends the next data item. Advise loops that are established with the XTYPF_ACKREQ flag are more robust with fast servers but may occasionally miss updates. Advise loops established without the XTYPF_ACKREQ flag are guaranteed not to miss updates as long as the client keeps up with the server.

A client can end an advise loop by specifying the XTYP_ADVSTOP transaction type in a call to DdeClientTransaction.

If a server does not support advise loops, it should specify the CBF_FAIL_ADVISES filter flag in the DdeInitialize function. This prevents the DDEML from sending the XTYP_ADVSTART and XTYP_ADVSTOP transactions to the server.


  77.9.4  Execute Transaction

A client can use the XTYP_EXECUTE transaction to cause a server to execute a command or a series of commands.

To execute a server command, the client first creates a buffer that contains a command string for the server to execute and then passes either a pointer to the buffer or a data handle identifying the buffer when it calls DdeClientTransaction. Other required parameters include the conversation handle, the item-name string handle, the format specification, and the XTYP_EXECUTE transaction type. When an application creates a data handle for passing execute data, the application must specify NULL for the hszItem parameter of the DdeCreateDataHandle function and zero for the uFmt parameter.

The DDEML passes the XTYP_EXECUTE transaction to the server's DDE callback function and specifies the format name, conversation handle, topic name, and data handle identifying the command string. If the server supports the command, it should use the DdeAccessData function to obtain a pointer to the command string, execute the command, and then return DDE_FACK. If the server does not support the command or cannot complete the transaction, it should return DDE_FNOTPROCESSED. The server should return DDE_FBUSY if it is too busy to complete the transaction.

In general, a server's callback function should process the XTYP_EXECUTE transaction before returning. Exceptions to this include the following:

1.	When the command passed with the XTYP_EXECUTE transaction requests the server to terminate, the server's should not terminate until its callback function returns from processing XTYP_EXECUTE.

2.	If the server must perform an operation such as processing a dialog box or a DDE transaction that might cause DDEML recursion problems, the server should return CBR_BLOCK to block the execute transaction, perform the operation, and then resume processing the execute transaction.

When DdeClientTransaction returns, the client can use the lpdwResult parameter to access the transaction-status flag. If the flag is DDE_FBUSY, the client should send the transaction again later.

If a server does not support the XTYP_EXECUTE transaction, it should specify the CBF_FAIL_EXECUTES filter flag in the DdeInitialize function. Doing so prevents the DDEML from sending this transaction to the server.


  77.9.5  Synchronous and Asynchronous Transactions

A client can send either synchronous or asynchronous transactions. In a synchronous transaction, the client specifies a time-out value that indicates the maximum amount of time it will wait for the server to process the transaction. DdeClientTransaction does not return until the server processes the transaction, the transaction fails, or the time-out value expires. The client specifies the time-out value when it calls DdeClientTransaction.

During a synchronous transaction, the client enters a modal loop while waiting for the transaction to be processed. The client can still process user input but cannot send another synchronous transaction until DdeClientTransaction returns.

A client sends an asynchronous transaction by specifying the TIMEOUT_ASYNC flag in DdeClientTransaction. The function returns after the transaction has begun, passing a transaction identifier to the client. When the server finishes processing the asynchronous transaction, the DDEML sends an XTYP_XACT_COMPLETE transaction to the client. One of the parameters that the DDEML passes to the client during the XTYP_XACT_COMPLETE transaction is the transaction identifier. By comparing this transaction identifier with the identifier returned by DdeClientTransaction, the client identifies which asynchronous transaction the server has finished processing.

A client can use the DdeSetUserHandle function as an aid in processing an asynchronous transaction. This function makes it possible for a client to associate an application-defined doubleword value with a conversation handle and a transaction identifier. The client can use the DdeQueryConvInfo function during the XTYP_XACT_COMPLETE transaction to obtain the application-defined doubleword value. Because of this, an application need not maintain a list of active transaction identifiers.

When a client successfully completes a request for data using a synchronous transaction, the DDEML has no way to tell when the client has finished using the data received. The client application must pass the data handle received to the DdeFreeDataHandle function, notifying the DDEML that the handle will no longer be used. Data handles returned by synchronous transactions are effectively owned by the client.

If a server does not process an asynchronous transaction in a timely manner, the client can abandon the transaction by calling the DdeAbandonTransaction function. The DDEML releases all resources associated with the transaction and discards the results of the transaction when the server finishes processing it. A time-out during a synchronous transaction effectively cancels the transaction.

The asynchronous transaction method is provided for applications that must send a high volume of DDE transactions while simultaneously performing a substantial amount of processing, such as performing calculations. The asynchronous method is also useful in applications that must stop processing DDE transactions temporarily so they can complete other tasks without interruption. In most other situations, an application should use the synchronous method.

Synchronous transactions are simpler to maintain and are faster than asynchronous transactions. However, only one synchronous transaction can be performed at a time, whereas many asynchronous transactions can be performed simultaneously. With synchronous transactions, a slow server can cause a client to remain idle while it is waiting for a response. Also, synchronous transactions cause the client to enter a modal loop that could bypass message filtering in the application's own message loop.

Message filtering is not bypassed if the client has set a MSGF_DDEMGR message filter. The main danger of the synchronous transaction modal loop is that a modal loop created by a dialog box can interfere with its operation. Asynchronous transactions should always be used when the DDEML is being used by a dynamic-link library (DLL).


  77.9.6  Transaction Control

An application can suspend transactions to its DDE callback function — either those transactions associated with a specific conversation handle or all transactions regardless of the conversation handle. This is useful when an application receives a transaction that requires lengthy processing. In such a case, the application could return CBR_BLOCK to suspend future transactions associated with the transaction's conversation handle, leaving the application free to process other conversations.

When processing has been completed, the application calls the DdeEnableCallback function to resume transactions associated with the suspended conversation. Calling DdeEnableCallback causes the DDEML to resend the transaction that resulted in the application suspending the conversation. Therefore, the application should store the result of the transaction in such a way that it can obtain and return the result without reprocessing the transaction.

An application can suspend all transactions associated with a specific conversation handle by specifying the handle and the EC_DISABLE flag in a call to DdeEnableCallback. By specifying a NULL handle, an application can suspend all transactions for all conversations.

When a conversation has been suspended, the DDEML saves transactions for the conversation in a transaction queue. When the application reenables the conversation, the DDEML removes the saved transactions from the queue and passes each transaction to the appropriate callback function. The capacity of the transaction queue is large, but an application should reenable a suspended conversation as soon as possible to avoid losing transactions.

An application can resume usual transaction processing by specifying the EC_ENABLEALL flag in DdeEnableCallback. For a more controlled resumption of transaction processing, the application can specify the EC_ENABLEONE flag. This removes one transaction from the transaction queue and passes it to the appropriate callback function; after that transaction has been processed, any conversations are again disabled.

If the EC_ENABLEONE flag and a conversation handle are specified in the call to DdeEnableCallback, only that conversation is blocked after the transaction has been processed. If a NULL conversation handle is specified, all conversations are blocked after a transaction has been processed in any conversation.


  77.9.7  Transaction Classes

The DDEML has four classes of transactions. Each class is identified by a constant that begins with the XCLASS_ prefix. The classes are defined in the DDEML header file. The class constant is combined with the transaction-type constant and is passed to the DDE callback function of the receiving application.

A transaction's class determines the return value that a callback function is expected to return if it processes the transaction. The following table shows the return values and transaction types associated with each of the four transaction classes.

Class	Return value	Transaction
XCLASS_BOOL	TRUE or FALSE	XTYP_ADVSTART XTYP_CONNECT
XCLASS_DATA	A data handle, CBR_BLOCK, or NULL	XTYP_ADVREQ XTYP_REQUEST XTYP_WILDCONNECT
XCLASS_FLAGS	A transaction flag: DDE_FACK, DDE_FBUSY, or DDE_FNOTPROCESSED	XTYP_ADVDATA XTYP_EXECUTE XTYP_POKE
XCLASS_NOTIFICATION	None	XTYP_ADVSTOP XTYP_CONNECT_CONFIRM XTYP_DISCONNECT XTYP_ERROR XTYP_REGISTER XTYP_UNREGISTER XTYP_XACT_COMPLETE


  77.9.8  Transaction Summary

The following table shows each DDE transaction type, the receiver of each type, and a description of the activity that causes the DDEML to generate each type.

Transaction type	Receiver	Cause
XTYP_ADVDATA	Client	A server responded to an XTYP_ADVREQ transaction by returning a data handle.
XTYP_ADVREQ	Server	A server called the DdePostAdvise function, indicating that the value of a data item in an advise loop had changed.
XTYP_ADVSTART	Server	A client specified the XTYP_ADVSTART transaction type in a call to the DdeClientTransaction function.
XTYP_ADVSTOP	Server	A client specified the XTYP_ADVSTOP transaction type in a call to DdeClientTransaction.
XTYP_CONNECT	Server	A client called the DdeConnect function and specified a service name and topic name supported by the server.
XTYP_CONNECT_CONFIRM	Server	The server returned TRUE in response to an XTYP_CONNECT or XTYP_WILDCONNECT transaction.
XTYP_DISCONNECT	Client/Server	A partner in a conversation called the DdeDisconnect function, causing both partners to receive this transaction.
XTYP_ERROR	Client/Server	A critical error has occurred. The DDEML may not have sufficient resources to continue.
XTYP_EXECUTE	Server	A client specified the XTYP_EXECUTE transaction type in a call to DdeClientTransaction.
XTYP_MONITOR	DDE monitoring application	A DDE event occurred in the system. For more information about DDE monitoring applications, see Section 77.11, »Monitoring Applications«.
XTYP_POKE	Server	A client specified the XTYP_POKE transaction type in a call to DdeClientTransaction.
XTYP_REGISTER	Client/Server	A server application used the DdeNameService function to register a service name.
XTYP_REQUEST	Server	A client specified the XTYP_REQUEST transaction type in a call to DdeClientTransaction.
XTYP_UNREGISTER	Client/Server	A server application used DdeNameService to unregister a service name.
XTYP_WILDCONNECT	Server	A client called the DdeConnect or DdeConnectList function, specifying NULL for the service name, the topic name, or both.
XTYP_XACT_COMPLETE	Client	An asynchronous transaction, sent when the client specified the TIMEOUT_ASYNC flag in a call to DdeClientTransaction, has concluded.


  77.10  Error Detection

Whenever a DDEML function fails, an application can call the DdeGetLastError function to determine the cause of the failure. DdeGetLastError returns an error value that specifies the cause of the most recent error.


  77.11  Monitoring Applications

You can use the application programming interface (API) elements of the DDEML to create an application that monitors DDE activity in the system. Like any DDEML application, a DDE monitoring application contains a DDE callback function. The DDEML notifies a monitoring application's DDE callback function whenever a DDE event occurs, passing information about the event to the callback function. The application typically displays the information in a window or writes it to a file.

To receive notifications from the DDEML, an application must have registered as a DDE monitor by specifying the APPCLASS_MONITOR flag in a call to the DdeInitialize function. In this same call, the application can specify one or more monitor flags to indicate the types of events of which the DDEML is to notify the application's callback function. The following table describes each of the monitor flags an application can specify:

Flag	Meaning
MF_CALLBACKS	Notifies the callback function whenever a transaction is sent to any DDE callback function in the system.
MF_CONV	Notifies the callback function whenever a conversation is established or terminated.
MF_ERRORS	Notifies the callback function whenever a DDEML error occurs.
MF_HSZ_INFO	Notifies the callback function whenever a DDEML application creates, frees, or increments the usage count of a string handle or whenever a string handle is freed as a result of a call to the DdeUninitialize function.
MF_LINKS	Notifies the callback function whenever an advise loop is started or ended.
MF_POSTMSGS	Notifies the callback function whenever the system or an application posts a DDE message.
MF_SENDMSGS	Notifies the callback function whenever the system or an application sends a DDE message.
The following example shows how to register a DDE monitoring application so that its DDE callback function receives notifications of all DDE events:

DWORD idInst;

PFNCALLBACK lpDdeProc;

hInst = hInstance;

lpDdeProc = (PFNCALLBACK) MakeProcInstance(

    (FARPROC) DDECallback,  /* points to callback function      */

    hInstance);             /* instance handle                  */

if (DdeInitialize(

        (LPDWORD) &idInst,  /* instance identifier              */

        lpDdeProc,          /* points to callback function      */

        APPCLASS_MONITOR |  /* this is a monitoring application */

        MF_CALLBACKS     |  /* monitor callback functions       */

        MF_CONV          |  /* monitor conversation data        */

        MF_ERRORS        |  /* monitor DDEML errors             */

        MF_HSZ_INFO      |  /* monitor data-handle activity     */

        MF_LINKS         |  /* monitor advise loops             */

        MF_POSTMSGS      |  /* monitor posted DDE messages      */

        MF_SENDMSGS,        /* monitor sent DDE messages        */

        0))                 /* reserved                         */

    return FALSE;

The DDEML informs a monitoring application of a DDE event by sending an XTYP_MONITOR transaction to the application's DDE callback function. During this transaction, the DDEML passes a monitor flag that specifies the type of DDE event that has occurred and a handle of a DDE object that contains detailed information about the event. The DDEML provides a set of structures that the application can use to extract the information from the DDE object. There is a corresponding structure for each type of DDE event. The following table describes each of these structures.

Structure	Description
MONCBSTRUCT	Contains information about a transaction.
MONCONVSTRUCT	Contains information about a conversation.
MONERRSTRUCT	Contains information about the latest DDE error.
MONLINKSTRUCT	Contains information about an advise loop.
MONHSZSTRUCT	Contains information about a string handle.
MONMSGSTRUCT	Contains information about a DDE message that was sent or posted.
The following example shows the DDE callback function of a DDE monitoring application that formats information about each string handle event and then displays the information in a window. The function uses the MONHSZSTRUCT structure to extract the information from the DDE object.

HDDEDATA CALLBACK DDECallback(uType, uFmt, hconv, hsz1, hsz2,

    hdata, dwData1, dwData2)

UINT uType;

UINT uFmt;

HCONV hconv;

HSZ hsz1;

HSZ hsz2;

HDDEDATA hdata;

DWORD dwData1;

DWORD dwData2;

{

    LPVOID lpData;

    CHAR *szAction;

    CHAR szBuf[256];

    DWORD cb;

    switch (uType) {

        case XTYP_MONITOR:

            /* Obtain a pointer to the global memory object. */

            if (lpData = DdeAccessData(hdata, &cb)) {

                /* Examine the monitor flag. */

                switch (dwData2) {

                    case MF_HSZ_INFO:

#define PHSZS ((MONHSZSTRUCT FAR *)lpData)

                        /*

                         * The global memory object contains

                         * string-handle data. Use the MONHSZSTRUCT

                         * structure to access the data.

                         */

                        switch (PHSZS->fsAction) {

                            /*

                             * Examine the action flags to

                             * determine the action performed on

                             * the handle.

                             */

                            case MH_CREATE:

                                szAction = "Created";

                                break;

                            case MH_KEEP:

                                szAction = "Incremented";

                                break;

                            case MH_DELETE:

                                szAction = "Deleted";

                                break;

                            case MH_CLEANUP:

                                szAction = "Cleaned up";

                                break;

                            default:

                                DdeUnaccessData(hdata);

                                return (HDDEDATA) 0;

                        }

                        /* Write formatted output to a buffer. */

                        wsprintf(szBuf,

                            "Handle %s, Task: %x, Hsz: %lx(%s)",

                            (LPSTR) szAction, PHSZS->hTask,

                            PHSZS->hsz, (LPSTR) PHSZS->str);

                        .

                        . /* Display text or write to a file. */

                        .

                        break;

#undef PHSZS

                    .

                    . /* Process other MF_* flags. */

                    .

                    default:

                        break;

                }

            }

            /* Free the global memory object. */

            DdeUnaccessData(hdata);

            break;

        default:

            break;

    }

    return (HDDEDATA) 0;

}


Shell Library
  Chapter 78    Shell Library

78.1  About the Shell Library

This chapter describes features of the shell for the Microsoft Windows operating system. The following features are supported by the dynamic-link library SHELL.DLL:

•	The drag-drop feature

•	Associations (used) to find and start applications

•	Extraction of icons from executable files

The header file for the functions that support these features is SHELLAPI.H. The library is SHELL32.LIB.


  78.1.1  Using the Shell Features

This section describes how to implement the shell features in your applications.


  78.1.2  Using the Drag-Drop Feature

When an application implements the drag-drop feature, a user can select one or more files in File Manager, drag them to an open application, and drop them there. The application in which the files were dropped receives a message it can use to retrieve the filenames and the coordinates of the point at which the files were dropped.

An application that can accept dropped files from File Manager calls the DragAcceptFiles function for one or more of its windows. When the user releases the mouse button to drop a file or files in the window specified in the call to DragAcceptFiles, File Manager sends the application a WM_DROPFILES message. (File Manager does not send the WM_DROPFILES message to an application unless the application calls DragAcceptFiles.) WM_DROPFILES contains a handle of a structure the application can query to retrieve the name of the dropped file and the coordinates of the cursor when the file was dropped. The application can use the DragQueryFile function to retrieve a count of the files that were dropped and their names. The DragQueryPoint function returns the window coordinates of the cursor when the user released the mouse button.

To free the memory allocated by the system for the WM_DROPFILES message, an application calls the DragFinish function when it is finished.

For example, an application can call the DragAcceptFiles function when it starts and call a drag-drop function when it receives a WM_DROPFILES message, as shown in the following example.

        case WM_CREATE:

            DragAcceptFiles(hwnd, TRUE);

            break;

        case WM_DROPFILES:

            DragFunc(hwnd, wParam); /* application-defined function */

            break;

        case WM_DESTROY:

            DragAcceptFiles(hwnd, FALSE);

            break;

The following example uses the DragQueryPoint function to determine where to begin to write text. The first call to the DragQueryFile function determines the number of dropped files. The loop writes the name of each file, beginning at the point returned by DragQueryPoint.

POINT pt;

WORD cFiles, a;

char lpszFile[80];

DragQueryPoint((HANDLE) wParam, &pt);

cFiles = DragQueryFile((HANDLE) wParam, 0xFFFF, (LPSTR) NULL, 0);

for(a = 0; a < cFiles; pt.y += 20, a++) {

    DragQueryFile((HANDLE) wParam, a, lpszFile, sizeof(lpszFile));

    TextOut(hdc, pt.x, pt.y, lpszFile, lstrlen(lpszFile));

}

DragFinish((HANDLE) wParam);


  78.2  Using Associations to Find and Start Applications

File Manager includes an Associate dialog box that makes it possible for users to associate a filename extension with a specific application. File Manager stores these associations in the registry (under HKEY_CURRENT_USER\Software\Description\Microsoft\Windows NT\CurrentVersion\Extensions). If a file has a filename extension that is associated with an application, that application starts automatically whenever a user double-clicks that file in File Manager.

Using the FindExecutable and ShellExecute functions, applications can take advantage of such associations to find and start applications or open and print files.

An application can use the FindExecutable function to retrieve the name and handle of the executable file that is associated with a specified filename. The ShellExecute function either opens or prints a specified file, depending on the value of its lpszOp parameter. To open a document file, the function relies on the association of the filename extension.


  78.3  Extracting Icons from Executable Files

An application can use the ExtractIcon function to retrieve the handle of an icon from a specified executable file, dynamic-link library, or icon file. The following example uses the DragQueryPoint function to retrieve the coordinates of the point where a file was dropped, the DragQueryFile function to retrieve the filename of a dropped file, and the ExtractIcon function to retrieve the handle of the first icon in the file, if any.

POINT pt;

WORD cFiles;

HDC hdc;

char lpszFile[80];

HANDLE hCurrentInst, hicon;

DragQueryPoint((HANDLE) wParam, &pt);

cFiles = DragQueryFile((HANDLE) wParam, 0xFFFF, NULL, NULL);

if(cFiles > 1) {

    TextOut(hdc, pt.x, pt.y,

        "Please drop only one icon file.", 31);

    return FALSE;

}

else {

    DragQueryFile((HANDLE) wParam, 0, lpszFile, sizeof(lpszFile));

    hCurrentInst = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE);

    hicon = ExtractIcon(hCurrentInst, lpszFile, 0);

    if (hicon == NULL)

        TextOut(hdc, pt.x, pt.y, "No icons found.", 15);

    else if (hicon == (HICON) 1)

        TextOut(hdc, pt.x, pt.y,

            "File must be .EXE, .ICO, or .DLL.", 33);

    else

        DrawIcon(hdc, pt.x, pt.y, hicon);

}

DragFinish((HANDLE) wParam);


  78.4  Functions

The following functions are used to implement shell features.

DragAcceptFiles
DragFinish
DragQueryFile
DragQueryPoint
ExtractIcon
FindExecutable
ShellExecute


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Screen Saver Library
  Chapter 79    Screen Saver Library

79.1  About Screen Savers

The Microsoft Win32 application programming interface (API) supports special applications called screen savers that start when the mouse and keyboard have been idle for a period of time. Screen savers exist for two main reasons:

•	To avoid phosphor burn caused by static images on a screen

•	To conceal sensitive information left on a screen

The Desktop application in Windows Control Panel lets users select from a list of screen savers, specify how much time should elapse before the screen saver is started, configure screen savers, and preview screen savers. Screen savers are loaded automatically when Windows starts or when a user activates the screen saver feature by using Control Panel.

Once a screen saver is chosen, Windows monitors keystrokes and mouse movements, starting the screen saver after a period of inactivity. However, Windows does not start the screen saver if any of the following conditions exist:

•	The active application is not a Windows-based application.

•	A computer-based training (CBT) window is present.

•	The active application returns a nonzero value in response to the WM_SYSCOMMAND message sent with the SC_SCREENSAVE identifier.

Screen savers contain specific exported functions, resource definitions, and variable declarations. The static-link library SCRNSAVE.LIB contains the main function and other startup code required for a screen saver. When a screen saver starts, the startup code in SCRNSAVE.LIB creates a full-screen window. The window class for this window is declared as follows.

WNDCLASS cls;

cls.hCursor        = NULL;

cls.hIcon          = LoadIcon(hInst, MAKEINTATOM(ID_APP));

cls.lpszMenuName   = NULL;

cls.lpszClassName  = "WindowsScreenSaverClass";

cls.hbrBackground  = GetStockObject(BLACK_BRUSH);

cls.hInstance      = hInst;

cls.style          = CS_VREDRAW | CS_HREDRAW

                     | CS_SAVEBITS | CS_DBLCLKS;

cls.lpfnWndProc    = (WNDPROC)ScreenSaverProc;

cls.cbWndExtra     = 0;

cls.cbClsExtra     = 0;

To create a screen saver, most developers create a source-code module containing three required functions and link them with SCRNSAVE.LIB. A screen saver module is responsible only for configuring itself and for providing visual effects.

One of the three required functions in a screen saver module is ScreenSaverProc. This function processes specific messages and passes any unprocessed messages back to SCRNSAVE.LIB. Some of the typical messages processed by ScreenSaverProc are shown in the following table.

Message	Meaning
WM_CREATE	Retrieve any initialization data from the file REGEDIT.INI. Set a window timer for the screen saver window. Perform any other required initialization.
WM_ERASEBKGND	Erase the screen saver window and prepare for subsequent drawing operations.
WM_TIMER	Perform drawing operations.
WM_DESTROY	Destroy the timer(s) created when the application processed the WM_CREATE message. Perform any additional required cleanup.
ScreenSaverProc passes unprocessed messages to SCRNSAVE.LIB by calling the DefScreenSaverProc function. The following table describes how this function processes various messages.

Message	Action
WM_SETCURSOR	Sets the cursor to the null cursor, removing it from the screen.
WM_PAINT	Paints the screen background.
WM_LBUTTONDOWN	Terminates the screen saver.
WM_MBUTTONDOWN	Terminates the screen saver.
WM_RBUTTONDOWN	Terminates the screen saver.
WM_KEYDOWN	Terminates the screen saver.
WM_MOUSEMOVE	Terminates the screen saver.
WM_ACTIVATE	If wParam is FALSE, terminates the screen saver.
The second required function in a screen saver module is ScreenSaverConfigureDialog. This function displays a dialog box that enables the user to configure the screen saver. (Thus, an application must provide a corresponding dialog box template.) Windows displays the configuration dialog box when the user chooses the Setup button in the Screen Saver box in the Desktop application in Control Panel. The data entered by the user with the configuration dialog box is stored in the REGEDIT.INI file.

The third required function in a screen saver module is RegisterDialogClasses. This function must be called by all screen saver applications. However, applications that do not require special windows or custom controls in the configuration dialog box can simply return TRUE. Applications requiring custom controls or special windows should use this function to register the corresponding window classes.

In addition to creating a module that supports the three functions just described, a screen saver should supply an icon. This icon is visible only when the screen saver is run as a stand-alone application. (To be run by Control Panel, a screen saver must have the .SCR filename extension; to be run as a stand-alone application, it must have the .EXE filename extension.) The icon must be identified in the screen saver's resource file by the constant ID_APP, which is defined in the header file SCRNSAVE.H.

One final requirement is a screen saver description string. The resource file for a screen saver must contain a descriptive string that Control Panel displays as the screen saver name. The description string must be the first string in the resource file's string table (identified with the ordinal value 1).


  79.2  Using the Screen Saver Functions

This section uses example code taken from a screen saver application to illustrate the following tasks:

•	Creating a screen saver

•	Creating a screen saver dialog box template

•	Supporting the screen saver window procedure

•	Creating a module-definition file

It also describes how to install new screen savers and add Help for a screen saver application.


  79.2.1  Creating a Screen Saver

This section contains example code taken from a screen saver application. At intervals ranging from 1 through 10 seconds, this application repaints the screen with one of four colors: white, light gray, dark gray, and black. The application paints the screen each time it receives a WM_TIMER message. The user can adjust the interval at which this message is sent by displaying the application's configuration dialog box and adjusting a single horizontal scroll bar. »This illustration« shows this dialog box.


  79.2.1.1  Supporting the Configuration Dialog Box

Most screen savers provide a configuration dialog box to let the user specify customization data such as unique colors, drawing speeds, line thicknesses, fonts, and so on. To support the configuration dialog box, the application must provide the necessary dialog box template and must also support the ScreenSaverConfigureDialog function. Following is the dialog box template for the sample application.

DLG_SCRNSAVECONFIGURE DIALOG 6, 18, 160, 63

LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

CAPTION "Sample Screen-Saver Setup"

FONT 8, "MS Sans Serif"

BEGIN

    GROUPBOX        "Redraw Speed", 101, 0, 6, 98, 40

    SCROLLBAR       ID_SPEED, 5, 31, 89, 10

    LTEXT           "Fast", 103, 6, 21, 20, 8

    LTEXT           "Slow", 104, 75, 21, 20, 8

    PUSHBUTTON      "OK", ID_OK, 117, 10, 40, 14

    PUSHBUTTON      "Cancel", ID_CANCEL, 117, 32, 40, 14

END

You must define the constant used to identify the dialog box template by using the decimal value 2003, as in the following example.

#define  DLG_SCRNSAVECONFIGURE 2003

The following example shows the ScreenSaverConfigureDialog function found in the sample application.

#define MINVEL  1               /* minimum redraw-speed value    */

#define MAXVEL  10              /* maximum redraw-speed value    */

#define DEFVEL  5               /* default redraw-speed value    */

LONG    lSpeed = DEFVEL;        /* redraw-speed variable         */

extern HINSTANCE hMainInstance; /* screen saver instance handle  */

CHAR   szAppName[80];           /* .INI section name             */

CHAR   szTemp[20];              /* temporary array of characters */

CHAR   szRedrawSpeed[] = "Redraw Speed";   /* .INI speed entry   */

BOOL WINAPI ScreenSaverConfigureDialog(hDlg, message, wParam, lParam)

HWND  hDlg;

UINT  message;

DWORD wParam;

LONG  lParam;

{

    static HWND hSpeed; /* handle of speed scroll bar */

    static HWND hOK;    /* handle of OK push button   */

    switch(message)

    {

        case WM_INITDIALOG:

            /* Retrieve the application-name string from the .RC file. */

            LoadString(hMainInstance, idsAppName, szAppName, 40);

            /* Retrieve the .INI (or registry) filename. */

            LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);

            /* Retrieve any redraw-speed data from the registry. */

            lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,

                DEFVEL, szIniFile);

            /*

             * If the initialization file does not contain an entry

             * for this screen saver, use the default value.

             */

            if(lSpeed > MAXVEL || lSpeed < MINVEL)

                lSpeed = DEFVEL;

            /* Initialize the redraw-speed scroll bar control. */

            hSpeed = GetDlgItem(hDlg, ID_SPEED);

            SetScrollRange(hSpeed, SB_CTL, MINVEL, MAXVEL, FALSE);

            SetScrollPos(hSpeed, SB_CTL, lSpeed, TRUE);

            /* Retrieve a handle of the OK push button control. */

            hOK = GetDlgItem(hDlg, ID_OK);

            return TRUE;

        case WM_HSCROLL:

            /*

             * Process scroll bar input, adjusting the lSpeed

             * value as appropriate.

             */

            switch (LOWORD(wParam))

                {

                    case SB_PAGEUP:

                        --lSpeed;

                    break;

                    case SB_LINEUP:

                        --lSpeed;

                    break;

                    case SB_PAGEDOWN:

                        ++lSpeed;

                    break;

                    case SB_LINEDOWN:

                        ++lSpeed;

                    break;

                    case SB_THUMBPOSITION:

                        lSpeed = HIWORD(wParam);

                    break;

                    case SB_BOTTOM:

                        lSpeed = MINVEL;

                    break;

                    case SB_TOP:

                        lSpeed = MAXVEL;

                    break;

                    case SB_THUMBTRACK:

                    case SB_ENDSCROLL:

                        return TRUE;

                    break;

                }

                if ((int) lSpeed <= MINVEL)

                    lSpeed = MINVEL;

                if ((int) lSpeed >= MAXVEL)

                    lSpeed = MAXVEL;

                SetScrollPos((HWND) lParam, SB_CTL, lSpeed, TRUE);

            break;

        case WM_COMMAND:

            switch(LOWORD(wParam))

            {

                case ID_OK:

                    /*

                    * Write the current redraw-speed variable to

                    * the .INI file.

                    */

                    wsprintf(szTemp, "%ld", lSpeed);

                    WritePrivateProfileString(szAppName, szRedrawSpeed,

                        szTemp, szIniFile);

                case ID_CANCEL:

                    EndDialog(hDlg, LOWORD(wParam) == ID_OK);

                return TRUE;

            }

    }

    return FALSE;

}

In addition to providing the dialog box template and supporting the ScreenSaverConfigureDialog function, an application must also support the RegisterDialogClasses function. This function registers any nonstandard window classes required by the screen saver. Because the sample application used only standard window classes in its dialog box procedure, this function simply returns TRUE, as in the following example.

BOOL WINAPI RegisterDialogClasses(hInst)

HANDLE  hInst;

{

    return TRUE;

}


  79.2.1.2  Supporting the Screen Saver Window Procedure

Each screen saver must support a window procedure named ScreenSaverProc. Like most window procedures, ScreenSaverProc processes a set of specific messages and passes any unprocessed messages to a default procedure. However, instead of passing them to the DefWindowProc function, ScreenSaverProc passes unprocessed messages to the DefScreenSaverProc function. Another difference between ScreenSaverProc and a normal window procedure is that the handle passed to ScreenSaverProc identifies the entire desktop rather than a client window. The following example shows the ScreenSaverProc window procedure for the sample screen saver.

#define MINVEL  1               /* minimum redraw-speed value    */

#define MAXVEL  10              /* maximum redraw-speed value    */

#define DEFVEL  5               /* default redraw-speed value    */

LONG    lSpeed = DEFVEL;        /* redraw-speed variable         */

extern HINSTANCE hMainInstance; /* screen saver instance handle  */

CHAR   szAppName[80];           /* .INI section name             */

CHAR   szTemp[20];              /* temporary array of characters */

CHAR   szRedrawSpeed[] = "Redraw Speed";   /* .INI speed entry   */

BOOL WINAPI ScreenSaverConfigureDialog(hDlg, message, wParam, lParam)

HWND  hDlg;

UINT  message;

DWORD wParam;

LONG  lParam;

{

    static HWND hSpeed; /* handle of speed scroll bar */

    static HWND hOK;    /* handle of OK push button   */

    switch(message)

    {

        case WM_INITDIALOG:

            /* Retrieve the application-name string from the .RC file. */

            LoadString(hMainInstance, idsAppName, szAppName, 40);

            /* Retrieve the .INI (or registry) filename. */

            LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);

            /* Retrieve any redraw-speed data from the registry. */

            lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,

                DEFVEL, szIniFile);

            /*

             * If the initialization file does not contain an entry

             * for this screen saver, use the default value.

             */

            if(lSpeed > MAXVEL || lSpeed < MINVEL)

                lSpeed = DEFVEL;

            /* Initialize the redraw-speed scroll bar control. */

            hSpeed = GetDlgItem(hDlg, ID_SPEED);

            SetScrollRange(hSpeed, SB_CTL, MINVEL, MAXVEL, FALSE);

            SetScrollPos(hSpeed, SB_CTL, lSpeed, TRUE);

            /* Retrieve a handle of the OK push button control. */

            hOK = GetDlgItem(hDlg, ID_OK);

            return TRUE;

        case WM_HSCROLL:

            /*

             * Process scroll bar input, adjusting the lSpeed

             * value as appropriate.

             */

            switch (LOWORD(wParam))

                {

                    case SB_PAGEUP:

                        --lSpeed;

                    break;

                    case SB_LINEUP:

                        --lSpeed;

                    break;

                    case SB_PAGEDOWN:

                        ++lSpeed;

                    break;

                    case SB_LINEDOWN:

                        ++lSpeed;

                    break;

                    case SB_THUMBPOSITION:

                        lSpeed = HIWORD(wParam);

                    break;

                    case SB_BOTTOM:

                        lSpeed = MINVEL;

                    break;

                    case SB_TOP:

                        lSpeed = MAXVEL;

                    break;

                    case SB_THUMBTRACK:

                    case SB_ENDSCROLL:

                        return TRUE;

                    break;

                }

                if ((int) lSpeed <= MINVEL)

                    lSpeed = MINVEL;

                if ((int) lSpeed >= MAXVEL)

                    lSpeed = MAXVEL;

                SetScrollPos((HWND) lParam, SB_CTL, lSpeed, TRUE);

            break;

        case WM_COMMAND:

            switch(LOWORD(wParam))

            {

                case ID_OK:

                   /*

                    * Write the current redraw-speed variable to

                    * the .INI file.

                    */

                    wsprintf(szTemp, "%ld", lSpeed);

                    WritePrivateProfileString(szAppName, szRedrawSpeed,

                        szTemp, szIniFile);

                case ID_CANCEL:

                    EndDialog(hDlg, LOWORD(wParam) == ID_OK);

                return TRUE;

            }

    }

    return FALSE;

}

LONG WINAPI ScreenSaverProc(hwnd, message, wParam, lParam)

HWND  hwnd;

UINT  message;

DWORD wParam;

LONG  lParam;

{

static HDC          hdc;    /* device-context handle */

static RECT         rc;     /* RECT structure        */

static UINT         uTimer; /* timer identifier      */

    switch(message)

    {

        case WM_CREATE:

            /* Retrieve the application-name string from the .RC file. */

            LoadString(hMainInstance, idsAppName, szAppName, 40);

            /* Retrieve the .INI (or registry) filename. */

            LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);

            /* Retrieve any redraw-speed data from the registry. */

            lSpeed = GetPrivateProfileInt(szAppName, szRedrawSpeed,

                DEFVEL, szIniFile);

           /*

            * Set a timer for the screen saver window using the

            * redraw-rate stored in REGEDIT.INI.

            */

            uTimer = SetTimer(hwnd, 1, lSpeed * 1000, NULL);

            break;

        case WM_ERASEBKGND:

           /*

            * The WM_ERASEBKGND message is issued before the

            * WM_TIMER message, allowing the screen saver to

            * paint the background as appropriate.

            */

            hdc = GetDC(hwnd);

            GetClientRect (hwnd, &rc);

            FillRect (hdc, &rc, GetStockObject(BLACK_BRUSH));

            ReleaseDC(hwnd,hdc);

            break;

        case WM_TIMER:

           /*

            * The WM_TIMER message is issued at (lSpeed * 1000)

            * intervals, where lSpeed == .001 seconds. This

            * code repaints the entire desktop with a white,

            * light gray, dark gray, or black brush each

            * time a WM_TIMER message is issued.

            */

            hdc = GetDC(hwnd);

            GetClientRect(hwnd, &rc);

            if (i++ <= 4)

                FillRect(hdc, &rc, GetStockObject(i));

            else

                (i = 0);

            ReleaseDC(hwnd,hdc);

            break;

        case WM_DESTROY:

           /*

            * When the WM_DESTROY message is issued, the screen saver

            * must destroy any of the timers that were set at WM_CREATE

            * time.

            */

            if (uTimer)

                KillTimer(hwnd, uTimer);

            break;

    }

   /*

    * DefScreenSaverProc processes any messages

    * ignored by ScreenSaverProc.

    */

    return DefScreenSaverProc(hwnd, message, wParam, lParam);

}


  79.2.1.3  Creating a Module-Definition File

The ScreenSaverProc and ScreenSaverConfigureDialog functions must be exported in the application's module-definition file; however, the RegisterDialogClasses function should not be exported. The following example shows the module-definition file for the sample application.

NAME    SSTEST.SCR

DESCRIPTION 'SCRNSAVE : Test'

STUB    'WINSTUB.EXE'

EXETYPE WINDOWS

CODE    MOVEABLE

DATA    MOVEABLE MULTIPLE

HEAPSIZE  1024

STACKSIZE 4096

EXPORTS

        ScreenSaverProc

        ScreenSaverConfigureDialog


  79.2.2  Installing New Screen Savers

When compiling the list of available screen savers, Control Panel searches the Windows startup directory for files with the .SCR extension. Because screen savers are standard Windows executable files with .EXE extensions, you must rename them so they have .SCR extensions and copy them to the correct directory.


  79.2.3  Adding Help

The configuration dialog box for a screen saver typically includes a Help button. Screen saver applications can check for the Help button identifier and call the WinHelp function in the same way Help is provided in other Windows-based applications.


  79.3  Functions

Following are the functions used with screen savers.

DefScreenSaverProc
RegisterDialogClasses
ScreenSaverConfigureDialog
ScreenSaverProc


File Installation Library
  Chapter 80    File Installation Library

80.1  About File Installation

The Microsoft Windows NT file installation library makes it easier for applications to install files properly and enables setup programs to analyze files currently installed.

The functions included in the file installation library determine where a file should be installed, identify conflicts with currently installed files, and perform the installation process. These functions enable installation programs to avoid the following problems:

•	Installing older versions of components over newer versions

•	Changing the language in a mixed-language system without notification

•	Installing multiple copies of a library in different directories

•	Copying files to network directories shared by multiple users

The file installation library also includes functions that enable applications to query a version resource for information about a file and present the information in a clear format. This information includes the file's purpose, author, version number, and so on.

Version information can be added to any Microsoft Windows file that can have Windows resources, such as a dynamic-link library (DLL), an executable file, or a font file. To add the information, a developer must create a version resource and add the resource to the file by using a resource compiler.

The file installation library (VER.DLL) and header file (VER.H) are available only for Windows-based applications.


  80.1.1  Creating an Installation Program

An installation program typically has the following goals:

•	To place files in the correct location.

•	To notify the user if the installation program is replacing an existing file with a version that is significantly different — for example, replacing a German-language file with an English-language file, or replacing a newer file with an older file.

When writing the installation program, the developer must have the following information for each file on the installation disk(s):

•	The name and location of the file (referred to as the source file).

•	The name of the equivalent file on the user's hard disk (referred to as the destination file). This name is usually the same as the filename on the installation disk.

•	The sharing status of the file — that is, whether the file is private to the application being installed or could be shared by multiple applications.

For each file on the installation disk(s), the installation program must, at a minimum, call the VerFindFile and VerInstallFile functions. These functions are described briefly in the following paragraphs.

The installation program can use VerFindFile with the destination-file name to determine where the file should be copied on the disk. This function can also be used to specify whether the file is private to the application or can be shared. If a problem occurs in finding the file, VerFindFile returns an error value. For example, if Windows is using the destination file, VerFindFile returns VFF_FILEINUSE. The installation program must notify the user of the problem and respond to the user's decision to continue or to end the installation.

VerInstallFile copies the source file to a temporary file in the directory specified by VerFindFile. If necessary, VerInstallFile expands the file by using the functions in the data decompression library, LZEXPAND.DLL.

VerInstallFile compares the version information of the temporary file to that of the destination file. If the two differ, VerInstallFile returns one or more error values. For example, it returns VIF_SRCOLD if the temporary file is older than the destination file and VIF_DIFFLANG if the files have different language identifiers or code-page values. The installation program must notify the user of the problem and respond to the user's decision to continue or to end the installation.

Some VerInstallFile errors are recoverable. That is, the installation program can call VerInstallFile again, specifying the VIFF_FORCEINSTALL option, to install the file regardless of the version conflict. If VerInstallFile returns VIF_TEMPFILE and the user chooses not to force the installation, the installation program should delete the temporary file.

VerInstallFile could encounter a nonrecoverable error when attempting to force installation, even though the error did not exist previously. For example, the file could be locked by another user before the installation program tried to force installation. If an installation program attempts to force installation after a non-recoverable error, VerInstallFile fails. The installation program must contain routines to recover from this type of error.

The recommended solution is to display for all errors a common dialog box with the buttons Install, Skip, and Install All. The Install All button should prevent the installation program from prompting the user about similar errors by including the VIFF_FORCEINSTALL option in all subsequent uses of VerInstallFile. For nonrecoverable errors, the Install and Install All buttons should be disabled.

To display a useful error message to the user, the installation program usually must retrieve information from the version resources of the conflicting files. The file installation library provides four functions the installation program can use for this purpose: the GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, and VerLanguageName functions. GetFileVersionInfoSize returns the size of the version information. GetFileVersionInfo uses information retrieved by GetFileVersionInfoSize to retrieve a structure that contains the version information. VerQueryValue retrieves a specific member from that structure.

For example, if VerInstallFile returns the VIF_DIFFTYPE error, the installation program should use the GetFileVersionInfoSize, GetFileVersionInfo, and VerQueryValue functions on the temporary and destination files to obtain the general type of each file. If the languages of the files conflict, the installation program should also use VerLanguageName to translate the binary language identifier into a text representation of the language. (For example, 0x040C translates to the string French.)

If VerInstallFile returns a file error, such as VIF_ACCESSVIOLATION, the installation program should use the GetLastError function to retrieve the most recent error value. The program should translate this value into an informative message to display to the user. The program must not yield control between the calls to VerInstallFile and GetLastError.


  80.2  Functions

Following are the functions used for file installation.

GetFileVersionInfo
GetFileVersionInfoSize
VerFindFile
VerInstallFile
VerLanguageName
VerQueryValue
GetFileResource (obsolete)
GetFileResourceSize (obsolete)


Data Decompression Library
  Chapter 81    Data Decompression Library

The Microsoft Windows operating system includes a dynamic-link library (DLL) named LZEXPAND.DLL. Typically, an application calls functions in LZEXPAND.DLL to decompress data previously compressed by using the Microsoft File Compression Utility (COMPRESS.EXE).

This chapter describes important concepts relating to data compression and describes the decompression functions in LZEXPAND.DLL.


  81.1  Data Compression

Data compression is an operation that reduces the size of a file by minimizing redundant data. In a file that contains text, redundant data can be frequently occurring characters, such as the space character, or common vowels, such as the letters e and a; it can also be frequently occurring character strings. Data compression creates a compressed version of a file by minimizing this redundant data.

Each type of data-compression algorithm minimizes redundant data in a unique manner. For example, the Huffman encoding algorithm assigns a code to characters in a file based on how frequently those characters occur. Another compression algorithm, called run-length encoding, generates a two-part value for repeated characters: the first part specifies the number of times the character is repeated, and the second part identifies the character. Another compression algorithm, known as the Lempel-Ziv algorithm, converts variable-length strings into fixed-length codes that consume less space than the original strings.

To compress large applications or data files, you can run COMPRESS.EXE from the command line. COMPRESS.EXE uses the Lempel-Ziv compression algorithm.


  81.2  Data Decompression

Applications can call the functions in LZEXPAND.DLL to decompress files compressed by using COMPRESS.EXE. The functions can also process uncompressed files without attempting to decompress them. To use these functions, applications must include the LZEXPAND.H header file.

The following table describes each function found in LZEXPAND.DLL.

Function	Purpose
CopyLZFile	This function is obsolete. It is provided only for backwards compatibility. Win32 applications should use the LZCopy function.
GetExpandedName	Retrieves the original name of a compressed file, if the /r option was used during compression of the file.
LZClose	Closes a file that was opened when the application called the LZOpenFile function.
LZCopy	Copies a source file to a destination file. If the source file is compressed, this function creates a decompressed destination file. If the source file is not compressed, this function duplicates the original file. This function is intended for single-file copy operations.
LZDone	This function is obsolete. It is provided only for backwards compatibility. Win32 applications should not use this function.
LZInit	Creates structures used for decompressing files.
LZOpenFile	Opens a file and returns a handle that identifies it.
LZRead	Reads a specified number of bytes from a file. If the file is compressed, this function decompresses the bytes before copying them to the destination buffer.
LZSeek	Positions the file pointer within the decompressed image of a compressed file. The application calls this function to position the pointer before calling the LZRead function.
LZStart	This function is obsolete. It is provided only for backwards compatibility. Win32 applications should not use it.


  81.3  Using the Data Decompression Library

Functions in LZEXPAND.DLL can be used to decompress single or multiple files. They can also be used to decompress compressed files a portion at a time.


  81.3.1  Decompressing a Single File

An application can decompress a single compressed file by performing the following tasks.

1.	Open the source file by calling the LZOpenFile function.

2.	Open the destination file by calling LZOpenFile.

3.	Copy the source file to the destination file by calling the LZCopy function and passing the handles returned by LZOpenFile.

4.	Close the files by calling the LZClose function.


  81.3.2  Decompressing Multiple Files

An application can decompress multiple files by performing the following tasks.

1.	Open the source files by calling the LZOpenFile function.

2.	Open the destination files by calling LZOpenFile.

3.	Copy the source files to the destination files by calling the LZCopy function.

4.	Close the files by calling the LZClose function.


  81.3.3  Reading Bytes from Compressed Files

In addition to decompressing a complete file in a single operation, an application can decompress a compressed file a portion at a time by using the LZSeek and LZRead functions. These functions are particularly useful when it is necessary to extract parts of large files. For example, a font manufacturer may have compressed files containing font metrics in addition to character data. To use the information in these files, an application would need to decompress the file; however, most applications would use only part of the file at any particular time. To get information about font metrics, the application would extract data from the header. To get information from the text, the application would reposition the file pointer by calling LZSeek and extract character data by calling LZRead.


  81.4  Functions

Following are the functions used to decompress files.

GetExpandedName
LZClose
LZCopy
LZInit
LZOpenFile
LZRead
LZSeek


Control Panel Applications
  Chapter 82    Control Panel Applications

82.1  About Control Panel

This chapter describes Microsoft Windows Control Panel (CONTROL.EXE) and explains how to create a Control Panel application and add it to Control Panel.

Control Panel provides a window for running applications used to configure the Windows environment. A number of standard applications are included with Windows. However, additional applications can be created and added to Control Panel. You can use this capability to modify environmental factors unique to specific hardware and software. »This illustration« shows the Control Panel window.

An application is contained in a dynamic-link library (DLL). A DLL can support more than one Control Panel application.

Control Panel loads Control Panel application libraries in this order:

1.	The library containing the standard Control Panel applications.

2.	Libraries with the .CPL filename extension residing in the Windows SYSTEM directory.

3.	Libraries specified by the MMCPL key of the HKEY_CURRENT_USER key in the registry. For more information about registry, see Chapter 52, »Registry and Initialization Files«.

4.	Libraries with the .CPL filename extension residing in the same directory as the CONTROL.EXE file.


  82.2  Starting a Control Panel Application

There are three ways to start a Control Panel application:

•	The user can open Control Panel and start an application by double-clicking the application icon.

•	The user or an application can open Control Panel by using a command-line argument that specifies the filename of the application to start. When the application closes, Control Panel also closes.

•	An application can send a WM_CPL_LAUNCH message to Control Panel while Control Panel is running. When the Control Panel application closes, Control Panel sends back a WM_CPL_LAUNCHED confirmation message.

The following code sample shows how an application can start Control Panel and the Sound application by using the WinExec function and a command-line argument.

WinExec("control.exe sound", SW_SHOWNORMAL)

When Control Panel starts, it immediately displays the Sound application. After the Sound application is closed, Control Panel closes.

The following code sample shows a function that starts a Control Panel application by using the WM_CPL_LAUNCH message.

#include <windows.h>    /* required for all Windows applications */

HANDLE hinst;

BOOL StartApplet(LPSTR lpszName, HWND hwndMine)

{

    HGLOBAL hglbAppletName;   /* handle of application name     */

    HWND hwndCPL;             /* handle of Control Panel window */

    LPSTR lpszAppletName;     /* name of application            */

    BOOL fStartedCPL = FALSE; /* application started?           */

    CHAR szName[] = "printers.cpl"; /* application name         */

    /*

     * Allocate a shareable memory block to hold the

     * application name string.

     */

    hglbAppletName = GlobalAlloc(GMEM_MOVEABLE,

        lstrlen(szName) + 1);

    if (hglbAppletName == NULL)

        return FALSE;

    lpszAppletName = GlobalLock(hglbAppletName);

    lstrcpy(lpszAppletName, szName);

    GlobalUnlock(hglbAppletName);

    /*

     * Get the Control Panel window handle and start Control Panel,

     * if necessary.

     */

    if ((hwndCPL = FindWindow("CtlPanelClass",

            "Control Panel")) == NULL) {

        WinExec("control.exe", SW_SHOWNA);

        hwndCPL = FindWindow("CtlPanelClass", "Control Panel");

        if (hwndCPL == NULL) {

            GlobalFree(hglbAppletName);

            return FALSE;

        }

        fStartedCPL = TRUE;

    }

    /* Start the application and end Control Panel, if started. */

    SendMessage(hwndCPL, WM_CPL_LAUNCH, (WPARAM) hwndMine,

        (LPARAM) lpszAppletName);

    if (fStartedCPL)

        SendMessage(hwndCPL, WM_CLOSE, 0, 0);

    GlobalFree(hglbAppletName);

    return TRUE;

}


  82.3  Creating a Control Panel Application

A Control Panel application must reside in a DLL that includes a standard entry-point function named CPlApplet. The application must include the CPL.H header file for the definition of Control Panel messages. Control Panel communicates with the DLL by sending the following CPL messages to the CPlApplet function.

Message	Description
CPL_DBLCLK	Sent when the user double-clicks an application icon. In response to this message, the DLL starts its configuration process, usually displaying a dialog box.
CPL_EXIT	Sent after the last CPL_STOP message and immediately before Control Panel calls the FreeLibrary function for the DLL. In response to this message, the DLL frees any remaining memory and prepares to close.
CPL_GETCOUNT	Sent after the CPL_INIT message, to prompt the DLL to return a number indicating how many applications it services.
CPL_INIT	Sent immediately after the DLL is loaded, to prompt the DLL to perform initialization procedures, including memory allocation.
CPL_INQUIRE	Sent after the CPL_GETCOUNT message, to prompt the DLL to provide information about each application. The handler for this message is a good place to include any initialization required by individual applications.
CPL_NEWINQUIRE	Sent to a Control Panel DLL to request information about an application the DLL supports. The CPL_NEWINQUIRE message is the same as the CPL_INQUIRE message except that its second parameter (lParam2) is a pointer to a NEWCPLINFO structure instead of a CPLINFO structure. Use CPL_NEWINQUIRE instead of CPL_INQUIRE in new applications.
CPL_SELECT	Sent when the user selects an application icon.
CPL_STOP	Sent once for each application before Control Panel closes. In response to this message, the DLL frees any memory associated with the individual application for which the message is sent.


  82.3.1  Creating the Entry-Point Function

Control Panel communicates with an application DLL through the CPlApplet function. Make sure to export this function by listing it in the EXPORTS statement of your module-definition (.DEF) file. The CPlApplet function handles the messages listed previously, performing three main tasks.

Task	Result
Initializing the application (CPL_INIT, CPL_NEWINQUIRE)	Allocates necessary memory and gives Control Panel the information for displaying the application icon.
Running the application (CPL_DBLCLK)	Passes control to a dialog box and its associated message processor.
Closing the application (CPL_STOP, CPL_EXIT)	Frees any memory allocated and prepares to close.
The CPlApplet function has the following syntax:

LONG CALLBACK* CPlApplet(hwndCPL, uMsg, lParam1, lParam2)

The hwndCPL parameter contains the handle of the Control Panel window. The uMsg parameter contains one of the CPL messages listed previously. The lParam1 and lParam2 parameters contain message-dependent values.


  82.3.2  Initializing the Application

To initialize a Control Panel application, Control Panel sends the CPL_INIT message first to the CPlApplet function, which prompts the application DLL to perform initialization procedures. If initialization succeeds, CPlApplet returns nonzero.

If CPlApplet returns zero in response to the CPL_INIT message, Control Panel calls the FreeLibrary function and ends communication with the application DLL. This is the only way an application can notify Control Panel of initialization problems and prevent the application from being loaded.

If initialization succeeds, Control Panel sends the CPL_GETCOUNT message. The CPlApplet function responds by returning the number of applications serviced by the application DLL. This number determines how many icons Control Panel displays for the DLL.

After Control Panel finds out the number of applications serviced by the DLL, it sends the CPL_NEWINQUIRE message once for each application. The lParam1 parameter specifies the application number — 0 for the first application and CPL_GETCOUNT − 1 for the last application.

Control Panel passes a far pointer to a NEWCPLINFO structure in the lParam2 parameter. The NEWCPLINFO structure has the following form.

typedef struct tagNEWCPLINFO /* ncpli */

{

    DWORD dwSize;          /* length of structure, in bytes     */

    DWORD dwFlags;         /* setup flags                       */

    DWORD dwHelpContext;   /* help-context number               */

    LONG  lData;           /* application-defined data          */

    HICON hIcon;           /* handle of icon (owned by CPL.EXE) */

    char  szName[32];      /* short-name string                 */

    char  szInfo[64];      /* description string (status line)  */

    char  szHelpFile[128]; /* path to help file                 */

} NEWCPLINFO;

The CPlApplet function must fill in the NEWCPLINFO structure. The function must assign values for the dwSize, hIcon, szName, and szInfo members for the structure size, application icon, short name, and description, respectively. To add a keyboard accelerator for the application, precede the selected accelerator character in the szName string with an ampersand. If the application DLL supports context-sensitive Help, the CPlApplet function should also assign the values for the dwHelpContext and szHelpFile members. The lData member can be used for application-defined data.

Note   The CPL_NEWINQUIRE message and NEWCPLINFO structure replace the CPL_INQUIRE message and CPLINFO structure. The latter have been retained for backward compatibility with Windows 3.x. If the application DLL does not respond to the CPL_NEWINQUIRE message, Control Panel sends it the CPL_INQUIRE message. Then the lParam2 parameter points to a CPLINFO structure rather than to a NEWCPLINFO structure.


  82.3.3  Responding to User Actions

Control Panel sends the CPL_SELECT or CPL_DBLCLK message when the user selects or double-clicks an application icon. For each message, Control Panel passes the application number in the lParam1 parameter and the lData value in the lParam2 parameter.

Typically, an application DLL does not respond to the CPL_SELECT message. Upon receiving the CPL_DBLCLK message, the application transfers control to the appropriate dialog box.


  82.3.4  Closing the Application and the Dynamic-Link Library

Before closing, Control Panel sends the CPL_STOP message once for each application in the DLL. lParam1 and lParam2 sent with the CPL_STOP message correspond to the application number and the lData value. After Control Panel sends the last CPL_STOP message, it sends a CPL_EXIT message and then calls the FreeLibrary function to free the DLL.

When the CPL_STOP and CPL_EXIT cases are executed, the DLL frees memory that it allocated. Typically, the DLL frees memory associated with individual applications when the CPL_STOP case is executed and frees any other allocated memory when the CPL_EXIT case is executed. The DLL also unregisters any private window classes that it registered during the CPL_INIT message.


  82.3.5  Example of a Control Panel Application

The following code sample shows the CPlApplet function for a DLL containing three Control Panel applications that set preferences for a component stereo system attached to the computer.

The sample uses an application-defined StereoApplets array that contains three structures, each corresponding to one of the Control Panel applications. Each structure contains all the information required by the CPL_INQUIRE message, as well as the dialog box template and dialog box procedure required by the CPL_DBLCLK message. The code demonstrates how to fill the structures in the StereoApplets array.

#define NUM_APPLETS 3

typedef struct tagApplets

{

    int icon;         /* icon resource identifier                */

    int namestring;   /* name-string resource identifier         */

    int descstring;   /* description-string resource identifier  */

    int dlgtemplate;  /* dialog box template resource identifier */

    DLGPROC dlgfn;    /* dialog box procedure                    */

} APPLETS;

APPLETS StereoApplets[NUM_APPLETS] =

{

    AMP_ICON, AMP_NAME, AMP_DESC, AMP_DLG, AmpDlgProc,

    TUNER_ICON, TUNER_NAME, TUNER_DESC, TUNER_DLG, TunerDlgProc,

    TAPE_ICON, TAPE_NAME, TAPE_DESC, TAPE_DLG, TapeDlgProc,

};

This code defines the CPlApplet function for the preceding example.

LONG CALLBACK CPlApplet(hwndCPL, uMsg, lParam1, lParam2)

HWND hwndCPL;      /* handle of Control Panel window */

UINT uMsg;         /* message                        */

LPARAM lParam1;    /* first message parameter        */

LPARAM lParam2;    /* second message parameter       */

{

    int i;

    LPNEWCPLINFO lpNewCPlInfo;

    i = (int) lParam1;

    switch (uMsg) {

        case CPL_INIT:      /* first message, sent once  */

            hinst = GetModuleHandle("ecp.cpl");

            return TRUE;

        case CPL_GETCOUNT:  /* second message, sent once */

            return NUM_APPLETS;

            break;

        case CPL_NEWINQUIRE: /* third message, sent once per app */

            lpNewCPlInfo = (LPNEWCPLINFO) lParam2;

            lpNewCPlInfo->dwSize = (DWORD) sizeof(NEWCPLINFO);

            lpNewCPlInfo->dwFlags = 0;

            lpNewCPlInfo->dwHelpContext = 0;

            lpNewCPlInfo->lData = 0;

            lpNewCPlInfo->hIcon = LoadIcon(hinst,

                (LPCTSTR) MAKEINTRESOURCE(StereoApplets[i].icon));

            lpNewCPlInfo->szHelpFile[0] = '\0';

            LoadString(hinst, StereoApplets[i].namestring,

                lpNewCPlInfo->szName, 32);

            LoadString(hinst, StereoApplets[i].descstring,

                lpNewCPlInfo->szInfo, 64);

            break;

        case CPL_SELECT:    /* application icon selected */

            break;

        case CPL_DBLCLK:    /* application icon double-clicked */

            MessageBeep(MB_ICONEXCLAMATION);

            DialogBox(hinst,

                MAKEINTRESOURCE(StereoApplets[i].dlgtemplate),

                hwndCPL, StereoApplets[i].dlgfn);

            break;

        case CPL_STOP:      /* sent once per app. before CPL_EXIT */

            break;

        case CPL_EXIT:    /* sent once before FreeLibrary called */

            break;

        default:

            break;

    }

    return 0;

}


  82.4  Setting Up a New Application

There are three ways to register an application DLL with Control Panel:

•	List the DLL in the MMCPL key of the HKEY_CURRENT_USER key in the registry. Use this method when the DLL is part of a system library and processes more than just messages from Control Panel. For more information about the registry, see Chapter 52, »Registry and Initialization Files«.

•	Assign the DLL a .CPL filename extension and add it to the directory that contains the CONTROL.EXE file.

•	Assign the DLL a .CPL filename extension and add it to the Windows SYSTEM directory.


  82.5  Functions and Messages

Following are the functions and messages used by Control Panel applications.


  Functions

CPlApplet


  Messages

CPL_DBLCLK
CPL_EXIT
CPL_GETCOUNT
CPL_INIT
CPL_INQUIRE
CPL_NEWINQUIRE
CPL_SELECT
CPL_STOP
WM_CPL_LAUNCH
WM_CPL_LAUNCHED


File Manager Extensions
  Chapter 83    File Manager Extensions

83.1  About File Manager Extensions

In Microsoft Windows, a File Manager extension is a dynamic-link library (DLL) that adds a menu and buttons to File Manager. A File Manager extension can also display (in the status bar) Help text for the buttons.

File Manager maintains a list of extensions in an initialization file and loads the extensions when starting. An extension DLL contains an entry point that processes menu commands and notification messages sent by File Manager. Up to five extension DLLs can be installed at any one time. This chapter describes how to create and install extensions for File Manager.


  83.1.1  Creating a File Manager Extension

A File Manager extension must reside in a DLL that includes a standard entry point, the FMExtensionProc callback function. The extension must include the WFEXT.H header file that defines File Manager messages and structures. File Manager communicates with the extension DLL by sending the following messages to the DLL's FMExtensionProc function.

Message	Meaning
1−99	User has selected an item from the extension-supplied menu. The value is the identifier of the selected menu item.
FMEVENT_INITMENU	User has selected the extension's menu. The extension should initialize items in the menu.
FMEVENT_LOAD	File Manager is loading the extension DLL and prompts the DLL for information about the menu that the DLL supplies.
FMEVENT_SELCHANGE	Selection in the File Manager directory window or Search Results window has changed.
FMEVENT_TOOLBARLOAD	File Manager is creating the toolbar and prompts the extension DLL for information about any buttons the DLL adds to the toolbar.
FMEVENT_UNLOAD	File Manager is unloading the extension DLL.
FMEVENT_USER_REFRESH	User has chosen the Refresh command from the Window menu. The extension should update items in the menu, if necessary.


  83.1.1.1  Creating the Entry-Point Function

File Manager communicates with an extension DLL through the FMExtensionProc callback function. Make sure to export this function by listing it in the EXPORTS statement of your extension's module-definition (.DEF) file. The FMExtensionProc function handles the messages listed in the preceding section by performing the tasks listed in the following table.

Task	Action
Initializing the extension (FMEVENT_LOAD)	Provides File Manager with the name and handle of the menu and saves the menu-item delta value.
Initializing the menu (FMEVENT_INITMENU)	Initializes all top-level menu items and the items in any submenus.
Initializing the toolbar (FMEVENT_TOOLBARLOAD)	Provides File Manager with information about the buttons to add to the toolbar, including the command identifier, Help string identifier, styles, and bitmap identifier.
Processing menu selections	Carries out commands that the user chooses from the extension's menu.
Processing file selections (FMEVENT_SELCHANGE)	Queries File Manager for information about the file that the user has selected from the directory window or Search Results window.
Updating items in the menu (FMEVENT_USER_REFRESH)	Modifies the menu as appropriate when the user chooses File Manager's Refresh command from the Window menu.
Providing menu item help strings (FMEVENT_HELPSTRING)	Provides File Manager with a help string for a specified command in a specified menu. File Manager displays this string in the area at the bottom left of the window.
Passing menu item help requests on to WinHelp (FMEVENT_HELPMENUITEM)	Provides WinHelp with the window passed by File Manager and menu item information,
Quitting the extension DLL (FMEVENT_UNLOAD)	Frees any memory allocated and prepares to exit.
The FMExtensionProc function is defined as follows.

LONG WINAPI FMExtensionProc(hwnd, wMsg, lParam)

HWND hwnd;

WORD wMsg;

LONG lParam;

The hwnd parameter identifies the File Manager window. An extension should use this window handle to specify the parent window for any dialog box or message box it must display. It should also use this handle to send query messages to File Manager. The uMsg parameter contains one of the File Manager messages listed previously. The lParam parameter contains a message-dependent value. The return value from the FMExtensionProc function depends on the value of the uMsg parameter.

The menu added to File Manager may be a hierarchical (cascaded) menu and may contain grayed, disabled, or checked menu items in addition to command items. Menu items should be text only; owner-drawn menus and bitmap menus are not supported. Changing the bitmap for check marks is not supported.

Whenever File Manager calls the FMExtensionProc function, it waits to refresh its directory windows (for changes in the file system) until after the function returns. This allows the extension to perform large numbers of file operations without excessive repainting on the part of File Manager. It is not necessary for the extension to send the FM_REFRESH_WINDOWS message to notify File Manager to repaint its directory windows. For more information about FM_REFRESH_WINDOWS, see Section 83.1.3, »Extension Messages«.


  83.1.1.2  Loading the Extension

File Manager first sends the FMEVENT_LOAD message to the FMExtensionProc function. The lParam parameter accompanying the FMEVENT_LOAD message points to an FMS_LOAD structure that File Manager uses to obtain information about the extension-supplied menu, including the menu name and menu handle. For a description of the FMS_LOAD structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

File Manager also uses the FMS_LOAD structure to pass the menu-item delta value to the extension. To avoid conflicts with its own menu-item identifiers, File Manager renumbers the menu-item identifiers in an extension-supplied menu by adding the delta value to each identifier. An extension DLL that must modify its menu after File Manager has loaded it must use the delta value. For example, to delete a menu item, the extension DLL finds the sum of the delta value and the menu-item identifier and passes it as the idItem parameter to the DeleteMenu function.

If an extension returns FALSE in response to this message, File Manager calls the FreeLibrary function and ends any communication with the extension DLL. This is the only place where an extension can notify File Manager of initialization problems and thus prevent the extension from being loaded.


  83.1.1.3  Adding Custom Buttons

A File Manager extension can add custom buttons to the File Manager toolbar by returning button information in response to the FMEVENT_TOOLBARLOAD message. File Manager sends this message to the FMExtensionProc function of the extension only if the extension successfully installed a custom menu during the processing of the FMEVENT_LOAD message. Use custom buttons as accelerator keys for menu commands specified in the custom menu.

When FMExtensionProc receives the FMEVENT_TOOLBARLOAD message, the lParam parameter points to an FMS_TOOLBARLOAD structure. The File Manager extension must copy information about the custom buttons to the structure, including the number of buttons and a specifier for the bitmap containing the button images (either the identifier for a bitmap resource or a handle to a memory bitmap). The extension must also include the address of an array of EXT_BUTTON structures, each of which must contain a command identifier for the corresponding button. If the button is an accelerator for a menu command, the button identifier and corresponding menu-command identifier must be equal. For a description of the FMS_TOOLBARLOAD and EXTBUTTON structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

The bitmap containing the button images must be a bitmap resource or a memory bitmap. The extension must copy either the resource identifier or the memory bitmap's handle to the FMS_TOOLBARLOAD structure; and, in the case of a bitmap resource, the resource must be in the extension's executable file.

The bitmap must contain one image for each specified button. The bitmap height is always 15 pixels; the width is always a multiple of 16 pixels because each button image must be 16 pixels wide. Button images are concatenated from left to right. For example, the image of the first button specified in the array of EXT_BUTTON structures must be the leftmost image in the bitmap.

An extension can provide a line of Help text for a button by specifying the identifier of a string resource in the idsHelp member of the EXT_BUTTON structure. When the user selects the button, File Manager retrieves the string resource and displays it on the toolbar.


  83.1.1.4  Processing Menu Selections

The menu resource that you define for your extension's menu must use menu-item identifiers in the range 1 through 99. When the user selects an item, the extension receives a command notification that is the identifier of the selected item as defined in the resource-definition file (which has the .RC filename extension). The command notification is not the sum of the delta value and the identifier. An extension DLL's FMExtensionProc function carries out commands by processing command notifications.


  83.1.1.5  Initializing the Extension Menu

Whenever the user selects the extension's main menu item from File Manager's menu bar, File Manager sends the FMEVENT_INITMENU message to the extension DLL. An extension can use this message to initialize its menu items. For example, an extension can add check marks, disable items, or gray items during this message.

When the user selects submenus within the extension's menu, File Manager does not send the FMEVENT_INITMENU message. An extension DLL must initialize all items at the same time, including those in submenus.


  83.1.1.6  Updating the Extension Menu

When the user chooses the Refresh command from the Window menu, File Manager sends an FMEVENT_USER_REFRESH message to an extension DLL. The extension can use this opportunity to update its menu items.


  83.1.1.7  Processing File Selections

When the user selects a filename in the directory window or in the Search Results window, File Manager sends the FMEVENT_SELCHANGE message to an extension DLL. The extension can use this opportunity to send a query message to File Manager to obtain more information about the user's selection. For more information, see Section 83.1.3, »Extension Messages«.

Because the user can change the selection often, the extension should return promptly after processing the FMEVENT_SELCHANGE message to avoid slowing the user's selection process.


  83.1.1.8  Quitting the Extension Dynamic-Link Library

When File Manager quits, it sends the FMEVENT_UNLOAD message to each extension DLL and then calls the FreeLibrary function to free the DLLs. Each DLL should free any memory that it has allocated.


  83.1.2  Installing Extensions

File Manager installs extensions that have settings in the [AddOns] section of the WINFILE.INI initialization file. Each setting contains an entry and a value. An entry consists of a string that represents the name of an extension. The value assigned to the entry consists of a string that specifies the path to the extension DLL. An application can use the WritePrivateProfileString function to add a setting to WINFILE.INI. The following example shows a setting in WINFILE.INI.

[AddOns]

MyExtension=C:\WINDOWS\SYSTEM32\MYEXT.DLL

File Manager does not display an error message if it cannot find an extension DLL, so an extension DLL can be deleted in order to uninstall it. Even so, an application that installs an extension DLL should provide an uninstall option to remove the extension's setting from the WINFILE.INI file.


  83.1.3  Extension Messages

An extension can send the following window messages to retrieve relevant information from File Manager. File Manager is guaranteed to respond correctly only to messages sent from the FMExtensionProc function.

Message	Description
FM_GETDRIVEINFO	File Manager returns drive information from the active window. An extension provides a pointer to an FMS_GETDRIVEINFO structure; File Manager fills the structure with drive information.
FM_GETFILESEL	File Manager returns information about a selected file from the active File Manager window (either the directory window or the Search Results window). An extension provides a pointer to an FMS_GETFILESEL structure; File Manager fills the structure with file information.
FM_GETFILESELLFN	Same as the FM_GETFILESEL message except that the selected file may have a long filename.
FM_GETFOCUS	File Manager returns a value that identifies the type of window with input focus.
FM_GETSELCOUNT	File Manager returns the count of selected files in the directory and Search Results windows.
FM_GETSELCOUNTLFN	Same as the FM_GETSELCOUNT message except that the count includes files with long filenames.
FM_REFRESH_WINDOWS	File Manager repaints either its active window or all of its windows. This message is similar to File Manager's Refresh command on the Window menu.
FM_RELOAD_EXTENSIONS	File Manager reloads all extensions. First, File Manager unloads all extensions, sending an FMEVENT_UNLOAD message to each extension. Then, it reloads the extensions, sending an FMEVENT_LOAD message to each extension. The FM_RELOAD_EXTENSIONS message allows an extension to uninstall itself by removing its setting from the WINFILE.INI file; this action causes File Manager to reload the remaining extensions. Other applications and programs (for example, installation programs) can also post this message by calling the PostMessage function.


  83.1.4  Processing Commands and Messages from File Manager

The following code shows the FMExtensionProc function for a sample extension DLL. It demonstrates how an extension processes the menu commands and notification messages sent by File Manager.

HINSTANCE hinst;

HMENU hmenu;

WORD wMenuDelta;

BOOL fMultiple = FALSE;

BOOL fLFN = FALSE;

LONG WINAPI FMExtensionProc(hwnd, wMsg, lParam)

HWND hwnd;

WORD wMsg;

LONG lParam;

{

    CHAR szBuf[200];

    INT count;

    switch (wMsg) {

   case FMEVENT_LOAD:

       #define lpload  ((LPFMS_LOAD) lParam)

       /* Save the menu-item delta value. */

       wMenuDelta = lpload->wMenuDelta;

       /* Fill the FMS_LOAD structure. */

       lpload->dwSize = sizeof(FMS_LOAD);

       lstrcpy(lpload->szMenuName, "&Extension");

       /* Return the handle of the menu. */

       hinst = GetModuleHandle("ext.dll");

       lpload->hMenu = GetSubMenu(LoadMenu(hinst,

      MAKEINTRESOURCE(MYMENU)), 0);

       return (LONG)TRUE;

   case FMEVENT_UNLOAD:

       /* Perform any cleanup procedures here. */

       break;

   case FMEVENT_INITMENU:

       /* Copy the menu handle. */

       hmenu = (HMENU) lParam;

       /*

        * Add check marks to menu items as appropriate.

        * Add menu-item delta values to menu-item

        * identifiers to specify the menu items to check.

        */

       CheckMenuItem(hmenu, wMenuDelta + IDM_MULTIPLE,

      fMultiple ? MF_BYCOMMAND | MF_CHECKED :

             MF_BYCOMMAND | MF_UNCHECKED);

       CheckMenuItem(hmenu, wMenuDelta + IDM_LFN,

      fLFN ? MF_BYCOMMAND | MF_CHECKED :

             MF_BYCOMMAND | MF_UNCHECKED);

       break;

   case FMEVENT_TOOLBARLOAD:

   {

       static EXT_BUTTON extbtn[] = {

          {1, 0, 0},

       };

            /* Fill the FMS_TOOLBARLOAD structure. */

       #define lptbld ((LPFMS_TOOLBARLOAD) lParam)

       lptbld->dwSize = sizeof(FMS_TOOLBARLOAD);

       lptbld->lpButtons = (LPEXT_BUTTON) &extbtn;

       lptbld->cButtons = 1;

       lptbld->cBitmaps = 1;

       lptbld->idBitmap = ID_BUTTONBITMAP;

       return (LONG)TRUE;

   }

   case FMEVENT_USER_REFRESH:

            MessageBox(hwnd, "User refresh event",

                "Hey!", MB_OK);

       break;

   case FMEVENT_SELCHANGE:

       break;

        /*

         * The following messages are generated when the user

         * chooses items from the extension menu.

         */

   case FMEVENT_HELPSTRING:

       #define lphs ((LPFMS_HELPSTRING)lParam)

       if (lphs->idCommand == -1)

          lstrcpy(lphs->szHelp, "Help for extension menu");

       else

          wsprintf(lphs->szHelp, "Help for item %d", lphs->idCommand);

       break;

   case FMEVENT_HELPMENUITEM:

       wsprintf(szBuf, "Help for %d", lParam);

       MessageBox(hwnd, szBuf, "WinHelp call", MB_OK);

       /*

        * Use: WinHelp(hwnd, "ExtHelp.hlp", HELP_CONTEXT, lParam);

        */

       break;

   case IDM_GETFOCUS:

       wsprintf(szBuf, "Focus %d", (INT) SendMessage(hwnd,

      FM_GETFOCUS, 0, 0));

       MessageBox(hwnd, szBuf, "Focus", MB_OK);

       break;

   case IDM_GETCOUNT:

       count = (INT) SendMessage(hwnd,

                fLFN ? FM_GETSELCOUNTLFN : FM_GETSELCOUNT,

                0, 0);

       wsprintf(szBuf, "%d files selected", count);

       MessageBox(hwnd, szBuf, "Selection Count", MB_OK);

       break;

   case IDM_GETFILE:

   {

       FMS_GETFILESEL file;

       count = (INT) SendMessage(hwnd,

      fLFN ? FM_GETSELCOUNTLFN : FM_GETSELCOUNT,

      FMFOCUS_DIR, 0);

       while (count >= 1) {

                /*

                 * Selection indices are zero-based (0 is

                 * first).

                 */

      count--;

      SendMessage(hwnd, FM_GETFILESEL, count,

          (LONG) (LPFMS_GETFILESEL) &file);

      wsprintf(szBuf, "file %s\nSize %ld",

          (LPSTR) file.szName, file.dwSize);

                MessageBox(hwnd, szBuf, "File Information",

                    MB_OK);

      if (!fMultiple)

         break;

       }

       break;

   }

   case IDM_GETDRIVE:

   {

       FMS_GETDRIVEINFO drive;

       SendMessage(hwnd, FM_GETDRIVEINFO, 0,

      (LONG) (LPFMS_GETDRIVEINFO)&drive);

       wsprintf(szBuf,

                "%s\nFree %ld\nTotal %ld\nVolume %s\nShare %s",

      (LPSTR) drive.szPath, drive.dwFreeSpace,

      drive.dwTotalSpace, (LPSTR) drive.szVolume,

      (LPSTR) drive.szShare);

       MessageBox(hwnd, szBuf, "Drive Info", MB_OK);

       break;

   }

   case IDM_LFN:

       MessageBox(hwnd, "IDM_LFN", "Hi", MB_OK);

       fLFN = !fLFN;

       break;

   case IDM_MULTIPLE:

       MessageBox(hwnd, "IDM_MULTIPLE", "Hi", MB_OK);

       fMultiple = !fMultiple;

       break;

   case IDM_REFRESH:

   case IDM_REFRESHALL:

       SendMessage(hwnd, FM_REFRESH_WINDOWS,

      wMsg == IDM_REFRESHALL, 0);

       break;

   case IDM_RELOAD:

       PostMessage(hwnd, FM_RELOAD_EXTENSIONS, 0, 0);

       break;

    }

    return 0L;

}


  83.1.5  Adding the Undelete Command

File Manager supports a hook for adding an Undelete command to the File menu (below the Delete command). If an "undelete" dynamic-link library is specified in the WINFILE.INI file, File Manager adds the Undelete command to the File menu when starting. When the user chooses the Undelete command, File Manager calls the DLL.

The [settings] section of the WINFILE.INI file should include a reference to the undelete DLL, as follows.

[settings]

UNDELETE.DLL=C:\MYDIR\OTHER.DLL

An undelete DLL must include a standard entry point, the UndeleteFile function. This function must be exported by specifying the name of the function in the EXPORTS statement of the DLL's module-definition (.DEF) file.

The UndeleteFile function is defined as follows:

DWORD APIENTRY UndeleteFile(hwndParent, lpszDir)

HWND hwndParent;

LPSTR lpszDir;

The hwndParent parameter identifies the parent window for any dialog boxes the DLL creates. The lpszDir parameter specifies the initial directory to be used (for example, C:\TEMP).


Shell Dynamic Data Exchange Interface
  Chapter 84    Shell Dynamic Data Exchange Interface

84.1  About Program Manager Initialization

This chapter describes the dynamic data exchange (DDE) interface of Program Manager (PROGMAN.EXE). Program Manager is a shell — that is, an application that enables users to group, start, and otherwise control other applications for the Microsoft Windows operating system.

Program Manager starts automatically when the user starts Windows and runs as long as Windows is in use. When it starts, Program Manager displays one or more windows within its main window. Each window contains icons that correspond to logically related Windows-based applications. For example, the Accessories window contains icons for Windows Write, Paintbrush, Notepad, and other accessory applications.

Program Manager stores initialization and configuration information in the registry. This information is stored under the Settings, Groups, and Restrictions keys in the following section of the registry:

HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Program Manager

Additional information is stored in the Program Groups key in the following section of the registry:

HKEY_LOCAL_MACHINE\SOFTWARE


  84.1.1  Settings Key

The Settings key contains information that Program Manager uses to configure its environment. The following entries appear in the Settings key.

Entry	Description
MinOnRun	Specifies whether to minimize Program Manager when an application is started.
AutoArrange	Specifies whether Program Manager should automatically arrange icons within groups.
SaveSettings	Specifies whether to save the position of the Program Manager window when Program Manager terminates.
DISPLAY.DRV	Specifies the filename of the display driver in use when Program Manager last terminated. When Program Manager starts, it compares this value to the filename of the display driver currently in use. If the names are different, Program Manager re-extracts the application icons.
Window	Specifies the location and dimensions of the Program Manager window.
Order	Specifies the order that the groups listed in the Groups key appear in the Program Manager window.
Startup	Specifies the name of the startup group. Program Manager automatically starts the applications in the startup group whenever it starts.


  84.1.2  Groups Key

The windows that appear in the Program Manager window correspond to group files. From the user's perspective, a group file is a collection of icons that represent logically related applications, but from the programmer's perspective, a group file is actually a collection of data. This data includes the color information for the icons (AND and XOR masks), an offset to the resource header of each icon, the ideal resolution for displaying each icon, the name of the executable (.EXE) file that contains the application, and so on.

There are two types of groups: common and personal. A common group is shared among multiple users through network connections; a personal group is not shared. Program Manager stores information about personal groups under the Groups key. It stores information about common groups under the HKEY_LOCAL_MACHINE\SOFTWARE key.

The Groups key of the registry identifies the names of the group files that Program Manager displays as unique windows or icons. The groups must be numbered, but they need not be listed in any particular order. Program Manager never changes the number of an existing group.


  84.1.3  Restrictions Key

The Restrictions key controls whether certain features of Program Manager are enabled or disabled. The following entries can appear in the Restrictions key.

Entry	Description
NoRun	Specifies whether to disable the Run command on the File menu. If this entry is set to 1, the Run command is disabled. If this entry is set to 0, the Run command is enabled. The default is 0 if no value is specified.
NoClose	Specifies whether to prevent the user from closing Program Manager through the File menu, the System menu, the ALT+F4 key combination, or the Task List. If this entry is set to 1, closing is prevented. If this entry is set to 0, closing is allowed. The default is 0 if no value is specified.
EditLevel	Controls the extent to which the user can modify read-write groups. (Shared read-only groups cannot be modified.) This entry can be set to one of the following values.
Value	Action
0	Allows any modifications to the group. This is the default value.
1	Prevents the user from creating, deleting, or renaming groups.
2	Prevents the user from creating, deleting, or renaming groups and from creating or deleting items in a group.
3	Prevents the user from creating, deleting, or renaming groups; from creating or deleting items in a group; and from changing command lines for items in a group.
4	Prevents the user from changing any property of an item in a group; from creating, deleting, or renaming groups; from creating or deleting items in a group; and from changing command lines for items in a group.
NoFileMenu	Specifies whether to disable the File menu and all of its commands. If this entry is set to 1, the File menu is disabled. If this entry is set to 0, the menu is enabled. The default setting is 0 if no value is specified.
NoSaveSettings	Specifies whether to disable the Save Settings on Exit command on the Options menu. If this entry is set to 1, the Save Settings on Exit command is disabled. If this entry is set to 0, the command is enabled. The default setting is 0 if no value is specified.
Setting the value of NoRun to 1 and the value of EditLevel to 3 prevents a user from using Program Manager to run any applications not already in a program group.


  84.2  Command-String Interface

Program Manager has a DDE command-string interface that allows other applications to create, display, delete, and reload groups; add items to groups; replace items in groups; delete items from groups; and close Program Manager. The following commands perform these actions:

AddItem	ExitProgman
CreateGroup	Reload
DeleteGroup	ReplaceItem
DeleteItem	ShowGroup
For example, the setup program for an application can use these commands to instruct Program Manager to install the application's icon in a group.

Multiple commands can be concatenated; each command must be contained in square brackets, and parameters must be contained in parentheses and separated by commas. Quotation marks must delimit arguments that contain spaces, brackets, or parentheses. For example, the following set of commands adds WINAPP.EXE to the Windows Applications group:

[CreateGroup("Windows Applications")]

[ShowGroup("MYGROUP.GRP",1)]

[AddItem(winapp.exe,Win App,winapp.exe,2)]

To use these commands, an application must first initiate a DDE conversation with Program Manager. The application and topic names for the conversation are both PROGMAN. Then the application sends the WM_DDE_EXECUTE message, specifying the appropriate command and its parameters.

Note   The user can configure Windows to use a shell other than Program Manager as the default. Therefore, do not design an application that assumes Program Manager will be available for a DDE conversation.

The following sections describe Program Manager DDE command strings in detail. In the syntax blocks in the following sections, brackets enclose optional parameters.


  84.2.1  CreateGroup

The syntax for the CreateGroup command has this form:

CreateGroup(GroupName[,CommonGroupFlag])

The CreateGroup command instructs Program Manager to create a new group or activate the window of an existing group.

Following are the parameters for this command:

GroupName

Identifies the group to be created or activated. This parameter is a string. If a group already exists with the name specified by GroupName, CreateGroup activates the group window.

CommonGroupFlag

Specifies whether the new group is a common group or a personal group. If this parameter is 1, a common group is created; if it is 0, a personal group is created. To create a common group, the user currently logged on must have administrative privileges. If this parameter is 1 but the user does not have administrative privileges, the command fails. The default value of this parameter is 1 (common group) if no value is specified and if the user has administrative privileges. The default value is 0 (personal group) if no value is specified and the user does not have administrative privileges.

Note   If the second parameter of the CreateGroup command specifies the path of the group file (as was required in Windows version 3.1), the parameter is ignored.


  84.2.2  ShowGroup

The syntax for the ShowGroup command has this form:

ShowGroup(GroupName,ShowCommand[,CommonGroupFlag])

The ShowGroup command instructs Program Manager to minimize, maximize, or restore the window of an existing group.

Following are the parameters for this command:

GroupName

Identifies the group window to be minimized, maximized, or restored.

ShowCommand

Specifies the action Program Manager is to perform on the group window. This parameter is an integer. It must have one of the following values.

Value	Action
1	Activates and displays the group window. If the window is minimized or maximized, Windows restores it to its original size and position.
2	Activates the group window and displays it as an icon.
3	Activates the group window and displays it as a maximized window.
4	Displays the group window in its most recent size and position. The window that is currently active remains active.
5	Activates the group window and displays it in its current size and position.
6	Minimizes the group window.
7	Displays the group window as an icon. The currently active window remains active.
8	Displays the group window in its current state. The currently active window remains active.
CommonGroupFlag

Specifies whether the group is a common group or a personal group. If this parameter is 1, the group being minimized, maximized, or restored is a common group; if it is 0, the group is a personal group. This parameter defaults to 1 (common group) if no value is specified. To minimize, maximize, or restore a common group, the user currently logged on must have administrative privileges. If this parameter is 1 but the user does not have administrative privileges, the command fails.


  84.2.3  DeleteGroup

The syntax for the DeleteGroup command has this form:

DeleteGroup(GroupName[,CommonGroupFlag])

The DeleteGroup command instructs Program Manager to delete an existing group.

Following are the parameters for this command:

GroupName

Identifies the group to be deleted.

CommonGroupFlag

Specifies whether the group is a common group or a personal group. If this parameter is 1, the group being deleted is a common group; if it is 0, the group is a personal group. This parameter defaults to 1 (common group) if no value is specified. To delete a common group, the user currently logged on must have administrative privileges. If this parameter is 1 but the user does not have administrative privileges, the command fails.

Note   If the second parameter of the DeleteGroup command specifies the path of the group file (as was required in Windows version 3.1), the parameter is ignored.


  84.2.4  Reload

The syntax for the Reload command has this form:

Reload(GroupName[,CommonGroupFlag])

The ReloadGroup command instructs Program Manager to remove and reload an existing group. An application that modifies group files can use this command to cause Program Manager to update the groups when it has finished making modifications.

Following are the parameters for this command:

GroupName

Identifies the group to be removed and reloaded. If no value is specified for the GroupName parameter, Program Manager unloads all groups and reloads the groups specified in the Groups key of the registry. The Settings and Restrictions keys are not reread.

CommonGroupFlag

Specifies whether the group is a common group or a personal group. If this parameter is 1, the group being reloaded is a common group; if it is 0, the group is a personal group. This parameter defaults to 1 (common group) if no value is specified. To reload a common group, the user currently logged on must have administrative privileges. If this parameter is 1 but the user does not have administrative privileges, the command fails.


  84.2.5  AddItem

The syntax for the AddItem command has this form:

AddItem(CmdLine[,
    Name[,IconPath[,IconIndex[,xPos,yPos[,DefDir[,
    HotKey,[,fMinimize] ] ] ] ] ] ])

The AddItem command instructs Program Manager to add an icon to an existing group. There is a limit of 50 items per group.

Following are the parameters for this command:

CmdLine

Specifies the full command line required to run the application. This parameter is a string. At a minimum, this string is the name of the executable file for the application. It can also include the full path of the application and any parameters required by the application.

Name

Specifies the title that is displayed below the icon in the group window.

IconPath

Identifies the filename for the icon to be displayed in the group window. This parameter is a string. This file can be either a Windows-based executable file or an icon file. If no value is specified for the IconPath parameter, Program Manager uses the first icon in the file specified by the CmdLine parameter if that file is an executable file. If CmdLine specifies an associated file, Program Manager uses the first icon of the associated executable file. The association is taken from the registry. (For more information about the registry, see Chapter 52, »Registry and Initialization Files«.) If CmdLine specifies neither an executable file nor an associated executable file, Program Manager uses a default icon.

IconIndex

Specifies the index of the icon in the file identified by the IconPath parameter. The IconIndex parameter is an integer. PROGMAN.EXE contains five built-in icons that can be used for programs not written for Windows.

xPos

Specifies the horizontal position of the icon in the group window. This parameter is an integer. Both the xPos and yPos parameters must be used to specify the position of the icon. If the position is not specified, Program Manager places the icon in the next available space.

yPos

Specifies the vertical position of the icon in the group window. This parameter is an integer. Both the xPos and yPos parameters must be used to specify the position of the icon. If the position is not specified, Program Manager places the icon in the next available space.

DefDir

Specifies the name of the default (or working) directory. This parameter is a string.

HotKey

Identifies a hot (or shortcut) key that is specified by the user.

fMinimize

Specifies whether an application window is to be minimized when first displayed.


  84.2.6  ReplaceItem

The syntax for the ReplaceItem command has this form:

ReplaceItem(ItemName)

The ReplaceItem command instructs Program Manager to delete an item and record the position of the deleted item. Program Manager adds a new item (specified by the next AddItem command) at this recorded position.

Following is the parameter for this command:

ItemName

Specifies the item to be deleted. Its position is recorded by Program Manager.


  84.2.7  DeleteItem

The syntax for the DeleteItem command has this form:

DeleteItem(ItemName)

The DeleteItem command instructs Program Manager to delete an item from the currently active group.

Following is the parameter for this command:

ItemName

Specifies the item to be deleted from the currently active group.


  84.2.8  ExitProgman

The syntax for the ExitProgman command has this form:

ExitProgman(bSaveGroups)

If Program Manager was started by another application, the ExitProgman command instructs Program Manager to terminate and, optionally, save its group information.

Following is the parameter for this command:

bSaveGroups

Specifies a Boolean value that, if it is nonzero, causes Program Manager to save its group information before closing. If bSaveGroups is zero, Program Manager does not save its group information.


  84.3  Requesting Group Information

Program Manager can provide information about its groups to an application. Applications can request this information from Program Manager by using the PROGMAN topic.

An application can obtain a list of Program Manager groups by issuing a request for the Group item. Program Manager provides the list in CF_TEXT format. The list consists of group-name strings separated by carriage returns.

An application can use a group name as an item name to request information about the group. Program Manager provides this information in CF_TEXT format. The fields of group information are separated by commas. The first line of the information contains the group name (in quotation marks), the path of the group file, and the number of items in the group. Each subsequent line contains information about an item in the group, including the command line (in quotation marks), the default directory, the icon path, the position in the group, the icon index, the shortcut key (in numeric form), and the minimize flag.


Interprocess Communications Options in Win32 Applications
  Chapter 85    Interprocess Communications Options in Win32 Applications

85.1  About Interprocess Communications

As computer users become more sophisticated, they demand more power from the applications they use. To meet this demand, developers add more features to their applications, and the applications become larger. At some point, these large applications can become unmanageable, both from a development standpoint and from a user-interface point of view. Therefore, developers now tend to produce highly focused applications that do a good job on a limited number of features and then to enable those applications to communicate and share data with other specialized applications. No longer can any one application meet all user expectations; the age of cooperating and communicating applications has arrived.

The Microsoft Win32 application programming interface (API) provides a rich set of mechanisms for facilitating communications and data sharing between applications. Collectively, the activities enabled by these mechanisms are called interprocess communications (IPC). In addition to facilitating the division of labor among several specialized processes, some forms of IPC can distribute the computational load among cooperating computers on a network.

Typically, cooperating and communicating applications can be categorized as clients or servers. A client is an application or a process that requests a service from some other process. A server is an application or a process that responds to a client request. Many applications act as both a client and a server, depending on the situation. For example, a word processing application might act as a client in requesting a summary table of manufacturing costs from a spreadsheet application acting as a server. The spreadsheet application, in turn, might act as a client in requesting the latest inventory levels from an automated inventory control application.


  85.2  Development Considerations

If a developer decides that an application would benefit from IPC, the developer must consider some of the following questions before deciding which of the available IPC methods to use:

•	Should the application be able to communicate with other applications running on other computers on a network, or is it sufficient for the application to communicate only with applications on the local computer? In other words, does the application need to be networkable? Some IPC methods work either on the local computer or over a network; others work only on the local computer.

•	Should the application be able to communicate with applications running on other computers that may be running under different operating systems (that is, MS-DOS, Microsoft Windows Version 3.x, UNIX®)? In other words, must the application be interoperable?

•	Should the user of the application have to choose the other application(s) with which the application communicates, or can the application implicitly find its cooperating partners?

•	Should the application communicate with many different applications in a general way, such as allowing cut and paste operations with any other application, or should its communications requirements be limited to a restricted set of interactions with specific other applications? Applications that communicate in a general way are called loosely coupled; applications that have a more strictly defined interaction are called tightly coupled.

•	Is performance a critical aspect of the application? All IPC mechanisms include some amount of communications overhead.

•	Should the application be a Windows-based application, or will character-mode functionalities be sufficient? Some IPC mechanisms discussed in this chapter do not work in character-mode−only applications. The clipboard, dynamic data exchange (DDE), and object linking and embedding (OLE) all require that the application have at least one window.

The answers to these questions determine whether an application can benefit by using one or more of the IPC mechanisms available in the Win32 API. This chapter discusses the strengths and weaknesses of each of the Win32 IPC mechanisms.


  85.2.1  File Mapping

File mapping enables a process to treat the content of a file as if it were a block of memory in the process's address space. Therefore, instead of using file input and output (I/O) operations, the process can use simple pointer operations to examine and modify the contents of the file.

The Win32 API enables two or more processes to access the same file-mapping object. Each process receives a pointer to memory in its own address space. With this pointer, the process can read or modify the contents of the file.

There are three ways an application can share a file-mapping object created in one process with another process:

•	Inheritance. The first process creates the file-mapping object and then allows the handle of the object to be inherited by a child process.

•	Named file mapping. The first process creates the file-mapping object with a well-known name (which can be different from the filename). The second process opens the file-mapping object by specifying the well-known name. Alternatively, the first process can create a file-mapping object with a unique name and communicate that name to the second process through some other IPC mechanism (named pipe, mailslot, and so on).

•	Handle duplication. The first process creates the file-mapping object and then passes the handle of the object to the second process. The second process then duplicates the handle to gain access to the shared memory. The original process can communicate the file-mapping handle to the second process through one of the other IPC mechanisms described in this chapter (named pipe, mailslot, and so on). For more information about duplicating handles, see Chapter 44, »Synchronization«.

When two or more processes have read-write access to a shared memory block, they must use some sort of synchronization object, such as a semaphore, to prevent data corruption in a multitasking environment.

File mapping is quite efficient and also provides operating-system−supported security attributes that can help prevent unauthorized data corruption. File mapping can be used only between processes on a local computer; it cannot be used over a network. An application can, however, create a file-mapping object to a file on a remotely mounted volume. For example, if a remote server is mounted as the F drive, an application can create a file-mapping object to a file on that volume. However, a process running on a remote server cannot share a file-mapping object with a process running on a local computer.

Key Point   File mapping is an efficient way for two or more processes on the same computer to share data, but the developer must provide synchronization between the processes. For more information, see Chapter 47, »File Mapping«, and Chapter 44, »Synchronization«.


  85.2.2  Shared Memory

The Win32 API uses a special case of file mapping to provide shared memory access between processes. If you specify the system swapping file when creating a file-mapping object, the file-mapping object is treated as a shared memory block. Other processes can access the same block of memory by opening the same file-mapping object, as described in Chapter 47, »File Mapping«.

Because shared memory is implemented with file mapping, it supports security access attributes and can operate only between processes running on the same computer.

Key Point   Shared memory in the Win32 API is implemented by using file mapping. All characteristics of file mapping apply to shared memory. For more information, see Chapter 47, »File Mapping«.


  85.2.3  Anonymous Pipes

An anonymous (or unnamed) pipe enables related processes to transfer information back and forth as if they were reading from and writing to a file. Typically, anonymous pipes are used for redirecting the standard input and output (I/O) of a child process so that it can exchange data with its parent process.

To use an anonymous pipe, the parent process typically creates the pipe and then allows its read and write handles to be inherited by a child process. The parent process writes data to the pipe; the child process can read the data from the other end of the pipe. Likewise, the child process can write data to the pipe and the parent process can read the data from its end of the pipe. A parent process can also create two or more child processes that inherit the read and write handles to an anonymous pipe. Those child processes can use that pipe to communicate with each other directly, without going through the parent process.

Anonymous pipes cannot be used over a network, nor can they be used between unrelated processes. For information about a pipe mechanism that can be used with unrelated processes and over a network, see Section 85.2.4, »Named Pipes«.

Key Point   Anonymous pipes provide an efficient way to redirect standard I/O to child processes on the same computer. For more information, see Chapter 54, »Pipes«.


  85.2.4  Named Pipes

Like anonymous pipes, named pipes are used to transfer data back and forth between processes. Unlike anonymous pipes, however, named pipes can operate between unrelated processes and across a network between computers. Typically, a server process creates a named pipe with a well-known name. Client processes that can get the name of the pipe can open the other end of the pipe, subject to access restrictions specified by the pipe's creator. After they are connected, the server and client can exchange data by performing read and write operations on the pipe. Alternatively, the pipe creator can create a pipe and let a child process inherit the handle to the pipe, or it can create a pipe with a unique name and communicate that name to the client through some other IPC mechanism (such as a mailslot maintained by the client).

Key Point   Named pipes provide a relatively simple programming interface that makes transferring data across a network no more difficult than transferring data between two processes on the same computer. For more information, see Chapter 54, »Pipes«.


  85.2.5  Mailslots

Mailslots provide a one-way interprocess communications capability. Any process can create a mailslot and become a mailslot server. Other processes, called mailslot clients, can gain access to the mailslot by its name and send messages to the mailslot server process. A process can be both a mailslot server and a mailslot client, so two-way IPC is possible with multiple mailslots.

Incoming messages are always appended to the mailslot. The mailslot saves the messages until the creating process has a chance to read them.

Mailslots are similar to named pipes, but with a somewhat simplified programming interface and the added ability to broadcast messages to all computers in a specified network domain. A mailslot client can send a message to a mailslot on its local computer, to a mailslot on another computer, or to all mailslots with the same name on all computers in a specified network domain. Messages broadcast to a domain can be no longer than 400 bytes; messages sent to a single mailslot are limited only by the maximum message size specified by the creator of the mailslot (which can be unlimited).

Key Point   Mailslots offer an easy way for applications to send and receive short messages. They also provide the ability to broadcast messages across all computers in a network domain. For more information, see Chapter 55, »Mailslots«.


  85.2.6  Clipboard

The clipboard provides a mechanism for the well-established cut-copy-paste model for simple data sharing between Windows-based applications. It enables an application to read or write data in many different standard and application-defined formats.

The clipboard acts as a central depository for data sharing among applications. When a user performs a cut or copy operation in an application, the application puts the selected data on the clipboard in one or more formats. Any other application can then retrieve the data from the clipboard, choosing from the available formats. The clipboard is a very loosely coupled exchange medium, wherein the two applications need only agree on the data format.

The clipboard mechanism works between applications on the same computer or on different computers on a network. It also works for Windows-based applications only, although 16-bit Windows 3.x applications running with the Microsoft Windows NT operating system can exchange clipboard data with 32-bit applications written for Windows NT.

Key Point   All Windows-based applications should support the clipboard for those data formats that they understand. For example, a text editor or word processor should at least be able to produce and accept clipboard data in pure text format. For more information, see Programmer's Reference, Volume 1, Chapter 25, "Clipboard."


  85.2.7  Dynamic Data Exchange

Dynamic data exchange (DDE) is a protocol for interprocess communications that enables applications to exchange data in a variety of formats. Applications can use DDE for one-time data exchanges or for ongoing exchanges in which the applications update one another as new data becomes available.

The data formats used by DDE are the same as those used for the Windows clipboard IPC mechanism. DDE can be thought of as an extension of the clipboard mechanism. The clipboard is almost always used for a one-time response to a user command, such as choosing the Paste command from a menu. DDE is also usually initiated by a user command, but it often continues to function without further user interaction.

Three types of data exchange are possible with DDE:

•	Cold link: The exchange is a one-time data transfer, like the clipboard.

•	Warm link: A server notifies the client when data changes, and the client must then request new data.

•	Hot link: A server sends data updates to the client when data changes.

DDE exchanges can occur between applications running on the same computer or on different computers on a network.

Key Point   Most major Windows-based applications support DDE. Like the clipboard, DDE support enables an application to exchange data in a variety of standard formats with other Windows-based applications that support DDE. A developer can also define custom DDE data formats for special-purpose IPC between applications with more tightly coupled communications requirements. For more information, see Programmer's Reference, Volume 1, Chapter 26, "Dynamic Data Exchange," and Chapter 77, »Dynamic Data Exchange Management Library«.


  85.2.8  Object Linking and Embedding

Object linking and embedding (OLE) applications manage compound documents — that is, documents made up of data from a variety of different applications. OLE provides services that make it easy for applications to call on other applications for data editing. For example, an OLE-aware word processor could embed a graph from a spreadsheet. The user could start the spreadsheet automatically from within the word processor by choosing the embedded chart for editing. The OLE libraries would take care of starting the spreadsheet and presenting the graph for editing. When the user quit the spreadsheet, the graph would be updated in the original word processor document. Contrast this with a DDE link involving a spreadsheet graph in a word processor document. With DDE, the user would have to explicitly start the spreadsheet and open the graph document in order to make changes. With OLE, the spreadsheet appears to be an extension of the word processor.

Like an application using DDE, an OLE-aware application can communicate with a wide variety of other Windows-based applications. Because the OLE protocol includes all necessary context information, the application will be able to hold OLE conversations with all other OLE applications — even those that have yet to be written.

Key Point   OLE supports compound documents and enables an application to include embedded or linked data that, when chosen, automatically starts another application for data editing. This enables the application to be extended by any other OLE-aware application.


  85.2.9  Dynamic-Link Libraries

It is possible to build a Win32 dynamic-link library (DLL) so that its global data is shared with all processes that call the DLL. Therefore, cooperating processes can call the DLL to examine and modify global data owned by the DLL. For example, process A calls a DLL function with data that the DLL stores in its global data space. Process B calls another DLL function that retrieves that data. Of course, because of the multitasking nature of the Win32 API, the DLL would have to use a semaphore or another synchronization object to control access to the shared memory.

Although shared global data can be used in a DLL, Win32 file mapping is recommended for shared memory. File mapping is more efficient and provides the additional benefit of access protection. (For example, a client can be limited to read-only access to a file-mapping object.)

Key Point   Although a developer can use shared global data segments in a DLL to allow two or more applications to share data, it is preferable to use Windows NT file-mapping functions to create shared memory. For more information, see Chapter 50, »Dynamic-Link Libraries«.


  85.2.10  Remote Procedure Call

The Win32 API provides remote procedure calls (RPC) to enable applications to call functions remotely. With RPC, communication with other processes becomes as easy as calling a function. RPC operates between processes on a single computer or on different computers on a network. One way to think of RPC is as a DLL that works on a network.

The RPC provided by the Win32 API is compliant with the Open Software Foundation (OSF) Distributed Computing Environment (DCE). This means that RPC applications written by using the Win32 API are able to communicate with other RPC applications running with other operating systems that support DCE. RPC automatically supports data conversion to account for different hardware architectures and for byte-ordering between dissimilar environments.

The Win32 development kit includes RPC libraries that support MS-DOS−hosted RPC clients. With this facility, a Windows NT server can provide service to many MS-DOS clients through RPC.

RPC clients and servers are tightly coupled but still maintain high performance. Windows NT makes extensive use of RPC to facilitate a client-server relationship between different parts of the operating system.

Key Point   RPC provides IPC with a function interface, with support for automatic data conversion and for communications with other operating systems. Using RPC, a developer can create high-performance, tightly coupled distributed applications. For more information, see the Microsoft Win32 Remote Procedure Call Programmer's Guide and Reference.


  85.2.11  The Netbios Function

The Win32 API provides the Netbios function to process low-level network control functions. This capability is provided primarily for applications written using the IBM NetBIOS system that must be ported to Windows. It is highly recommended that a developer writing a new application use the other IPC mechanisms described in this chapter rather than the low-level Netbios function. The IPC mechanisms provided in the Win32 API encapsulate and hide an enormous amount of raw NetBIOS functionality that the developer would otherwise have to implement.

Consider, for example, the following list of NetBIOS actions that would be necessary to emulate a Win32 mailslot:

On the server end

•	Add the name to the local table.

•	Listen for the session connection.

•	Read the data upon connection.

•	Append the data to the message queue.

•	Close the session.

•	Listen for another session connection.

•	Allow the queued messages to be retrieved.

On the client side

•	Open the session.

•	Write the data.

•	Close the session.

Key Point   The Netbios function is provided only for porting an existing application written using the IBM NetBIOS system or for those applications that need specialized access to low-level network functionality. For most applications, it is better to use the higher-level IPC mechanisms available in the Win32 API. For more information, see Chapter 56, »Networks«.


  85.3  Summary

It is likely that an application will support IPC by using several of the mechanisms described in this chapter. For example, all Windows-based applications should provide at least minimal support for the clipboard. In addition, DDE and OLE may offer the application an opportunity to communicate in a loosely coupled way with a wide variety of applications that support these protocols. The great strength of these loosely coupled mechanisms is that a developer can enable an application to share data with other applications without knowing anything about the applications themselves. By supporting the protocols for the clipboard, DDE, and OLE, the developer is assured of a growing number of applications with which the application can share data. As new applications are written that support these protocols, the developer's application will be ready to communicate with them.

As an application becomes more sophisticated, a developer may find it advantageous to break up the application into tightly coupled cooperating processes that use shared memory, pipes, or RPC to communicate. These tightly coupled mechanisms can provide high-performance extensions to the application. But when adding these more specialized IPC methods, the developer should not abandon the more loosely coupled IPC methods that allow the application to share data in a general way with most other Windows-based applications.


Error Codes
  Appendix A    Error Codes

Alphabetical List of Error Codes

Error Code	Description
EPT_S_CANT_CREATE
	The endpoint mapper database could not be created.
EPT_S_CANT_PERFORM_OP
	The operation cannot be performed.
EPT_S_INVALID_ENTRY
	The entry is invalid.
EPT_S_NOT_REGISTERED
	There are no more endpoints available from the endpoint mapper.
ERROR_ACCESS_DENIED
	Access is denied.
ERROR_ACCOUNT_DISABLED
	The referenced account is currently disabled and cannot be logged on to.
ERROR_ACCOUNT_EXPIRED
	The user's account has expired.
ERROR_ACCOUNT_RESTRICTION
	Indicates a referenced user name and authentication information are valid, but some user account restriction has prevented successful authentication (such as time-of-day restrictions).
ERROR_ADAP_HDW_ERR
	A network adapter hardware error occurred.
ERROR_ALIAS_EXISTS
	The specified alias already exists.
ERROR_ALLOTTED_SPACE_EXCEEDED
	When a block of memory is allotted for future updates, such as the memory allocated to hold discretionary access control and primary group information, successive updates may exceed the amount of memory originally allotted. Since quota may already have been charged to several processes that have handles of the object, it is not reasonable to alter the size of the allocated memory. Instead, a request that requires more memory than has been allotted must fail and the ERROR_ALLOTTED_SPACE_EXCEEDED error returned.
ERROR_ALREADY_ASSIGNED
	The local device name is already in use.
ERROR_ALREADY_EXISTS
	Attempt to create file that already exists.
ERROR_ALREADY_RUNNING_LKG
	The system is currently running with the last-known-good configuration.
ERROR_ARENA_TRASHED
	The storage control blocks were destroyed.
ERROR_ARITHMETIC_OVERFLOW
	Arithmetic result exceeded 32-bits.
ERROR_ATOMIC_LOCKS_NOT_SUPPORTED
	The file system does not support atomic changing of the lock type.
ERROR_AUTODATASEG_EXCEEDS_64k
	The operating system cannot run this application program.
ERROR_BAD_ARGUMENTS
	The argument string passed to DosExecPgm is incorrect.
ERROR_BAD_COMMAND
	The device does not recognize the command.
ERROR_BAD_DESCRIPTOR_FORMAT
	Indicates a security descriptor is not in the required format (absolute or self-relative).
ERROR_BAD_DEV_TYPE
	The network resource type is incorrect.
ERROR_BAD_DEVICE
	The specified device name is invalid.
ERROR_BAD_DRIVER_LEVEL
	The system does not support the requested command.
ERROR_BAD_ENVIRONMENT
	The environment is incorrect.
ERROR_BAD_EXE_FORMAT
	%1 is not a valid Windows-based application.
ERROR_BAD_FORMAT
	An attempt was made to load a program with an incorrect format.
ERROR_BAD_IMPERSONATION_LEVEL
	A specified impersonation level is invalid. Also used to indicate a required impersonation level was not provided.
ERROR_BAD_INHERITANCE_ACL
	Indicates that an attempt to build either an inherited ACL or ACE did not succeed. One of the more probable causes is the replacement of a CreatorId with an SID that didn't fit into the ACE or ACL.
ERROR_BAD_LENGTH
	The program issued a command but the command length is incorrect.
ERROR_BAD_LOGON_SESSION_STATE
	The logon session is not in a state consistent with the requested operation.
ERROR_BAD_NET_NAME
	The network name cannot be found.
ERROR_BAD_NET_RESP
	The specified server cannot perform the requested operation.
ERROR_BAD_NETPATH
	The network path was not found.
ERROR_BAD_PATHNAME
	The specified path name is invalid.
ERROR_BAD_PIPE
	The pipe state is invalid.
ERROR_BAD_PROFILE
	The network connection profile is damaged.
ERROR_BAD_PROVIDER
	The specified network provider name is invalid.
ERROR_BAD_REM_ADAP
	The remote adapter is not compatible.
ERROR_BAD_THREADID_ADDR
	The address for the thread ID is incorrect.
ERROR_BAD_TOKEN_TYPE
	The type of token object is inappropriate for its attempted use.
ERROR_BAD_UNIT
	The system cannot find the specified device.
ERROR_BAD_USERNAME
	The specified user name is invalid.
ERROR_BAD_VALIDATION_CLASS
	The requested validation information class is invalid.
ERROR_BADDB
	The configuration registry database is damaged.
ERROR_BADKEY
	The configuration registry key is invalid.
ERROR_BEGINNING_OF_MEDIA
	The beginning of the tape or partition was encountered.
ERROR_BOOT_ALREADY_ACCEPTED
	The current boot has already been accepted for use as the last-known-good control set.
ERROR_BROKEN_PIPE
	The pipe was ended.
ERROR_BUFFER_OVERFLOW
	The file name is too long.
ERROR_BUS_RESET
	The I/O bus was reset.
ERROR_BUSY
	The requested resource is in use.
ERROR_BUSY_DRIVE
	The system cannot perform a JOIN or SUBST at this time.
ERROR_CALL_NOT_IMPLEMENTED
	The Application Program Interface (API) entered will only work in Windows/NT mode.
ERROR_CAN_NOT_COMPLETE
	Cannot complete function for some reason.
ERROR_CANCEL_VIOLATION
	A lock request was not outstanding for the supplied cancel region.
ERROR_CANNOT_COPY
	The Copy API cannot be used.
ERROR_CANNOT_FIND_WND_CLASS
	Cannot find window class.
ERROR_CANNOT_IMPERSONATE
	Indicates that an attempt was made to impersonate via a named pipe was not yet read from.
ERROR_CANNOT_MAKE
	The directory or file cannot be created.
ERROR_CANNOT_OPEN_PROFILE
	Unable to open the network connection profile.
ERROR_CANT_ACCESS_DOMAIN_INFO
	Indicates a domain controller could not be contacted or that objects within the domain are protected and necessary information could not be retrieved.
ERROR_CANT_DISABLE_MANDATORY
	A mandatory group cannot be disabled.
ERROR_CANT_OPEN_ANONYMOUS
	An attempt was made to open an anonymous level token. Anonymous tokens cannot be opened.
ERROR_CANTOPEN
	The configuration registry key cannot be opened.
ERROR_CANTREAD
	The configuration registry key cannot be read.
ERROR_CANTWRITE
	The configuration registry key cannot be written.
ERROR_CHILD_MUST_BE_VOLATILE
	An attempt was made to create a stable subkey under a volatile parent key.
ERROR_CHILD_NOT_COMPLETE
	The application cannot be run in Windows mode.
ERROR_CHILD_WINDOW_MENU
	Child windows can't have menus.
ERROR_CIRCULAR_DEPENDENCY
	Circular service dependency was specified.
ERROR_CLASS_ALREADY_EXISTS
	Class already exists.
ERROR_CLASS_DOES_NOT_EXIST
	Class does not exist.
ERROR_CLASS_HAS_WINDOWS
	Class still has open windows.
ERROR_CLIPBOARD_NOT_OPEN
	Thread doesn't have clipboard open.
ERROR_CONNECTION_UNAVAIL
	The device is not currently connected but is a remembered connection.
ERROR_CONTROL_ID_NOT_FOUND
	Control ID not found.
ERROR_COUNTER_TIMEOUT
	A serial I/O operation completed because the time-out period expired. (The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.)
ERROR_CRC
	Data error (cyclic redundancy check).
ERROR_CURRENT_DIRECTORY
	The directory cannot be removed.
ERROR_DATABASE_DOES_NOT_EXIST
	The database specified does not exist.
ERROR_DC_NOT_FOUND
	Invalid HDC passed to ReleaseDC.
ERROR_DEPENDENT_SERVICES_RUNNING
	A stop control has been sent to a service which other running services are dependent on.
ERROR_DESTROY_OBJECT_OF_OTHER_THREAD
	Cannot destroy object created by another thread.
ERROR_DEV_NOT_EXIST
	The specified network resource is no longer available.
ERROR_DEVICE_ALREADY_REMEMBERED
	An attempt was made to remember a device that was previously remembered.
ERROR_DEVICE_IN_USE
	The device is in use by an active process and cannot be disconnected.
ERROR_DEVICE_NOT_PARTITIONED
	Tape partition information could not be found when loading a tape.
ERROR_DIR_NOT_EMPTY
	The directory is not empty.
ERROR_DIR_NOT_ROOT
	The directory is not a subdirectory of the root directory.
ERROR_DIRECT_ACCESS_HANDLE
	Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O.
ERROR_DIRECTORY
	The directory name is invalid.
ERROR_DISCARDED
	The segment is already discarded and cannot be locked.
ERROR_DISK_CHANGE
	Program stopped because alternate disk was not inserted.
ERROR_DISK_CORRUPT
	The disk structure is damaged and nonreadable.
ERROR_DISK_FULL
	There is not enough space on the disk.
ERROR_DISK_OPERATION_FAILED
	While accessing the hard disk, a disk operation failed even after retries.
ERROR_DISK_RECALIBRATE_FAILED
	While accessing the hard disk, a recalibrate operation failed, even after retries.
ERROR_DISK_RESET_FAILED
	While accessing the hard disk, a disk controller reset was needed, but even that failed.
ERROR_DLL_INIT_FAILED
	A DLL initialization routine failed.
ERROR_DOMAIN_EXISTS
	The specified domain already exists.
ERROR_DOMAIN_LIMIT_EXCEEDED
	An attempt to exceed the limit on the number of domains per server for this release.
ERROR_DOMAIN_TRUST_INCONSISTENT
	The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
ERROR_DRIVE_LOCKED
	The disk is in use or locked by another process.
ERROR_DUP_DOMAINNAME
	The workgroup or domain name is already in use by another computer on the network.
ERROR_DUP_NAME
	A duplicate name exists on the network.
ERROR_DUPLICATE_SERVICE_NAME
	The name is already in use as either a service name or a service display name.
ERROR_DYNLINK_FROM_INVALID_RING
	The operating system cannot run this application program.
ERROR_EA_ACCESS_DENIED
	Access to the EA is denied.
ERROR_EA_FILE_CORRUPT
	The EA file on the mounted file system is damaged.
ERROR_EA_LIST_INCONSISTENT
	The EAs are inconsistent.
ERROR_EA_TABLE_FULL
	The EA table in the EA file on the mounted file system is full.
ERROR_EAS_DIDNT_FIT
	The EAs did not fit in the buffer.
ERROR_EAS_NOT_SUPPORTED
	The mounted file system does not support extended attributes.
ERROR_END_OF_MEDIA
	End of tape mark was reached during an operation.
ERROR_ENVVAR_NOT_FOUND
	The system could not find the environment option entered.
ERROR_EOM_OVERFLOW
	Physical end of tape encountered.
ERROR_EVENTLOG_CANT_START
	No event log file could be opened, so the event logging service did not start.
ERROR_EVENTLOG_FILE_CHANGED
	The event log file has changed between reads.
ERROR_EVENTLOG_FILE_CORRUPT
	One of the Eventlog logfiles is damaged.
ERROR_EXCEPTION_IN_SERVICE
	An exception occurred in the service when handling the control request.
ERROR_EXCL_SEM_ALREADY_OWNED
	The exclusive semaphore is owned by another process.
ERROR_EXE_MARKED_INVALID
	The operating system cannot run %1.
ERROR_EXTENDED_ERROR
	An extended error has occurred.
ERROR_FAIL_I24
	Fail on INT 24.
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
	The service process could not connect to the service controller.
ERROR_FILE_CORRUPT
	The file or directory is damaged and nonreadable.
ERROR_FILE_EXISTS
	The file exists.
ERROR_FILE_INVALID
	The volume for a file was externally altered and the opened file is no longer valid.
ERROR_FILE_NOT_FOUND
	The system cannot find the file specified.
ERROR_FILEMARK_DETECTED
	A tape access reached a filemark.
ERROR_FILENAME_EXCED_RANGE
	The file name or extension is too long.
ERROR_FLOPPY_BAD_REGISTERS
	The floppy disk controller returned inconsistent results in its registers.
ERROR_FLOPPY_ID_MARK_NOT_FOUND
	No ID address mark was found on the floppy disk.
ERROR_FLOPPY_WRONG_CYLINDER
	Mismatch between the floppy disk sector ID field and the floppy disk controller track address.
ERROR_FLOPPY_UNKNOWN_ERROR
	The floppy disk controller reported an error that is not recognized by the floppy disk driver.
ERROR_FULLSCREEN_MODE
	The requested operation cannot be performed in full-screen mode.
ERROR_GEN_FAILURE
	A device attached to the system is not functioning.
ERROR_GENERIC_NOT_MAPPED
	Indicates generic access types were contained in an access mask that should already be mapped to non-generic access types.
ERROR_GLOBAL_ONLY_HOOK
	This hook can only be set globally.
ERROR_GROUP_EXISTS
	The specified group already exists.
ERROR_HANDLE_DISK_FULL
	The disk is full.
ERROR_HANDLE_EOF
	Reached End Of File.
ERROR_HOOK_NEEDS_HMOD
	Cannot set non-local hook without an module handle.
ERROR_HOOK_NOT_INSTALLED
	Hook is not installed.
ERROR_HOTKEY_ALREADY_REGISTERED
	Hotkey is already registered.
ERROR_HOTKEY_NOT_REGISTERED
	Hotkey is not registered.
ERROR_HWNDS_HAVE_DIFFERENT_PARENT
	All DeferWindowPos HWNDs must have same parent.
ERROR_ILL_FORMED_PASSWORD
	When trying to update a password, this return status indicates the value provided for the new password contains values not allowed in passwords.
ERROR_INFLOOP_IN_RELOC_CHAIN
	The operating system cannot run.
ERROR_INSUFFICIENT_BUFFER
	The data area passed to a system call is too small.
ERROR_INTERNAL_DB_CORRUPTION
	This error indicates the requested operation cannot be completed due to a catastrophic media failure or on-disk data structure corruption.
ERROR_INTERNAL_DB_ERROR
	The Local Security Authority (LSA) database contains in internal inconsistency.
ERROR_INTERNAL_ERROR
	This error indicates the SAM server has encounterred an internal consistency error in its database. This catastrophic failure prevents further operation of SAM.
ERROR_INVALID_ACCEL_HANDLE
	Invalid accelerator-table handle.
ERROR_INVALID_ACCESS
	The access code is invalid.
ERROR_INVALID_ACCOUNT_NAME
	The name provided is not a properly formed account name.
ERROR_INVALID_ACL
	Indicates the ACL structure is not valid.
ERROR_INVALID_ADDRESS
	Attempt to access invalid address.
ERROR_INVALID_AT_INTERRUPT_TIME
	Cannot request exclusive semaphores at interrupt time.
ERROR_INVALID_BLOCK
	The storage control block address is invalid.
ERROR_INVALID_BLOCK_LENGTH
	When accessing a new tape of a multivolume partition, the current block size is incorrect.
ERROR_INVALID_CATEGORY
	The IOCTL call made by the application program is incorrect.
ERROR_INVALID_COMBOBOX_MESSAGE
	Invalid Message, combo box doesn't have an edit control.
ERROR_INVALID_COMPUTERNAME
	The format of the specified computer name is invalid.
ERROR_INVALID_CURSOR_HANDLE
	The cursor handle is invalid.
ERROR_INVALID_DATA
	The data is invalid.
ERROR_INVALID_DATATYPE
	The specified datatype is invalid.
ERROR_INVALID_DOMAINNAME
	The format of the specified domain name is invalid.
ERROR_INVALID_DOMAIN_ROLE
	Indicates the requested operation cannot be completed with the domain in its present role.
ERROR_INVALID_DOMAIN_STATE
	Indicates the domain is in the wrong state to perform the desired operation.
ERROR_INVALID_DRIVE
	The system cannot find the specified drive.
ERROR_INVALID_DWP_HANDLE
	The DeferWindowPos handle is invalid.
ERROR_INVALID_EA_HANDLE
	The specified EA handle is invalid.
ERROR_INVALID_EA_NAME
	The specified EA name is invalid.
ERROR_INVALID_EDIT_HEIGHT
	Height must be less than 256.
ERROR_INVALID_ENVIRONMENT
	The Environment specified is invalid.
ERROR_INVALID_EVENT_COUNT
	The number of specified semaphore events is incorrect.
ERROR_INVALID_EVENTNAME
	The format of the specified event name is invalid.
ERROR_INVALID_EXE_SIGNATURE
	%1 cannot be run in Windows/NT mode.
ERROR_INVALID_FILTER_PROC
	The filter proc is invalid.
ERROR_INVALID_FLAG_NUMBER
	The flag passed is incorrect.
ERROR_INVALID_FLAGS
	The flags are invalid.
ERROR_INVALID_FUNCTION
	The function is incorrect.
ERROR_INVALID_GROUP_ATTRIBUTES
	The specified attributes are invalid, or incompatible with the attributes for the group as a whole.
ERROR_INVALID_GROUPNAME
	The format of the specified group name is invalid.
ERROR_INVALID_GW_COMMAND
	The GW_* command is invalid.
ERROR_INVALID_HANDLE
	The internal file identifier is incorrect.
ERROR_INVALID_HOOK_FILTER
	The hook filter type is invalid.
ERROR_INVALID_HOOK_HANDLE
	The hook handle is invalid.
ERROR_INVALID_ICON_HANDLE
	The icon handle is invalid.
ERROR_INVALID_ID_AUTHORITY
	The value provided is an invalid value for an identifier authority.
ERROR_INVALID_INDEX
	The index is invalid.
ERROR_INVALID_LB_MESSAGE
	The message for single-selection list box is invalid.
ERROR_INVALID_LEVEL
	The system call level is incorrect.
ERROR_INVALID_LIST_FORMAT
	The list is not correct.
ERROR_INVALID_LOGON_HOURS
	The user account has time restrictions and cannot be logged onto at this time.
ERROR_INVALID_LOGON_TYPE
	Indicates an invalid value has been provided for LogonType has been requested.
ERROR_INVALID_MEMBER
	A new member could not be added to an alias because the member has the wrong account type.
ERROR_INVALID_MENU_HANDLE
	The menu handle is invalid.
ERROR_INVALID_MESSAGE
	Window can't handle sent message.
ERROR_INVALID_MESSAGEDEST
	The format of the specified message destination is invalid.
ERROR_INVALID_MESSAGENAME
	The format of the specified message name is invalid.
ERROR_INVALID_MINALLOCSIZE
	The operating system cannot run %1.
ERROR_INVALID_MODULETYPE
	The operating system cannot run %1.
ERROR_INVALID_MSGBOX_STYLE
	The message box style is invalid.
ERROR_INVALID_NAME
	The file name, directory name, or volume label is syntactically incorrect.
ERROR_INVALID_NETNAME
	The format of the specified network name is invalid.
ERROR_INVALID_ORDINAL
	The operating system cannot run %1.
ERROR_INVALID_OWNER
	Indicates a particular Security ID cannot be assigned as the owner of an object.
ERROR_INVALID_PARAMETER
	The parameter is incorrect.
ERROR_INVALID_PASSWORD
	The specified network password is incorrect.
ERROR_INVALID_PASSWORDNAME
	The format of the specified password is invalid.
ERROR_INVALID_PRIMARY_GROUP
	Indicates a particular Security ID cannot be assigned as the primary group of an object.
ERROR_INVALID_PRINTER_COMMAND
	The printer command is invalid.
ERROR_INVALID_PRINTER_NAME
	The printer name is invalid.
ERROR_INVALID_PRIORITY
	The specified priority is invalid.
ERROR_INVALID_SCROLLBAR_RANGE
	Scrollbar range greater than 0x7FFF.
ERROR_INVALID_SECURITY_DESCR
	Indicates the SECURITY_DESCRIPTOR structure is invalid.
ERROR_INVALID_SEGDPL
	The operating system cannot run %1.
ERROR_INVALID_SEGMENT_NUMBER
	The system detected a segment number that is incorrect.
ERROR_INVALID_SEPARATOR_FILE
	The specified separator file is invalid.
ERROR_INVALID_SERVER_STATE
	Indicates the Sam Server was in the wrong state to perform the desired operation.
ERROR_INVALID_SERVICE_ACCOUNT
	The account name is invalid or does not exist.
ERROR_INVALID_SERVICE_CONTROL
	The requested control is not valid for this service
ERROR_INVALID_SERVICE_LOCK
	The specified service database lock is invalid.
ERROR_INVALID_SERVICENAME
	The format of the specified service name is invalid.
ERROR_INVALID_SHARENAME
	The format of the specified share name is invalid.
ERROR_INVALID_SHOWWIN_COMMAND
	The ShowWindow command is invalid.
ERROR_INVALID_SID
	Indicates the SID structure is invalid.
ERROR_INVALID_SIGNAL_NUMBER
	The signal being posted is incorrect.
ERROR_INVALID_SPI_VALUE
	The SPI_* parameter is invalid.
ERROR_INVALID_STACKSEG
	The operating system cannot run.
ERROR_INVALID_STARTING_CODESEG
	The operating system cannot run.
ERROR_INVALID_SUB_AUTHORITY
	Indicates the sub-authority value is invalid for the particular use.
ERROR_INVALID_TARGET_HANDLE
	The target internal file identifier is incorrect.
ERROR_INVALID_THREAD_ID
	The thread ID is invalid.
ERROR_INVALID_USER_BUFFER
	The supplied user buffer is invalid for the requested operation.
ERROR_INVALID_VERIFY_SWITCH
	The verify-on-write switch parameter value is incorrect.
ERROR_INVALID_WINDOW_HANDLE
	The window handle invalid.
ERROR_INVALID_WORKSTATION
	The user account is restricted and cannot be used to log on from the source workstation.
ERROR_IO_DEVICE
	The request could not be performed because of an I/O device error.
ERROR_IO_INCOMPLETE
	Overlapped IO event not in signaled state.
ERROR_IO_PENDING
	Overlapped IO operation in progress.
ERROR_IOPL_NOT_ENABLED
	The operating system is not presently configured to run this application.
ERROR_IRQ_BUSY
	Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened.
ERROR_IS_JOIN_PATH
	Not enough resources are available to process this command.
ERROR_IS_JOIN_TARGET
	A JOIN or SUBST command cannot be used for a drive that contains previously joined drives.
ERROR_IS_JOINED
	An attempt was made to use a JOIN or SUBST command on a drive that is already joined.
ERROR_IS_SUBST_PATH
	The path specified is being used in a substitute.
ERROR_IS_SUBST_TARGET
	An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute.
ERROR_IS_SUBSTED
	An attempt was made to use a JOIN or SUBST command on a drive already substituted.
ERROR_ITERATED_DATA_EXCEEDS_64k
	The operating system cannot run %1.
ERROR_JOIN_TO_JOIN
	The system tried to join a drive to a directory on a joined drive.
ERROR_JOIN_TO_SUBST
	The system tried to join a drive to a directory on a substituted drive.
ERROR_JOURNAL_HOOK_SET
	The journal hook is already installed.
ERROR_KEY_DELETED
	Illegal operation attempted on a registry key that has been marked for deletion.
ERROR_KEY_HAS_CHILDREN
	An attempt was made to create a symbolic link in a registry key that already has subkeys or values.
ERROR_LABEL_TOO_LONG
	The volume label entered exceeds the 11 character limit. The first 11 characters were written to disk. Any characters that exceeded the 11 character limit were automatically deleted.
ERROR_LAST_ADMIN
	Indicates the requested operation would disable or delete the last remaining administration account. This is not allowed to prevent creating a situation where the system will not be administrable.
ERROR_LB_WITHOUT_TABSTOPS
	This list box doesn't support tab stops.
ERROR_LISTBOX_ID_NOT_FOUND
	List box ID not found.
ERROR_LM_CROSS_ENCRYPTION_REQUIRED
	An attempt was made to change a user password in the security account manager without providing the required LM cross-encrypted password.
ERROR_LOCAL_USER_SESSION_KEY
	A user session key was requested for a local RPC connection. The session key returned is a constant value and not unique to this connection.
ERROR_LOCK_FAILED
	Attempt to lock a region of a file failed.
ERROR_LOCK_VIOLATION
	The process cannot access the file because another process has locked a portion of the file.
ERROR_LOCKED
	The segment is locked and cannot be reallocated.
ERROR_LOG_FILE_FULL
	The event log file is full.
ERROR_LOGON_FAILURE
	The attempted logon is invalid. This is due to either a bad username or authentication information.
ERROR_LOGON_NOT_GRANTED
	A requested type of logon, such as Interactive, Network, or Service, is not granted by the target system's local security policy. The system administrator can grant the required form of logon.
ERROR_LOGON_SESSION_COLLISION
	The logon session ID is already in use.
ERROR_LOGON_SESSION_EXISTS
	An attempt was made to start a new session manager or LSA logon session with an ID already in use.
ERROR_LOGON_TYPE_NOT_GRANTED
	A user has requested a type of logon, such as interactive or network, that was not granted. An administrator has control over who may logon interactively and through the network.
ERROR_LUIDS_EXHAUSTED
	Indicates there are no more LUID to allocate.
ERROR_MAX_THRDS_REACHED
	No more threads can be created in the system.
ERROR_MEDIA_CHANGED
	Media in drive may have changed.
ERROR_MEMBER_IN_ALIAS
	The specified account name is not a member of the alias.
ERROR_MEMBER_IN_GROUP
	The specified user account is already in the specified group account. Also used to indicate a group can not be deleted because it contains a member.
ERROR_MEMBER_NOT_IN_ALIAS
	The specified account name is not a member of the alias.
ERROR_MEMBER_NOT_IN_GROUP
	The specified user account is not a member of the specified group account.
ERROR_MEMBERS_PRIMARY_GROUP
	Indicates a member cannot be removed from a group because the group is currently the member's primary group.
ERROR_META_EXPANSION_TOO_LONG
	The global filename characters * or ? are entered incorrectly, or too many global filename characters are specified.
ERROR_MOD_NOT_FOUND
	The specified module cannot be found.
ERROR_MORE_DATA
	More data is available.
ERROR_MORE_WRITES
	A serial I/O operation was completed by another write to the serial port. (The IOCTL_SERIAL_XOFF_COUNTER reached zero.)
ERROR_MR_MID_NOT_FOUND
	The system cannot find message for message number 0x%1 in message file for %2.
ERROR_NEGATIVE_SEEK
	An attempt was made to move the file pointer before the beginning of the file.
ERROR_NESTING_NOT_ALLOWED
	Can't nest calls to LoadModule.
ERROR_NETLOGON_NOT_STARTED
	An attempt was made to logon, but the network logon service was not started.
ERROR_NET_WRITE_FAULT
	A write fault occurred on the network.
ERROR_NETNAME_DELETED
	The specified network name is no longer available.
ERROR_NETWORK_ACCESS_DENIED
	Network access is denied.
ERROR_NETWORK_BUSY
	The network is busy.
ERROR_NO_BROWSER_SERVERS_FOUND
	The list of servers for this workgroup is not currently available
ERROR_NO_DATA
	Pipe close in progress.
ERROR_NO_DATA_DETECTED
	During a tape access, the end of the data marker was reached.
ERROR_NO_IMPERSONATION_TOKEN
	An attempt was made to operate on an impersonation token by a thread was not currently impersonating a client.
ERROR_NO_INHERITANCE
	Indicates an ACL contains no inheritable components.
ERROR_NO_LOG_SPACE
	System could not allocate required space in a registry log.
ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
	The account used is an interdomain trust account. Use your normal user account or remote user account to access this server.
ERROR_NOLOGON_SERVER_TRUST_ACCOUNT
	The account used is an server trust account. Use your normal user account or remote user account to access this server.
ERROR_NO_LOGON_SERVERS
	There are currently no logon servers available to service the logon request.
ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT
	The account used is a workstation trust account. Use your normal user account or remote user account to access this server.
ERROR_NO_MEDIA_IN_DRIVE
	Tape query failed because of no media in drive.
ERROR_NO_MORE_FILES
	There are no more files.
ERROR_NO_MORE_ITEMS
	No more data is available.
ERROR_NO_MORE_SEARCH_HANDLES
	No more internal file identifiers available.
ERROR_NO_NET_OR_BAD_PATH
	No network provider accepted the given network path.
ERROR_NO_NETWORK
	The network is not present or not started.
ERROR_NO_PROC_SLOTS
	The system cannot start another process at this time.
ERROR_NO_QUOTAS_FOR_ACCOUNT
	No system quota limits are specifically set for this account.
ERROR_NO_SCROLLBARS
	Window does not have scroll bars.
ERROR_NO_SECURITY_ON_OBJECT
	Indicates an attempt was made to operate on the security of an object that does not have security associated with it.
ERROR_NO_SHUTDOWN_IN_PROGRESS
	An attempt to abort the shutdown of the system failed because no shutdown was in progress.
ERROR_NO_SIGNAL_SENT
	No process in the command subtree has a signal handler.
ERROR_NO_SPOOL_SPACE
	Space to store the file waiting to be printed is not available on the server.
ERROR_NO_SUCH_ALIAS
	The specified alias does not exist.
ERROR_NO_SUCH_DOMAIN
	The specified domain does not exist.
ERROR_NO_SUCH_GROUP
	The specified group does not exist.
ERROR_NO_SUCH_LOGON_SESSION
	A specified logon session does not exist. It may already have been terminated.
ERROR_NO_SUCH_MEMBER
	A new member cannot be added to an alias because the member does not exist.
ERROR_NO_SUCH_PACKAGE
	A specified authentication package is unknown.
ERROR_NO_SUCH_PRIVILEGE
	A specified privilege does not exist.
ERROR_NO_SUCH_USER
	The specified user does not exist.
ERROR_NO_SYSTEM_MENU
	Window does not have system menu.
ERROR_NO_TOKEN
	An attempt was made to reference a token that does not exist.
ERROR_NO_TRUST_LSA_SECRET
	The workstation does not have a trust secret.
ERROR_NO_TRUST_SAM_ACCOUNT
	The domain controller does not have an account for this workstation.
ERROR_NO_UNICODE_TRANSLATION
	No mapping for the Unicode character exists in the target multi-byte code page.
ERROR_NO_USER_SESSION_KEY
	There is no user session key for the specified logon session.
ERROR_NO_VOLUME_LABEL
	The disk has no volume label.
ERROR_NO_WILDCARD_CHARACTERS
	No wildcard characters found.
ERROR_NOACCESS
	Invalid access to memory location.
ERROR_NON_MDICHILD_WINDOW
	DefMDIChildProc called with a non-MDI child window.
ERROR_NONE_MAPPED
	None of the information to be mapped has been translated.
ERROR_NOT_ALL_ASSIGNED
	Indicates not all privileges referenced are assigned to the caller. This allows, for example, all privileges to be disabled without having to know exactly which privileges are assigned.
ERROR_NOT_CHILD_WINDOW
	Window is not a child window.
ERROR_NOT_CONNECTED
	This network connection does not exist.
ERROR_NOT_CONTAINER
	Cannot enumerate a non-container.
ERROR_NOT_DOS_DISK
	The specified disk cannot be accessed.
ERROR_NOT_ENOUGH_MEMORY
	Not enough storage is available to process this command.
ERROR_NOT_ENOUGH_SERVER_MEMORY
	Not enough server storage is available to process this command.
ERROR_NOT_JOINED
	The system attempted to delete the JOIN of a drive not previously joined.
ERROR_NOT_LOCKED
	The segment is already unlocked.
ERROR_NOT_LOGON_PROCESS
	The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process.
ERROR_NOT_OWNER
	Attempt to release mutex not owned by caller.
ERROR_NOT_READY
	The drive is not ready.
ERROR_NOT_REGISTRY_FILE
	The system attempted to load or restore a file into the registry, and the specified file is not in the format of a registry file.
ERROR_NOT_SAME_DEVICE
	The system cannot move the file to a different disk drive.
ERROR_NOT_SUBSTED
	The system attempted to delete the substitution of a drive not previously substituted.
ERROR_NOT_SUPPORTED
	The network request is not supported.
ERROR_NOTIFY_ENUM_DIR
	This indicates that a notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes.
ERROR_NT_CROSS_ENCRYPTION_REQUIRED
	An attempt was made to change a user password in the security account manager without providing the necessary Windows NT cross-encrypted password.
ERROR_NULL_LM_PASSWORD
	The Windows NT password is too complex to be converted to a Windows-networking password. The Windows-networking password returned is a NULL string.
ERROR_OPEN_FAILED
	The system cannot open the specified device or file.
ERROR_OPEN_FILES
	There are open files or requests pending on this connection.
ERROR_OPERATION_ABORTED
	The I/O operation was aborted due to either thread exit or application request.
ERROR_OUT_OF_PAPER
	The printer is out of paper.
ERROR_OUT_OF_STRUCTURES
	Storage to process this request is not available.
ERROR_OUTOFMEMORY
	Not enough storage is available to complete this operation.
ERROR_PARTITION_FAILURE
	Tape could not be partitioned.
ERROR_PASSWORD_EXPIRED
	The user account's password has expired.
ERROR_PASSWORD_RESTRICTION
	When trying to update a password, this status indicates that some password update rule was violated. For example, the password may not meet length criteria.
ERROR_PATH_BUSY
	The specified path cannot be used at this time.
ERROR_PATH_NOT_FOUND
	The system cannot find the specified path.
ERROR_PIPE_BUSY
	All pipe instances busy.
ERROR_PIPE_CONNECTED
	There is a process on other end of the pipe.
ERROR_PIPE_LISTENING
	Waiting for a process to open the other end of the pipe.
ERROR_PIPE_NOT_CONNECTED
	No process on other end of pipe.
ERROR_POPUP_ALREADY_ACTIVE
	Pop-up menu already active.
ERROR_POSSIBLE_DEADLOCK
	A potential deadlock condition has been detected.
ERROR_PRINT_CANCELLED
	File waiting to be printed was deleted.
ERROR_PRINTER_ALREADY_EXISTS
	The printer already exists.
ERROR_PRINTER_DRIVER_ALREADY_INSTALLED
	The specified printer driver is already installed.
ERROR_PRINTQ_FULL
	The printer queue is full.
ERROR_PRIVATE_DIALOG_INDEX
	Using private DIALOG window words.
ERROR_PRIVILEGE_NOT_HELD
	A required privilege is not held by the client.
ERROR_PROC_NOT_FOUND
	The specified procedure could not be found.
ERROR_PROCESS_ABORTED
	The process terminated unexpectedly.
ERROR_READ_FAULT
	The system cannot read from the specified device.
ERROR_REDIR_PAUSED
	The specified printer or disk device has been paused.
ERROR_REDIRECTOR_HAS_OPEN_HANDLES
	The redirector is in use and cannot be unloaded.
ERROR_REGISTRY_CORRUPT
	The registry is damaged. The structure of one of the files that contains registry data is damaged, or the system's in memory image of the file is damaged, or the file could not be recovered because its alternate copy or log was absent or damaged.
ERROR_REGISTRY_IO_FAILED
	The registry initiated an I/O operation that had an unrecoverable failure. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry.
ERROR_REGISTRY_RECOVERED
	One of the files containing the system's registry data had to be recovered by use of a log or alternate copy. The recovery succeeded.
ERROR_RELOC_CHAIN_XEEDS_SEGLIM
	The operating system cannot run.
ERROR_REM_NOT_LIST
	The remote computer is not available.
ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
	An attempt was made to establish a session to an Advanced Server server, but there are already too many sessions established to that server.
ERROR_REQ_NOT_ACCEP
	The network request was not accepted.
ERROR_NOT_ENOUGH_QUOTA
	Not enough quota is available to process this command.
ERROR_RESOURCE_DATA_NOT_FOUND
	The specified image file did not contain a resource section.
ERROR_RESOURCE_LANG_NOT_FOUND
	The specified resource language ID cannot be found in the image file.
ERROR_RESOURCE_NAME_NOT_FOUND
	The specified resource name can not be found in the image file.
ERROR_RESOURCE_TYPE_NOT_FOUND
	The specified resource type can not be found in the image file.
ERROR_REVISION_MISMATCH
	Indicates two revision levels are incompatible.
ERROR_RING2_STACK_IN_USE
	The ring 2 stack is in use.
ERROR_RING2SEG_MUST_BE_MOVABLE
	The code segment cannot be greater than or equal to 64KB.
ERROR_RXACT_COMMIT_FAILURE
	Indicates an error occurred during a registry transaction commit. The database has been left in an unknown state. The state of the registry transaction is left as COMMITTING. This status value is returned by the runtime library (RTL) registry transaction package (RXact).
ERROR_RXACT_INVALID_STATE
	Indicates that the transaction state of a registry sub-tree is incompatible with the requested operation. For example, a request has been made to start a new transaction with one already in progress, or a request to apply a transaction when one is not currently in progress. This status value is returned by the runtime library (RTL) registry transaction package (RXact).
ERROR_SAME_DRIVE
	The system cannot join or substitute a drive to or for a directory on the same drive.
ERROR_SCREEN_ALREADY_LOCKED
	Screen already locked.
ERROR_SECRET_TOO_LONG
	The length of an secret exceeds the maximum length allowed. The length and number of secrets is limited to satisfy the United States State Department export restrictions.
ERROR_SECTOR_NOT_FOUND
	The drive cannot find the requested sector.
ERROR_SEEK
	The drive cannot locate a specific area or track on the disk.
ERROR_SEEK_ON_DEVICE
	The file pointer cannot be set on the specified device or file.
ERROR_SEM_IS_SET
	The semaphore is set and cannot be closed.
ERROR_SEM_NOT_FOUND
	The specified system semaphore name was not found.
ERROR_SEM_OWNER_DIED
	The previous ownership of this semaphore has ended.
ERROR_SEM_TIMEOUT
	The semaphore timeout period has expired.
ERROR_SEM_USER_LIMIT
	Insert the disk for drive 1.
ERROR_SERIAL_NO_DEVICE
	No serial device was successfully initialized. The serial driver will unload.
ERROR_SERVER_DISABLED
	The GUID allocation server is already disabled at the moment.
ERROR_SERVER_HAS_OPEN_HANDLES
	The server is in use and cannot be unloaded.
ERROR_SERVER_NOT_DISABLED
	The GUID allocation server is already enabled at the moment.
ERROR_SERVICE_ALREADY_RUNNING
	An instance of the service is already running.
ERROR_SERVICE_CANNOT_ACCEPT_CTRL
	The service cannot accept control messages at this time.
ERROR_SERVICE_DATABASE_LOCKED
	The service database is locked.
ERROR_SERVICE_DEPENDENCY_DELETED
	The dependency service does not exist or has been marked for deletion.
ERROR_SERVICE_DEPENDENCY_FAIL
	The dependency service or group failed to start.
ERROR_SERVICE_DISABLED
	The specified service is disabled and cannot be started.
ERROR_SERVICE_DOES_NOT_EXIST
	The specified service does not exist as an installed service.
ERROR_SERVICE_EXISTS
	The specified service already exists.
ERROR_SERVICE_LOGON_FAILED
	The service did not start due to a logon failure.
ERROR_SERVICE_MARKED_FOR_DELETE
	The specified service has been marked for deletion.
ERROR_SERVICE_NEVER_STARTED
	No attempts to start the service have been made since the last boot.
ERROR_SERVICE_NO_THREAD
	A thread could not be created for the service.
ERROR_SERVICE_NOT_ACTIVE
	The service has not been started.
ERROR_SERVICE_REQUEST_TIMEOUT
	The service did not respond to the start or control request in a timely fashion.
ERROR_SERVICE_SPECIFIC_ERROR
	The service has returned a service-specific error code.
ERROR_SERVICE_START_HANG
	After starting, the service hung in a start-pending state.
ERROR_SESSION_CREDENTIAL_CONFLICT
	The credentials supplied conflict with an existing set of credentials.
ERROR_SETCOUNT_ON_BAD_LB
	LB_SETCOUNT sent to non-lazy list box.
ERROR_SETMARK_DETECTED
	A tape access reached a setmark.
ERROR_SHARING_BUFFER_EXCEEDED
	Too many files opened for sharing.
ERROR_SHARING_PAUSED
	The remote server is paused or is in the process of being started.
ERROR_SHARING_VIOLATION
	The process cannot access the file because it is being used by another process.
ERROR_SHUTDOWN_IN_PROGRESS
	A system shutdown is in progress.
ERROR_SIGNAL_PENDING
	A signal is already pending.
ERROR_SIGNAL_REFUSED
	The recipient process has refused the signal.
ERROR_SOME_NOT_MAPPED
	Some of the information to be mapped has not been translated.
ERROR_SPECIAL_ACCOUNT
	Indicates an operation was attempted on a built-in (special) SAM account that is incompatible with built-in accounts. For example, built-in accounts cannot be renamed or deleted.
ERROR_SPECIAL_GROUP
	The requested operation cannot be performed on the specified group because it is a built-in special group.
ERROR_SPECIAL_USER
	The requested operation cannot be performed on the specified user because it is a built-in special user.
ERROR_STACK_OVERFLOW
	Recursion too deep, stack overflowed.
ERROR_SUBST_TO_JOIN
	The system attempted to SUBST a drive to a directory on a joined drive.
ERROR_SUBST_TO_SUBST
	The system attempted to substitute a drive to a directory on a substituted drive.
ERROR_SUCCESS
	The operation was successfully completed.
ERROR_SWAPERROR
	Error accessing paging file.
ERROR_SYSTEM_TRACE
	System trace information not specified in your CONFIG.SYS file, or tracing is not allowed.
ERROR_THREAD_1_INACTIVE
	The signal handler cannot be set.
ERROR_TLW_WITH_WSCHILD
	CreateWindow failed, creating top-level window with WS_CHILD style.
ERROR_TOKEN_ALREADY_IN_USE
	An attempt was made to establish a token for use as a primary token but the token is already in use. A token can only be the primary token of one process at a time.
ERROR_TOO_MANY_CMDS
	The network BIOS command limit has been reached.
ERROR_TOO_MANY_CONTEXT_IDS
	During a logon attempt, the user's security context accumulated too many security IDs. Remove the user from some groups or aliases to reduce the number of security ids to incorporate into the security context.
ERROR_TOO_MANY_LUIDS_REQUESTED
	The number of LUID requested cannot be allocated with a single allocation.
ERROR_TOO_MANY_MODULES
	Too many dynamic link modules are attached to this program or dynamic link module.
ERROR_TOO_MANY_MUXWAITERS
	Too many semaphores are already set.
ERROR_TOO_MANY_NAMES
	The name limit for the local computer network adapter card exceeded.
ERROR_TOO_MANY_OPEN_FILES
	The system cannot open the file.
ERROR_TOO_MANY_POSTS
	Too many posts made to a semaphore.
ERROR_TOO_MANY_SECRETS
	The maximum number of secrets that can be stored in a single system was exceeded. The length and number of secrets is limited to satisfy the United States State Department export restrictions.
ERROR_TOO_MANY_SEM_REQUESTS
	The semaphore cannot be set again.
ERROR_TOO_MANY_SEMAPHORES
	Cannot create another system semaphore.
ERROR_TOO_MANY_SESS
	The network BIOS session limit exceeded.
ERROR_TOO_MANY_SIDS
	Too many SIDs specified.
ERROR_TOO_MANY_TCBS
	Cannot create another thread.
ERROR_TRUST_FAILURE
	The network logon failed.
ERROR_TRUSTED_DOMAIN_FAILURE
	The trust relationship between the primary domain and the trusted domain failed.
ERROR_TRUSTED_RELATIONSHIP_FAILURE
	The trust relationship between this workstation and the primary domain failed.
ERROR_UNABLE_TO_LOCK_MEDIA
	Attempt to lock the eject media mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA
	Unload media failed.
ERROR_UNEXP_NET_ERR
	An unexpected network error occurred.
ERROR_UNKNOWN_PORT
	The specified port is unknown.
ERROR_UNKNOWN_PRINTPROCESSOR
	The print processor is unknown.
ERROR_UNKNOWN_PRINTER_DRIVER
	The printer driver is unknown.
ERROR_UNKNOWN_REVISION
	Indicates an encountered or specified revision number is not one known by the service. The service may not be aware of a more recent revision.
ERROR_UNRECOGNIZED_MEDIA
	The disk media is not recognized. It may not be formatted.
ERROR_UNRECOGNIZED_VOLUME
	The volume does not contain a recognized file system. Make sure that all required file system drivers are loaded and the volume is not damaged.
ERROR_USER_EXISTS
	The specified user already exists.
ERROR_VC_DISCONNECTED
	The session was canceled.
ERROR_WAIT_NO_CHILDREN
	There are no child processes to wait for.
ERROR_WINDOW_NOT_COMBOBOX
	The window is not a combo box.
ERROR_WINDOW_NOT_DIALOG
	The window is not a valid dialog window.
ERROR_WINDOW_OF_OTHER_THREAD
	Invalid window, belongs to other thread.
ERROR_WRITE_FAULT
	The system cannot write to the specified device.
ERROR_WRITE_PROTECT
	The media is write protected.
ERROR_WRONG_DISK
	The wrong disk is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.
ERROR_WRONG_PASSWORD
	When trying to update a password, this return status indicates the value provided as the current password is incorrect.
LZERROR_BADINHANDLE
	Invalid input handle.
LZERROR_BADOUTHANDLE
	Invalid output handle.
LZERROR_BADVALUE
	Input parameter out of acceptable range.
LZERROR_GLOBALLOC
	Insufficient memory for LZFile structure.
LZERROR_GLOBLOCK
	Bad global handle.
LZERROR_READ
	Corrupt compressed file format.
LZERROR_WRITE
	Out of space for output file.
LZERROR_UNKNOWNALG
	Compression algorithm not recognized.
NO_ERROR
	No error.
RPC_S_ADDRESS_ERROR
	An addressing error occurred in the server.
RPC_S_ALREADY_LISTENING
	The server is already listening.
RPC_S_ALREADY_REGISTERED
	The object UUID already registered.
RPC_S_BINDING_HAS_NO_AUTH
	The binding does not contain any authentication information.
RPC_S_CALL_FAILED
	The remote procedure call failed.
RPC_S_CALL_FAILED_DNE
	The remote procedure call failed and did not execute.
RPC_S_CALL_IN_PROGRESS
	A remote procedure call is already in progress for this thread.
RPC_S_CANNOT_BIND
	An attempt to bind with the server failed.
RPC_S_CANNOT_SUPPORT
	The requested operation is not supported.
RPC_S_CANT_CREATE_ENDPOINT
	The endpoint cannot be created.
RPC_S_DUPLICATE_ENDPOINT
	The endpoint is a duplicate.
RPC_S_ENTRY_ALREADY_EXISTS
	The entry already exists.
RPC_S_ENTRY_NOT_FOUND
	The entry is not found.
RPC_S_FP_DIV_ZERO
	A floating point operation at the server caused a divide by zero.
RPC_S_FP_OVERFLOW
	A floating point overflow occurred at the server.
RPC_S_FP_UNDERFLOW
	A floating point underflow occurred at the server.
RPC_S_GROUP_MEMBER_NOT_FOUND
	The group member was not found.
RPC_S_INCOMPLETE_NAME
	The entry name is incomplete.
RPC_S_INTERFACE_NOT_FOUND
	The interface was not found.
RPC_S_INTERNAL_ERROR
	An internal error occurred in RPC.
RPC_S_INVALID_AUTH_IDENTITY
	The security context is invalid.
RPC_S_INVALID_BINDING
	The binding handle is invalid.
RPC_S_INVALID_BOUND
	The array bounds are invalid.
RPC_S_INVALID_ENDPOINT_FORMAT
	The endpoint format is invalid.
RPC_S_INVALID_NAF_IF
	The network address family is invalid.
RPC_S_INVALID_NAME_SYNTAX
	The name syntax is invalid.
RPC_S_INVALID_NET_ADDR
	The network address is invalid.
RPC_S_INVALID_NETWORK_OPTIONS
	The network options are invalid.
RPC_S_INVALID_OBJECT
	The object universal unique identifier (UUID) is the nil UUID.
RPC_S_INVALID_RPC_PROTSEQ
	The RPC protocol sequence is invalid.
RPC_S_INVALID_STRING_BINDING
	The string binding is invalid.
RPC_S_INVALID_STRING_UUID
	The string UUID is invalid.
RPC_S_INVALID_TAG
	The tag is invalid.
RPC_S_INVALID_TIMEOUT
	The timeout value is invalid.
RPC_S_INVALID_VERS_OPTION
	The version option is invalid.
RPC_S_MAX_CALLS_TOO_SMALL
	The maximum number of calls is too small.
RPC_S_NAME_SERVICE_UNAVAILABLE
	The name service is unavailable.
RPC_S_NO_BINDINGS
	There are no bindings.
RPC_S_NO_CALL_ACTIVE
	There is not a remote procedure call active in this thread.
RPC_S_NO_CONTEXT_AVAILABLE
	No security context is available to allow impersonation.
RPC_S_NO_ENDPOINT_FOUND
	No endpoint was found.
RPC_S_NO_ENTRY_NAME
	The binding does not contain an entry name.
RPC_S_NO_INTERFACES_EXPORTED
	No interfaces were exported.
RPC_S_NO_MORE_BINDINGS
	There are no more bindings.
RPC_S_NO_MORE_MEMBERS
	There are no more members.
RPC_S_NO_PROTSEQS
	There are no protocol sequences.
RPC_S_NO_PROTSEQS_REGISTERED
	No protocol sequences were registered.
RPC_S_NOT_LISTENING
	The server is not listening.
RPC_S_NOTHING_TO_UNEXPORT
	There is nothing to unexport.
RPC_S_OBJECT_NOT_FOUND
	The object UUID was not found.
RPC_S_OUT_OF_RESOURCES
	Not enough resources are available to complete this operation.
RPC_S_PROCNUM_OUT_OF_RANGE
	The procedure number is out of range.
RPC_S_PROTOCOL_ERROR
	An RPC protocol error occurred.
RPC_S_PROTSEQ_NOT_FOUND
	The RPC protocol sequence was not found.
RPC_S_PROTSEQ_NOT_SUPPORTED
	The RPC protocol sequence is not supported.
RPC_S_SERVER_NOT_LISTENING
	The server is not listening for remote procedure calls.
RPC_S_SERVER_OUT_OF_MEMORY
	The server has insufficient memory to complete this operation.
RPC_S_SERVER_TOO_BUSY
	The server is too busy to complete this operation.
RPC_S_SERVER_UNAVAILABLE
	The server is unavailable.
RPC_S_STRING_TOO_LONG
	The string is too long.
RPC_S_TYPE_ALREADY_REGISTERED
	The type UUID is already registered.
RPC_S_UNKNOWN_AUTHN_LEVEL
	The authentication level is unknown.
RPC_S_UNKNOWN_AUTHN_SERVICE
	The authentication service is unknown.
RPC_S_UNKNOWN_AUTHN_TYPE
	The authentication type is unknown.
RPC_S_UNKNOWN_AUTHZ_SERVICE
	The authorization service is unknown.
RPC_S_UNKNOWN_IF
	The interface is unknown.
RPC_S_UNKNOWN_MGR_TYPE
	The manager type is unknown.
RPC_S_UNSUPPORTED_NAME_SYNTAX
	The name syntax is not supported.
RPC_S_UNSUPPORTED_TRANS_SYN
	The transfer syntax is not supported by the server.
RPC_S_UNSUPPORTED_TYPE
	The type UUID is not supported.
RPC_S_UUID_NO_ADDRESS
	No network address is available to use to construct a UUID.
RPC_S_WRONG_KIND_OF_BINDING
	The binding handle is the incorrect type.
RPC_S_ZERO_DIVIDE
	The server attempted an integer divide by zero.
RPC_X_BAD_STUB_DATA
	The stub received bad data.
RPC_X_BYTE_COUNT_TOO_SMALL
	The byte count is too small.
RPC_X_ENUM_VALUE_OUT_OF_RANGE
	The enumeration value is out of range.
RPC_X_NO_MORE_ENTRIES
	The list of servers available for auto_handle binding was exhausted.
RPC_X_NULL_REF_POINTER
	A null reference pointer was passed to the stub.
RPC_X_SS_CANNOT_GET_CALL_HANDLE
	The stub is unable to get the call handle.
RPC_X_SS_CHAR_TRANS_OPEN_FAIL
	The file designated by DCERPCCHARTRANS cannot be opened.
RPC_X_SS_CHAR_TRANS_SHORT_FILE
	The file containing the character translation table has fewer than 512 bytes.
RPC_X_SS_CONTEXT_DAMAGED
	The context handle changed during a call.
RPC_X_SS_CONTEXT_MISMATCH
	The context handle does not match any known context handles.
RPC_X_SS_HANDLES_MISMATCH
	The binding handles passed to a remote procedure call do not match.
RPC_X_SS_IN_NULL_CONTEXT
	A null context handle is passed as an [in] parameter.


  Numerical List of Error Codes

-8 LZERROR_UNKNOWNALG

-7 LZERROR_BADVALUE

-6 LZERROR_GLOBLOCK

-5 LZERROR_GLOBALLOC

-4 LZERROR_WRITE

-3 LZERROR_READ

-2 LZERROR_BADOUTHANDLE

-1 LZERROR_BADINHANDLE

0L NO_ERROR

0L ERROR_SUCCESS

1L ERROR_INVALID_FUNCTION

2L ERROR_FILE_NOT_FOUND

3L ERROR_PATH_NOT_FOUND

4L ERROR_TOO_MANY_OPEN_FILES

5L ERROR_ACCESS_DENIED

6L ERROR_INVALID_HANDLE

7L ERROR_ARENA_TRASHED

8L ERROR_NOT_ENOUGH_MEMORY

9L ERROR_INVALID_BLOCK

10L ERROR_BAD_ENVIRONMENT

11L ERROR_BAD_FORMAT

12L ERROR_INVALID_ACCESS

13L ERROR_INVALID_DATA

14L ERROR_OUTOFMEMORY

15L ERROR_INVALID_DRIVE

16L ERROR_CURRENT_DIRECTORY

17L ERROR_NOT_SAME_DEVICE

18L ERROR_NO_MORE_FILES

19L ERROR_WRITE_PROTECT

20L ERROR_BAD_UNIT

21L ERROR_NOT_READY

22L ERROR_BAD_COMMAND

23L ERROR_CRC

24L ERROR_BAD_LENGTH

25L ERROR_SEEK

26L ERROR_NOT_DOS_DISK

27L ERROR_SECTOR_NOT_FOUND

28L ERROR_OUT_OF_PAPER

29L ERROR_WRITE_FAULT

30L ERROR_READ_FAULT

31L ERROR_GEN_FAILURE

32L ERROR_SHARING_VIOLATION

33L ERROR_LOCK_VIOLATION

34L ERROR_WRONG_DISK

36L ERROR_SHARING_BUFFER_EXCEEDED

38L ERROR_HANDLE_EOF

39L ERROR_HANDLE_DISK_FULL

50L ERROR_NOT_SUPPORTED

51L ERROR_REM_NOT_LIST

52L ERROR_DUP_NAME

53L ERROR_BAD_NETPATH

54L ERROR_NETWORK_BUSY

55L ERROR_DEV_NOT_EXIST

56L ERROR_TOO_MANY_CMDS

57L ERROR_ADAP_HDW_ERR

58L ERROR_BAD_NET_RESP

59L ERROR_UNEXP_NET_ERR

60L ERROR_BAD_REM_ADAP

61L ERROR_PRINTQ_FULL

62L ERROR_NO_SPOOL_SPACE

63L ERROR_PRINT_CANCELLED

64L ERROR_NETNAME_DELETED

65L ERROR_NETWORK_ACCESS_DENIED

66L ERROR_BAD_DEV_TYPE

67L ERROR_BAD_NET_NAME

68L ERROR_TOO_MANY_NAMES

69L ERROR_TOO_MANY_SESS

70L ERROR_SHARING_PAUSED

71L ERROR_REQ_NOT_ACCEP

72L ERROR_REDIR_PAUSED

80L ERROR_FILE_EXISTS

82L ERROR_CANNOT_MAKE

83L ERROR_FAIL_I24

84L ERROR_OUT_OF_STRUCTURES

85L ERROR_ALREADY_ASSIGNED

86L ERROR_INVALID_PASSWORD

87L ERROR_INVALID_PARAMETER

88L ERROR_NET_WRITE_FAULT

89L ERROR_NO_PROC_SLOTS

100L ERROR_TOO_MANY_SEMAPHORES

101L ERROR_EXCL_SEM_ALREADY_OWNED

102L ERROR_SEM_IS_SET

103L ERROR_TOO_MANY_SEM_REQUESTS

104L ERROR_INVALID_AT_INTERRUPT_TIME

105L ERROR_SEM_OWNER_DIED

106L ERROR_SEM_USER_LIMIT

107L ERROR_DISK_CHANGE

108L ERROR_DRIVE_LOCKED

109L ERROR_BROKEN_PIPE

110L ERROR_OPEN_FAILED

111L ERROR_BUFFER_OVERFLOW

112L ERROR_DISK_FULL

113L ERROR_NO_MORE_SEARCH_HANDLES

114L ERROR_INVALID_TARGET_HANDLE

117L ERROR_INVALID_CATEGORY

118L ERROR_INVALID_VERIFY_SWITCH

119L ERROR_BAD_DRIVER_LEVEL

120L ERROR_CALL_NOT_IMPLEMENTED

121L ERROR_SEM_TIMEOUT

122L ERROR_INSUFFICIENT_BUFFER

123L ERROR_INVALID_NAME

124L ERROR_INVALID_LEVEL

125L ERROR_NO_VOLUME_LABEL

126L ERROR_MOD_NOT_FOUND

127L ERROR_PROC_NOT_FOUND

128L ERROR_WAIT_NO_CHILDREN

129L ERROR_CHILD_NOT_COMPLETE

130L ERROR_DIRECT_ACCESS_HANDLE

131L ERROR_NEGATIVE_SEEK

132L ERROR_SEEK_ON_DEVICE

133L ERROR_IS_JOIN_TARGET

134L ERROR_IS_JOINED

135L ERROR_IS_SUBSTED

136L ERROR_NOT_JOINED

137L ERROR_NOT_SUBSTED

138L ERROR_JOIN_TO_JOIN

139L ERROR_SUBST_TO_SUBST

140L ERROR_JOIN_TO_SUBST

141L ERROR_SUBST_TO_JOIN

142L ERROR_BUSY_DRIVE

143L ERROR_SAME_DRIVE

144L ERROR_DIR_NOT_ROOT

145L ERROR_DIR_NOT_EMPTY

146L ERROR_IS_SUBST_PATH

147L ERROR_IS_JOIN_PATH

148L ERROR_PATH_BUSY

149L ERROR_IS_SUBST_TARGET

150L ERROR_SYSTEM_TRACE

151L ERROR_INVALID_EVENT_COUNT

152L ERROR_TOO_MANY_MUXWAITERS

153L ERROR_INVALID_LIST_FORMAT

154L ERROR_LABEL_TOO_LONG

155L ERROR_TOO_MANY_TCBS

156L ERROR_SIGNAL_REFUSED

157L ERROR_DISCARDED

158L ERROR_NOT_LOCKED

159L ERROR_BAD_THREADID_ADDR

160L ERROR_BAD_ARGUMENTS

161L ERROR_BAD_PATHNAME

162L ERROR_SIGNAL_PENDING

164L ERROR_MAX_THRDS_REACHED

167L ERROR_LOCK_FAILED

170L ERROR_BUSY

173L ERROR_CANCEL_VIOLATION

174L ERROR_ATOMIC_LOCKS_NOT_SUPPORTED

180L ERROR_INVALID_SEGMENT_NUMBER

182L ERROR_INVALID_ORDINAL

183L ERROR_ALREADY_EXISTS

186L ERROR_INVALID_FLAG_NUMBER

187L ERROR_SEM_NOT_FOUND

188L ERROR_INVALID_STARTING_CODESEG

189L ERROR_INVALID_STACKSEG

190L ERROR_INVALID_MODULETYPE

191L ERROR_INVALID_EXE_SIGNATURE

192L ERROR_EXE_MARKED_INVALID

193L ERROR_BAD_EXE_FORMAT

194L ERROR_ITERATED_DATA_EXCEEDS_64k

195L ERROR_INVALID_MINALLOCSIZE

196L ERROR_DYNLINK_FROM_INVALID_RING

197L ERROR_IOPL_NOT_ENABLED

198L ERROR_INVALID_SEGDPL

199L ERROR_AUTODATASEG_EXCEEDS_64k

200L ERROR_RING2SEG_MUST_BE_MOVABLE

201L ERROR_RELOC_CHAIN_XEEDS_SEGLIM

202L ERROR_INFLOOP_IN_RELOC_CHAIN

203L ERROR_ENVVAR_NOT_FOUND

205L ERROR_NO_SIGNAL_SENT

206L ERROR_FILENAME_EXCED_RANGE

207L ERROR_RING2_STACK_IN_USE

208L ERROR_META_EXPANSION_TOO_LONG

209L ERROR_INVALID_SIGNAL_NUMBER

210L ERROR_THREAD_1_INACTIVE

212L ERROR_LOCKED

214L ERROR_TOO_MANY_MODULES

215L ERROR_NESTING_NOT_ALLOWED

230L ERROR_BAD_PIPE

231L ERROR_PIPE_BUSY

232L ERROR_NO_DATA

233L ERROR_PIPE_NOT_CONNECTED

234L ERROR_MORE_DATA

240L ERROR_VC_DISCONNECTED

254L ERROR_INVALID_EA_NAME

255L ERROR_EA_LIST_INCONSISTENT

259L ERROR_NO_MORE_ITEMS

266L ERROR_CANNOT_COPY

267L ERROR_DIRECTORY

275L ERROR_EAS_DIDNT_FIT

276L ERROR_EA_FILE_CORRUPT

277L ERROR_EA_TABLE_FULL

278L ERROR_INVALID_EA_HANDLE

282L ERROR_EAS_NOT_SUPPORTED

288L ERROR_NOT_OWNER

298L ERROR_TOO_MANY_POSTS

317L ERROR_MR_MID_NOT_FOUND

487L ERROR_INVALID_ADDRESS

534L ERROR_ARITHMETIC_OVERFLOW

535L ERROR_PIPE_CONNECTED

536L ERROR_PIPE_LISTENING

994L ERROR_EA_ACCESS_DENIED

995L ERROR_OPERATION_ABORTED

996L ERROR_IO_INCOMPLETE

997L ERROR_IO_PENDING

998L ERROR_NOACCESS

999L ERROR_SWAPERROR

1001L ERROR_STACK_OVERFLOW

1002L ERROR_INVALID_MESSAGE

1003L ERROR_CAN_NOT_COMPLETE

1004L ERROR_INVALID_FLAGS

1005L ERROR_UNRECOGNIZED_VOLUME

1006L ERROR_FILE_INVALID

1007L ERROR_FULLSCREEN_MODE

1008L ERROR_NO_TOKEN

1009L ERROR_BADDB

1010L ERROR_BADKEY

1011L ERROR_CANTOPEN

1012L ERROR_CANTREAD

1013L ERROR_CANTWRITE

1014L ERROR_REGISTRY_RECOVERED

1015L ERROR_REGISTRY_CORRUPT

1016L ERROR_REGISTRY_IO_FAILED

1017L ERROR_NOT_REGISTRY_FILE

1018L ERROR_KEY_DELETED

1019L ERROR_NO_LOG_SPACE

1020L ERROR_KEY_HAS_CHILDREN

1021L ERROR_CHILD_MUST_BE_VOLATILE

1022L ERROR_NOTIFY_ENUM_DIR

1051L ERROR_DEPENDENT_SERVICES_RUNNING

1052L ERROR_INVALID_SERVICE_CONTROL

1053L ERROR_SERVICE_REQUEST_TIMEOUT

1054L ERROR_SERVICE_NO_THREAD

1055L ERROR_SERVICE_DATABASE_LOCKED

1056L ERROR_SERVICE_ALREADY_RUNNING

1057L ERROR_INVALID_SERVICE_ACCOUNT

1058L ERROR_SERVICE_DISABLED

1059L ERROR_CIRCULAR_DEPENDENCY

1060L ERROR_SERVICE_DOES_NOT_EXIST

1061L ERROR_SERVICE_CANNOT_ACCEPT_CTRL

1062L ERROR_SERVICE_NOT_ACTIVE

1063L ERROR_FAILED_SERVICE_CONTROLLER_CONNECT

1064L ERROR_EXCEPTION_IN_SERVICE

1065L ERROR_DATABASE_DOES_NOT_EXIST

1066L ERROR_SERVICE_SPECIFIC_ERROR

1067L ERROR_PROCESS_ABORTED

1068L ERROR_SERVICE_DEPENDENCY_FAIL

1069L ERROR_SERVICE_LOGON_FAILED

1070L ERROR_SERVICE_START_HANG

1071L ERROR_INVALID_SERVICE_LOCK

1072L ERROR_SERVICE_MARKED_FOR_DELETE

1073L ERROR_SERVICE_EXISTS

1074L ERROR_ALREADY_RUNNING_LKG

1075L ERROR_SERVICE_DEPENDENCY_DELETED

1076L ERROR_BOOT_ALREADY_ACCEPTED

1077L ERROR_SERVICE_NEVER_STARTED

1078L ERROR_DUPLICATE_SERVICE_NAME

1100L ERROR_END_OF_MEDIA

1101L ERROR_FILEMARK_DETECTED

1102L ERROR_BEGINNING_OF_MEDIA

1103L ERROR_SETMARK_DETECTED

1104L ERROR_NO_DATA_DETECTED

1105L ERROR_PARTITION_FAILURE

1106L ERROR_INVALID_BLOCK_LENGTH

1107L ERROR_DEVICE_NOT_PARTITIONED

1108L ERROR_UNABLE_TO_LOCK_MEDIA

1109L ERROR_UNABLE_TO_UNLOAD_MEDIA

1110L ERROR_MEDIA_CHANGED

1111L ERROR_BUS_RESET

1112L ERROR_NO_MEDIA_IN_DRIVE

1113L ERROR_NO_UNICODE_TRANSLATION

1114L ERROR_DLL_INIT_FAILED

1115L ERROR_SHUTDOWN_IN_PROGRESS

1116L ERROR_NO_SHUTDOWN_IN_PROGRESS

1117L ERROR_IO_DEVICE

1118L ERROR_SERIAL_NO_DEVICE

1119L ERROR_IRQ_BUSY

1120L ERROR_MORE_WRITES

1121L ERROR_COUNTER_TIMEOUT

1122L ERROR_FLOPPY_ID_MARK_NOT_FOUND

1123L ERROR_FLOPPY_WRONG_CYLINDER

1124L ERROR_FLOPPY_UNKNOWN_ERROR

1125L ERROR_FLOPPY_BAD_REGISTERS

1126L ERROR_DISK_RECALIBRATE_FAILED

1127L ERROR_DISK_OPERATION_FAILED

1128L ERROR_DISK_RESET_FAILED

1129L ERROR_EOM_OVERFLOW

1130L ERROR_NOT_ENOUGH_SERVER_MEMORY

1131L ERROR_POSSIBLE_DEADLOCK

1200L ERROR_BAD_DEVICE

1201L ERROR_CONNECTION_UNAVAIL

1202L ERROR_DEVICE_ALREADY_REMEMBERED

1203L ERROR_NO_NET_OR_BAD_PATH

1204L ERROR_BAD_PROVIDER

1205L ERROR_CANNOT_OPEN_PROFILE

1206L ERROR_BAD_PROFILE

1207L ERROR_NOT_CONTAINER

1208L ERROR_EXTENDED_ERROR

1209L ERROR_INVALID_GROUPNAME

1210L ERROR_INVALID_COMPUTERNAME

1211L ERROR_INVALID_EVENTNAME

1212L ERROR_INVALID_DOMAINNAME

1213L ERROR_INVALID_SERVICENAME

1214L ERROR_INVALID_NETNAME

1215L ERROR_INVALID_SHARENAME

1216L ERROR_INVALID_PASSWORDNAME

1217L ERROR_INVALID_MESSAGENAME

1218L ERROR_INVALID_MESSAGEDEST

1219L ERROR_SESSION_CREDENTIAL_CONFLICT

1220L ERROR_REMOTE_SESSION_LIMIT_EXCEEDED

1221L ERROR_DUP_DOMAINNAME

1300L ERROR_NOT_ALL_ASSIGNED

1301L ERROR_SOME_NOT_MAPPED

1302L ERROR_NO_QUOTAS_FOR_ACCOUNT

1303L ERROR_LOCAL_USER_SESSION_KEY

1304L ERROR_NULL_LM_PASSWORD

1305L ERROR_UNKNOWN_REVISION

1306L ERROR_REVISION_MISMATCH

1307L ERROR_INVALID_OWNER

1308L ERROR_INVALID_PRIMARY_GROUP

1309L ERROR_NO_IMPERSONATION_TOKEN

1310L ERROR_CANT_DISABLE_MANDATORY

1311L ERROR_NO_LOGON_SERVERS

1312L ERROR_NO_SUCH_LOGON_SESSION

1313L ERROR_NO_SUCH_PRIVILEGE

1314L ERROR_PRIVILEGE_NOT_HELD

1315L ERROR_INVALID_ACCOUNT_NAME

1316L ERROR_USER_EXISTS

1317L ERROR_NO_SUCH_USER

1318L ERROR_GROUP_EXISTS

1319L ERROR_NO_SUCH_GROUP

1320L ERROR_MEMBER_IN_GROUP

1321L ERROR_MEMBER_NOT_IN_GROUP

1322L ERROR_LAST_ADMIN

1323L ERROR_WRONG_PASSWORD

1324L ERROR_ILL_FORMED_PASSWORD

1325L ERROR_PASSWORD_RESTRICTION

1326L ERROR_LOGON_FAILURE

1327L ERROR_ACCOUNT_RESTRICTION

1328L ERROR_INVALID_LOGON_HOURS

1329L ERROR_INVALID_WORKSTATION

1330L ERROR_PASSWORD_EXPIRED

1331L ERROR_ACCOUNT_DISABLED

1332L ERROR_NONE_MAPPED

1333L ERROR_TOO_MANY_LUIDS_REQUESTED

1334L ERROR_LUIDS_EXHAUSTED

1335L ERROR_INVALID_SUB_AUTHORITY

1336L ERROR_INVALID_ACL

1337L ERROR_INVALID_SID

1338L ERROR_INVALID_SECURITY_DESCR

1340L ERROR_BAD_INHERITANCE_ACL

1341L ERROR_SERVER_DISABLED

1342L ERROR_SERVER_NOT_DISABLED

1343L ERROR_INVALID_ID_AUTHORITY

1344L ERROR_ALLOTTED_SPACE_EXCEEDED

1345L ERROR_INVALID_GROUP_ATTRIBUTES

1346L ERROR_BAD_IMPERSONATION_LEVEL

1347L ERROR_CANT_OPEN_ANONYMOUS

1348L ERROR_BAD_VALIDATION_CLASS

1349L ERROR_BAD_TOKEN_TYPE

1350L ERROR_NO_SECURITY_ON_OBJECT

1351L ERROR_CANT_ACCESS_DOMAIN_INFO

1352L ERROR_INVALID_SERVER_STATE

1353L ERROR_INVALID_DOMAIN_STATE

1354L ERROR_INVALID_DOMAIN_ROLE

1355L ERROR_NO_SUCH_DOMAIN

1356L ERROR_DOMAIN_EXISTS

1357L ERROR_DOMAIN_LIMIT_EXCEEDED

1358L ERROR_INTERNAL_DB_CORRUPTION

1359L ERROR_INTERNAL_ERROR

1360L ERROR_GENERIC_NOT_MAPPED

1361L ERROR_BAD_DESCRIPTOR_FORMAT

1362L ERROR_NOT_LOGON_PROCESS

1363L ERROR_LOGON_SESSION_EXISTS

1364L ERROR_NO_SUCH_PACKAGE

1365L ERROR_BAD_LOGON_SESSION_STATE

1366L ERROR_LOGON_SESSION_COLLISION

1367L ERROR_INVALID_LOGON_TYPE

1368L ERROR_CANNOT_IMPERSONATE

1369L ERROR_RXACT_INVALID_STATE

1370L ERROR_RXACT_COMMIT_FAILURE

1371L ERROR_SPECIAL_ACCOUNT

1372L ERROR_SPECIAL_GROUP

1373L ERROR_SPECIAL_USER

1374L ERROR_MEMBERS_PRIMARY_GROUP

1375L ERROR_TOKEN_ALREADY_IN_USE

1376L ERROR_NO_SUCH_ALIAS

1377L ERROR_MEMBER_NOT_IN_ALIAS

1378L ERROR_MEMBER_IN_ALIAS

1379L ERROR_ALIAS_EXISTS

1380L ERROR_LOGON_NOT_GRANTED

1381L ERROR_TOO_MANY_SECRETS

1382L ERROR_SECRET_TOO_LONG

1383L ERROR_INTERNAL_DB_ERROR

1384L ERROR_TOO_MANY_CONTEXT_IDS

1385L ERROR_LOGON_TYPE_NOT_GRANTED

1386L ERROR_NT_CROSS_ENCRYPTION_REQUIRED

1387L ERROR_NO_SUCH_MEMBER

1388L ERROR_INVALID_MEMBER

1389L ERROR_TOO_MANY_SIDS

1390L ERROR_LM_CROSS_ENCRYPTION_REQUIRED

1391L ERROR_NO_INHERITANCE

1392L ERROR_FILE_CORRUPT

1393L ERROR_DISK_CORRUPT

1394L ERROR_NO_USER_SESSION_KEY

1400L ERROR_INVALID_WINDOW_HANDLE

1401L ERROR_INVALID_MENU_HANDLE

1402L ERROR_INVALID_CURSOR_HANDLE

1403L ERROR_INVALID_ACCEL_HANDLE

1404L ERROR_INVALID_HOOK_HANDLE

1405L ERROR_INVALID_DWP_HANDLE

1406L ERROR_TLW_WITH_WSCHILD

1407L ERROR_CANNOT_FIND_WND_CLASS

1408L ERROR_WINDOW_OF_OTHER_THREAD

1409L ERROR_HOTKEY_ALREADY_REGISTERED

1410L ERROR_CLASS_ALREADY_EXISTS

1411L ERROR_CLASS_DOES_NOT_EXIST

1412L ERROR_CLASS_HAS_WINDOWS

1413L ERROR_INVALID_INDEX

1414L ERROR_INVALID_ICON_HANDLE

1415L ERROR_PRIVATE_DIALOG_INDEX

1416L ERROR_LISTBOX_ID_NOT_FOUND

1417L ERROR_NO_WILDCARD_CHARACTERS

1418L ERROR_CLIPBOARD_NOT_OPEN

1419L ERROR_HOTKEY_NOT_REGISTERED

1420L ERROR_WINDOW_NOT_DIALOG

1421L ERROR_CONTROL_ID_NOT_FOUND

1422L ERROR_INVALID_COMBOBOX_MESSAGE

1423L ERROR_WINDOW_NOT_COMBOBOX

1424L ERROR_INVALID_EDIT_HEIGHT

1425L ERROR_DC_NOT_FOUND

1426L ERROR_INVALID_HOOK_FILTER

1427L ERROR_INVALID_FILTER_PROC

1428L ERROR_HOOK_NEEDS_HMOD

1429L ERROR_GLOBAL_ONLY_HOOK

1430L ERROR_JOURNAL_HOOK_SET

1431L ERROR_HOOK_NOT_INSTALLED

1432L ERROR_INVALID_LB_MESSAGE

1433L ERROR_SETCOUNT_ON_BAD_LB

1434L ERROR_LB_WITHOUT_TABSTOPS

1435L ERROR_DESTROY_OBJECT_OF_OTHER_THREAD

1436L ERROR_CHILD_WINDOW_MENU

1437L ERROR_NO_SYSTEM_MENU

1438L ERROR_INVALID_MSGBOX_STYLE

1439L ERROR_INVALID_SPI_VALUE

1440L ERROR_SCREEN_ALREADY_LOCKED

1441L ERROR_HWNDS_HAVE_DIFFERENT_PARENT

1442L ERROR_NOT_CHILD_WINDOW

1443L ERROR_INVALID_GW_COMMAND

1444L ERROR_INVALID_THREAD_ID

1445L ERROR_NON_MDICHILD_WINDOW

1446L ERROR_POPUP_ALREADY_ACTIVE

1447L ERROR_NO_SCROLLBARS

1448L ERROR_INVALID_SCROLLBAR_RANGE

1449L ERROR_INVALID_SHOWWIN_COMMAND

1500L ERROR_EVENTLOG_FILE_CORRUPT

1501L ERROR_EVENTLOG_CANT_START

1502L ERROR_LOG_FILE_FULL

1503L ERROR_EVENTLOG_FILE_CHANGED

1700L RPC_S_INVALID_STRING_BINDING

1701L RPC_S_WRONG_KIND_OF_BINDING

1702L RPC_S_INVALID_BINDING

1703L RPC_S_PROTSEQ_NOT_SUPPORTED

1704L RPC_S_INVALID_RPC_PROTSEQ

1705L RPC_S_INVALID_STRING_UUID

1706L RPC_S_INVALID_ENDPOINT_FORMAT

1707L RPC_S_INVALID_NET_ADDR

1708L RPC_S_NO_ENDPOINT_FOUND

1709L RPC_S_INVALID_TIMEOUT

1710L RPC_S_OBJECT_NOT_FOUND

1711L RPC_S_ALREADY_REGISTERED

1712L RPC_S_TYPE_ALREADY_REGISTERED

1713L RPC_S_ALREADY_LISTENING

1714L RPC_S_NO_PROTSEQS_REGISTERED

1715L RPC_S_NOT_LISTENING

1716L RPC_S_UNKNOWN_MGR_TYPE

1717L RPC_S_UNKNOWN_IF

1718L RPC_S_NO_BINDINGS

1719L RPC_S_NO_PROTSEQS

1720L RPC_S_CANT_CREATE_ENDPOINT

1721L RPC_S_OUT_OF_RESOURCES

1722L RPC_S_SERVER_UNAVAILABLE

1723L RPC_S_SERVER_TOO_BUSY

1724L RPC_S_INVALID_NETWORK_OPTIONS

1725L RPC_S_NO_CALL_ACTIVE

1726L RPC_S_CALL_FAILED

1727L RPC_S_CALL_FAILED_DNE

1728L RPC_S_PROTOCOL_ERROR

1729L RPC_S_CANNOT_BIND

1730L RPC_S_UNSUPPORTED_TRANS_SYN

1731L RPC_S_SERVER_OUT_OF_MEMORY

1732L RPC_S_UNSUPPORTED_TYPE

1733L RPC_S_INVALID_TAG

1734L RPC_S_INVALID_BOUND

1735L RPC_S_NO_ENTRY_NAME

1736L RPC_S_INVALID_NAME_SYNTAX

1737L RPC_S_UNSUPPORTED_NAME_SYNTAX

1738L RPC_S_SERVER_NOT_LISTENING

1739L RPC_S_UUID_NO_ADDRESS

1740L RPC_S_DUPLICATE_ENDPOINT

1741L RPC_S_UNKNOWN_AUTHN_TYPE

1742L RPC_S_MAX_CALLS_TOO_SMALL

1743L RPC_S_STRING_TOO_LONG

1744L RPC_S_PROTSEQ_NOT_FOUND

1745L RPC_S_PROCNUM_OUT_OF_RANGE

1746L RPC_S_BINDING_HAS_NO_AUTH

1747L RPC_S_UNKNOWN_AUTHN_SERVICE

1748L RPC_S_UNKNOWN_AUTHN_LEVEL

1749L RPC_S_INVALID_AUTH_IDENTITY

1750L RPC_S_UNKNOWN_AUTHZ_SERVICE

1751L EPT_S_INVALID_ENTRY

1752L EPT_S_CANT_PERFORM_OP

1753L EPT_S_NOT_REGISTERED

1754L RPC_S_NO_INTERFACES_EXPORTED

1755L RPC_S_INCOMPLETE_NAME

1756L RPC_S_INVALID_VERS_OPTION

1757L RPC_S_NO_MORE_MEMBERS

1758L RPC_S_NOTHING_TO_UNEXPORT

1759L RPC_S_INTERFACE_NOT_FOUND

1760L RPC_S_ENTRY_ALREADY_EXISTS

1761L RPC_S_ENTRY_NOT_FOUND

1762L RPC_S_NAME_SERVICE_UNAVAILABLE

1763L RPC_S_INVALID_NAF_IF

1764L RPC_S_CANNOT_SUPPORT

1765L RPC_S_NO_CONTEXT_AVAILABLE

1766L RPC_S_INTERNAL_ERROR

1767L RPC_S_ZERO_DIVIDE

1768L RPC_S_ADDRESS_ERROR

1769L RPC_S_FP_DIV_ZERO

1770L RPC_S_FP_UNDERFLOW

1771L RPC_S_FP_OVERFLOW

1772L RPC_X_NO_MORE_ENTRIES

1773L RPC_X_SS_CHAR_TRANS_OPEN_FAIL

1774L RPC_X_SS_CHAR_TRANS_SHORT_FILE

1775L RPC_X_SS_IN_NULL_CONTEXT

1776L RPC_X_SS_CONTEXT_MISMATCH

1777L RPC_X_SS_CONTEXT_DAMAGED

1778L RPC_X_SS_HANDLES_MISMATCH

1779L RPC_X_SS_CANNOT_GET_CALL_HANDLE

1780L RPC_X_NULL_REF_POINTER

1781L RPC_X_ENUM_VALUE_OUT_OF_RANGE

1782L RPC_X_BYTE_COUNT_TOO_SMALL

1783L RPC_X_BAD_STUB_DATA

1784L ERROR_INVALID_USER_BUFFER

1785L ERROR_UNRECOGNIZED_MEDIA

1786L ERROR_NO_TRUST_LSA_SECRET

1787L ERROR_NO_TRUST_SAM_ACCOUNT

1788L ERROR_TRUSTED_DOMAIN_FAILURE

1789L ERROR_TRUSTED_RELATIONSHIP_FAILURE

1790L ERROR_TRUST_FAILURE

1791L RPC_S_CALL_IN_PROGRESS

1792L ERROR_NETLOGON_NOT_STARTED

1793L ERROR_ACCOUNT_EXPIRED

1794L ERROR_REDIRECTOR_HAS_OPEN_HANDLES

1795L ERROR_PRINTER_DRIVER_ALREADY_INSTALLED

1796L ERROR_UNKNOWN_PORT

1797L ERROR_UNKNOWN_PRINTER_DRIVER

1798L ERROR_UNKNOWN_PRINTPROCESSOR

1799L ERROR_INVALID_SEPARATOR_FILE

1800L ERROR_INVALID_PRIORITY

1801L ERROR_INVALID_PRINTER_NAME

1802L ERROR_PRINTER_ALREADY_EXISTS

1803L ERROR_INVALID_PRINTER_COMMAND

1804L ERROR_INVALID_DATATYPE

1805L ERROR_INVALID_ENVIRONMENT

1806L RPC_S_NO_MORE_BINDINGS

1807L ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT

1808L ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT

1809L ERROR_NOLOGON_SERVER_TRUST_ACCOUNT

1810L ERROR_DOMAIN_TRUST_INCONSISTENT

1811L ERROR_SERVER_HAS_OPEN_HANDLES

1812L ERROR_RESOURCE_DATA_NOT_FOUND

1813L ERROR_RESOURCE_TYPE_NOT_FOUND

1814L ERROR_RESOURCE_NAME_NOT_FOUND

1815L ERROR_RESOURCE_LANG_NOT_FOUND

1816L ERROR_NOT_ENOUGH_QUOTA

1898L RPC_S_GROUP_MEMBER_NOT_FOUND

1899L EPT_S_CANT_CREATE

1900L RPC_S_INVALID_OBJECT

2138L ERROR_NO_NETWORK

2202L ERROR_BAD_USERNAME

2250L ERROR_NOT_CONNECTED

2401L ERROR_OPEN_FILES

2404L ERROR_DEVICE_IN_USE

6118L ERROR_NO_BROWSER_SERVERS_FOUND


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Virtual-Key Codes
  Appendix B    Virtual-Key Codes

Virtual-Key Codes

The following table shows the symbolic constant names, hexadecimal values, and keyboard equivalents for the virtual-key codes used by the Microsoft Windows operating system. The codes are listed in numeric order.

Symbolic constant name	Value (hexadecimal)	Mouse or keyboard equivalent
VK_LBUTTON	01	Left mouse button
VK_RBUTTON	02	Right mouse button
VK_CANCEL	03	Control-break processing
VK_MBUTTON	04	Middle mouse button (three-button mouse)
—	05−07	Undefined
VK_BACK	08	BACKSPACE key
VK_TAB	09	TAB key
—	0A−0B	Undefined
VK_CLEAR	0C	CLEAR key
VK_RETURN	0D	ENTER key
—	0E−0F	Undefined
VK_SHIFT	10	SHIFT key
VK_CONTROL	11	CTRL key
VK_MENU	12	ALT key
VK_PAUSE	13	PAUSE key
VK_CAPITAL	14	CAPS LOCK key
—	15−19	Reserved for Kanji systems
—	1A	Undefined
VK_ESCAPE	1B	ESC key
—	1C−1F	Reserved for Kanji systems
VK_SPACE	20	SPACEBAR
VK_PRIOR	21	PAGE UP key
VK_NEXT	22	PAGE DOWN key
VK_END	23	END key
VK_HOME	24	HOME key
VK_LEFT	25	LEFT ARROW key
VK_UP	26	UP ARROW key
VK_RIGHT	27	RIGHT ARROW key
VK_DOWN	28	DOWN ARROW key
VK_SELECT	29	SELECT key
—	2A	Original equipment manufacturer (OEM) specific
VK_EXECUTE	2B	EXECUTE key
VK_SNAPSHOT	2C	PRINT SCREEN key for Windows 3.0 and later
VK_INSERT	2D	INS key
VK_DELETE	2E	DEL key
VK_HELP	2F	HELP key
VK_0	30	0 key
VK_1	31	1 key
VK_2	32	2 key
VK_3	33	3 key
VK_4	34	4 key
VK_5	35	5 key
VK_6	36	6 key
VK_7	37	7 key
VK_8	38	8 key
VK_9	39	9 key
—	3A−40	Undefined
VK_A	41	A key
VK_B	42	B key
VK_C	43	C key
VK_D	44	D key
VK_E	45	E key
VK_F	46	F key
VK_G	47	G key
VK_H	48	H key
VK_I	49	I key
VK_J	4A	J key
VK_K	4B	K key
VK_L	4C	L key
VK_M	4D	M key
VK_N	4E	N key
VK_O	4F	O key
VK_P	50	P key
VK_Q	51	Q key
VK_R	52	R key
VK_S	53	S key
VK_T	54	T key
VK_U	55	U key
VK_V	56	V key
VK_W	57	W key
VK_X	58	X key
VK_Y	59	Y key
VK_Z	5A	Z key
—	5B−5F	Undefined
VK_NUMPAD0	60	Numeric keypad 0 key
VK_NUMPAD1	61	Numeric keypad 1 key
VK_NUMPAD2	62	Numeric keypad 2 key
VK_NUMPAD3	63	Numeric keypad 3 key
VK_NUMPAD4	64	Numeric keypad 4 key
VK_NUMPAD5	65	Numeric keypad 5 key
VK_NUMPAD6	66	Numeric keypad 6 key
VK_NUMPAD7	67	Numeric keypad 7 key
VK_NUMPAD8	68	Numeric keypad 8 key
VK_NUMPAD9	69	Numeric keypad 9 key
VK_MULTIPLY	6A	Multiply key
VK_ADD	6B	Add key
VK_SEPARATOR	6C	Separator key
VK_SUBTRACT	6D	Subtract key
VK_DECIMAL	6E	Decimal key
VK_DIVIDE	6F	Divide key
VK_F1	70	F1 key
VK_F2	71	F2 key
VK_F3	72	F3 key
VK_F4	73	F4 key
VK_F5	74	F5 key
VK_F6	75	F6 key
VK_F7	76	F7 key
VK_F8	77	F8 key
VK_F9	78	F9 key
VK_F10	79	F10 key
VK_F11	7A	F11 key
VK_F12	7B	F12 key
VK_F13	7C	F13 key
VK_F14	7D	F14 key
VK_F15	7E	F15 key
VK_F16	7F	F16 key
VK_F17	80H	F17 key
VK_F18	81H	F18 key
VK_F19	82H	F19 key
VK_F20	83H	F20 key
VK_F21	84H	F21 key
VK_F22	85H	F22 key
VK_F23	86H	F23 key
VK_F24	87H	F24 key
—	88−8F	Unassigned
VK_NUMLOCK	90	NUM LOCK key
VK_SCROLL	91	SCROLL LOCK key
—	92−B9	Unassigned
—	BA−C0	OEM specific
—	C1−DA	Unassigned
—	DB−E4	OEM specific
—	E5	Unassigned
—	E6	OEM specific
—	E7−E8	Unassigned
—	E9−F5	OEM specific
—	F6−FE	Unassigned


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Locale Identifiers
  Appendix C    Locale Identifiers

This appendix contains detailed information about national language support in Microsoft Windows. The information presented here pertains to locale identifiers, LCTYPE constants, country codes, and language identifiers.


  Locale Identifiers (LCIDs)

A locale identifier (LCID) is a DWORD value containing the language identifier in the lower word and a reserved value in the upper word. The identifier supplied in an LCID is a standard international numeric abbreviation. This LCID has the components necessary to uniquely identify one of the installed system-defined locales.

Applications can use the MAKELCID macro to create LCID values. For more information about the MAKELCID macro, see the Microsoft Win32 Programmer's Reference, Volume 5.

There are two predefined LCID values: LOCALE_SYSTEM_DEFAULT is the system default locale, and LOCALE_USER_DEFAULT is the current user's locale.


  LCTYPE Constants

An LCTYPE constant is a constant that specifies a particular piece of locale information.

The values in the following list correspond to the names of these values in the configuration registry, under both the user's preferences (as values in the registry key HKEY_CURRENT_USER\Control Panel\International) and the system's installed languages (as files pointed to by registry keys, one key per language installed, under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\NLS). All values are null-terminated Unicode strings. If no maximum length is indicated, the strings may vary in length.

Constant	Description
LOCALE_ILANGUAGE	Language identifier indicating the language. The maximum number of characters allowed for this string is 5.
LOCALE_SLANGUAGE	Full localized name of the language.
LOCALE_SENGLANGUAGE	Full English name of the language from the International Organization for Standardization (ISO) Standard 639. This is always restricted to characters mappable into the ASCII 127-character subset.
LOCALE_SABBREVLANGNAME	Abbreviated name of the language, created by taking the 2-letter language abbreviation from the ISO Standard 639 and adding a third letter, as appropriate, to indicate the sublanguage.
LOCALE_SNATIVELANGNAME	Native name of the language.
LOCALE_ICOUNTRY	Country code, based on international phone codes, also referred to as IBM country codes. The maximum number of characters allowed for this string is 6.
LOCALE_SCOUNTRY	Full localized name of the country.
LOCALE_SENGCOUNTRY	Full English name of the country. This is always restricted to characters mappable into the ASCII 127-character subset.
LOCALE_SABBREVCTRYNAME	Abbreviated name of the country from the ISO Standard 3166.
LOCALE_SNATIVECTRYNAME	Native name of the country.
LOCALE_IDEFAULTLANGUAGE	Language identifier for the principal language spoken in this locale. This is provided so that partially specified locales can be completed with default values. The maximum number of characters allowed for this string is 5.
LOCALE_IDEFAULTCOUNTRY	Country code for the principal country in this locale. This is provided so that partially specified locales can be completed with default values. The maximum number of characters allowed for this string is 6.
LOCALE_IDEFAULTCODEPAGE	Original equipment manufacturer (OEM) code page associated with the country. The maximum number of characters allowed for this string is 6.
LOCALE_SLIST	Character(s) used to separate list items. For example, a comma is used in many locales.
LOCALE_IMEASURE	System of measurement. This value is 0 if the metric system (Systéme International d'Unités, or S.I.) is used and 1 if the U.S. system is used. The maximum number of characters allowed for this string is 2.
LOCALE_SDECIMAL	Character(s) used as the decimal separator.
LOCALE_STHOUSAND	Character(s) used to separate groups of digits to the left of the decimal.
LOCALE_SGROUPING	Sizes for each group of digits to the left of the decimal. An explicit size is needed for each group; sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. To group thousands, specify 3;0, for example.
LOCALE_IDIGITS	Number of fractional digits. The maximum number of characters allowed for this string is 3.
LOCALE_ILZERO	Specifier for leading zeros in decimal fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	No leading zeros
1	Leading zeros
LOCALE_SNATIVEDIGITS	Native equivalents to ASCII 0 through 9.
LOCALE_SCURRENCY	String used as the local monetary symbol.
LOCALE_SINTLSYMBOL	Three characters of the international monetary symbol specified in ISO 4217, "Codes for the Representation of Currencies and Funds," followed by the character separating this string from the amount.
LOCALE_SMONDECIMALSEP	Character(s) used as the monetary decimal separator.
LOCALE_SMONTHOUSANDSEP	Character(s) used as the monetary separator between groups of digits to the left of the decimal.
LOCALE_SMONGROUPING	Sizes for each group of monetary digits to the left of the decimal. An explicit size is needed for each group; sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. To group thousands, specify 3;0, for example.
LOCALE_ICURRDIGITS	Number of fractional digits for the local monetary format. The maximum number of characters allowed for this string is 3.
LOCALE_IINTLCURRDIGITS	Number of fractional digits for the international monetary format. The maximum number of characters allowed for this string is 3.
LOCALE_ICURRENCY	Positive currency mode. The maximum number of characters allowed for this string is 2. The mode can be one of the following values:
Value	Meaning
0	Prefix, no separation
1	Suffix, no separation
2	Prefix, 1-char. separation
3	Suffix, 1-char. separation
LOCALE_INEGCURR	Negative currency mode. The maximum number of characters allowed for this string is 3. The mode can be one of the following values:
Value	Example
0	($1.1)
1	−$1.1
2	$−1.1
3	$1.1−
4	(1.1$)
5	−1.1$
6	1.1−$
7	1.1$−
8	−1.1 $ (space before $)
9	−$ 1.1 (space after $)
10	1.1 $− (space before $)
11	$ 1.1− (space after $)
LOCALE_SDATE	Character(s) for the date separator.
LOCALE_STIME	Character(s) for the time separator.
LOCALE_STIMEFORMAT	Time formatting strings for this locale.
LOCALE_SSHORTDATE	Short date formatting string for this locale.
LOCALE_SLONGDATE	Long date formatting string for this locale.
LOCALE_IDATE	Short date format-ordering specifier. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	Month-Day-Year
1	Day-Month-Year
2	Year-Month-Day
LOCALE_ILDATE	Long date format-ordering specifier. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	Month-Day-Year
1	Day-Month-Year
2	Year-Month-Day
LOCALE_ITIME	Time format specifier. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	AM / PM 12-hour format
1	24-hour format
LOCALE_ICENTURY	Specifier for full 4-digit century. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	Abbreviated 2-digit century
1	Full 4-digit century
LOCALE_ITLZERO	Specifier for leading zeros in time fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	No leading zeros for hours
1	Leading zeros for hours
LOCALE_IDAYLZERO	Specifier for leading zeros in day fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	No leading zeros for days
1	Leading zeros for days
LOCALE_IMONLZERO	Specifier for leading zeros in month fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:
Value	Meaning
0	No leading zeros for months
1	Leading zeros for months
LOCALE_S1159	String for the AM designator.
LOCALE_S2359	String for the PM designator.
LOCALE_SDAYNAME1	Native long name for Monday.
LOCALE_SDAYNAME2	Native long name for Tuesday.
LOCALE_SDAYNAME3	Native long name for Wednesday.
LOCALE_SDAYNAME4	Native long name for Thursday.
LOCALE_SDAYNAME5	Native long name for Friday.
LOCALE_SDAYNAME6	Native long name for Saturday.
LOCALE_SDAYNAME7	Native long name for Sunday.
LOCALE_SABBREVDAYNAME1	Native abbreviated name for Monday.
LOCALE_SABBREVDAYNAME2	Native abbreviated name for Tuesday.
LOCALE_SABBREVDAYNAME3	Native abbreviated name for Wednesday.
LOCALE_SABBREVDAYNAME4	Native abbreviated name for Thursday.
LOCALE_SABBREVDAYNAME5	Native abbreviated name for Friday.
LOCALE_SABBREVDAYNAME6	Native abbreviated name for Saturday.
LOCALE_SABBREVDAYNAME7	Native abbreviated name for Sunday.
LOCALE_SMONTHNAME1	Native long name for January.
LOCALE_SMONTHNAME2	Native long name for February.
LOCALE_SMONTHNAME3	Native long name for March.
LOCALE_SMONTHNAME4	Native long name for April.
LOCALE_SMONTHNAME5	Native long name for May.
LOCALE_SMONTHNAME6	Native long name for June.
LOCALE_SMONTHNAME7	Native long name for July.
LOCALE_SMONTHNAME8	Native long name for August.
LOCALE_SMONTHNAME9	Native long name for September.
LOCALE_SMONTHNAME10	Native long name for October.
LOCALE_SMONTHNAME11	Native long name for November.
LOCALE_SMONTHNAME12	Native long name for December.
LOCALE_SABBREVMONTHNAME1	Native abbreviated name for January.
LOCALE_SABBREVMONTHNAME2	Native abbreviated name for February.
LOCALE_SABBREVMONTHNAME3	Native abbreviated name for March.
LOCALE_SABBREVMONTHNAME4	Native abbreviated name for April.
LOCALE_SABBREVMONTHNAME5	Native abbreviated name for May.
LOCALE_SABBREVMONTHNAME6	Native abbreviated name for June.
LOCALE_SABBREVMONTHNAME7	Native abbreviated name for July.
LOCALE_SABBREVMONTHNAME8	Native abbreviated name for August.
LOCALE_SABBREVMONTHNAME9	Native abbreviated name for September.
LOCALE_SABBREVMONTHNAME10	Native abbreviated name for October.
LOCALE_SABBREVMONTHNAME11	Native abbreviated name for November.
LOCALE_SABBREVMONTHNAME12	Native abbreviated name for December.
LOCALE_SPOSITIVESIGN	String value for the positive sign.
LOCALE_SNEGATIVESIGN	String value for the negative sign.
LOCALE_IPOSSIGNPOSN	Formatting index for positive values. The maximum number of characters allowed for this string is 2. The index can be one of the following values:
Value	Meaning
0	Parentheses surround the amount and the monetary symbol.
1	The sign string precedes the amount and the monetary symbol.
2	The sign string succeeds the amount and the monetary symbol.
3	The sign string immediately precedes the monetary symbol.
4	The sign string immediately succeeds the monetary symbol.
LOCALE_INEGSIGNPOSN	Formatting index for negative values. This index uses the same values as LOCALE_IPOSSIGNPOSN. The maximum number of characters allowed for this string is 2.
LOCALE_IPOSSYMPRECEDES	Position of monetary symbol in a positive monetary value. This value is 1 if the monetary symbol precedes the positive amount, 0 if it follows it. The maximum number of characters allowed for this string is 2.
LOCALE_IPOSSEPBYSPACE	Separation of monetary symbol in a positive monetary value. This value is 1 if the monetary symbol is separated by a space from a positive amount, 0 if it is not. The maximum number of characters allowed for this string is 2.
LOCALE_INEGSYMPRECEDES	Position of monetary symbol in a negative monetary value. This value is 1 if the monetary symbol precedes the negative amount, 0 if it follows it. The maximum number of characters allowed for this string is 2.
LOCALE_INEGSEPBYSPACE	Separation of monetary symbol in a negative monetary value. This value is 1 if the monetary symbol is separated by a space from the negative amount, 0 if it is not. The maximum number of characters allowed for this string is 2.
LOCALE_NOUSEROVERRIDE	This constant may be OR'ed with any other LCTYPE constant in a call to the GetLocaleInfoW function. This always causes the function to bypass any user overrides, and return the system default value for the other LCTYPE specified in the function call, based on the given LCID.


  Language Identifiers and Locales

Applications can use the MAKELANGID macro to create a language identifier. For information about the MAKELANGID macro, see the Microsoft Win32 Programmer's Reference, Volume 5.

The first release of Windows NT supports 35 sublanguages/locales.

The following 28 sublanguages/locales use the Latin 1 script:

Latin 1 Script

Identifier	Language	Sublanguage/Locale	Language Code
0x0406	Danish	Danish	DAN
0x0413	Dutch	Dutch (Standard)	NLD
0x0813	Dutch	Belgian (Flemish)	NLB
0x0409	English	American	ENU
0x0809	English	British	ENG
0x0c09	English	Australian	ENA
0x1009	English	Canadian	ENC
0x1409	English	New Zealand	ENZ
0x1809	English	Ireland	ENI
0x040b	Finnish	Finnish	FIN
0x040c	French	French (Standard)	FRA
0x080c	French	Belgian	FRB
0x0c0c	French	Canadian	FRC
0x100c	French	Swiss	FRS
0x0407	German	German (Standard)	DEU
0x0807	German	Swiss	DES
0x0c07	German	Austrian	DEA
0x040f	Icelandic	Icelandic	ISL
0x0410	Italian	Italian (Standard)	ITA
0x0810	Italian	Swiss	ITS
0x0414	Norwegian	Norwegian (Bokmal)	NOR
0x0814	Norwegian	Norwegian (Nynorsk)	NON
0x0416	Portuguese	Portuguese (Brazilian)	PTB
0x0816	Portuguese	Portuguese (Standard)	PTG
0x041D	Swedish	Swedish	SVE
0x040a	Spanish	Spanish (Standard/Traditional)	ESP
0x080a	Spanish	Mexican	ESM
0x0c0a	Spanish	Spanish (Modern)	ESN
The following 5 sublanguages/locales use the Latin 2 script:

Latin 2 Script

Identifier	Sublanguage/Locale	Language Code
0x041f	Turkish	TRK
0x0415	Polish	PLK
0x0405	Czech	CSY
0x041b	Slovak	SKY
0x040e	Hungarian	HUN
The following sublanguage/locale uses the Cyrillic script:

Cyrillic Script

Identifier	Sublanguage/Locale	Language Code
0x0419	Russian	RUS
The following sublanguage/locale uses an other script:

Other Script

Identifier	Sublanguage/Locale	Language Code
0x0408	Greek	ELL
The following special identifiers are also defined:

Special Identifiers

Identifier	Sublanguage/Locale
0x0000	Language-Neutral
0x0400	Process Default Language


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Manufacturer and Product Identifiers
  Appendix D    Manufacturer and Product Identifiers

Introduction

This appendix provides lists of the manufacturer and product identifiers currently used with the Microsoft Windows operating system with Multimedia Extensions. This list will grow as more manufacturers create multimedia products for Windows.

To get a current list of manufacturer and product identifiers for the Multimedia Extensions, and to register new ones, request a Multimedia Developer Registration Kit from the following group:

Microsoft Corporation
Multimedia Systems Group
Product Marketing
One Microsoft Way
Redmond, WA 98052−6399


  Manufacturer Identifiers

Following are the current manufacturer identifiers for the Multimedia Extensions.

Constant	Value	Description
MM_MICROSOFT	1	Drivers developed by Microsoft Corporation


  Product Identifiers

Following are the current product identifiers for the Multimedia Extensions.

Constant	Value	Description
MM_MIDI_MAPPER	1	Microsoft MIDI Mapper
MM_SNDBLAST_MIDIOUT	3	Sound Blaster (™)  MIDI output port
MM_SNDBLAST_MIDIIN	4	Sound Blaster MIDI input port
MM_SNDBLAST_SYNTH	5	Sound Blaster internal synthesizer
MM_SNDBLAST_WAVEOUT	6	Sound Blaster waveform output port
MM_SNDBLAST_WAVEIN	7	Sound Blaster waveform input port
MM_ADLIB	9	Ad Lib® (or compatible) synthesizer
MM_MPU401_MIDIOUT	10	Roland® MPU-401 MIDI output port
MM_MPU401_MIDIIN	11	Roland MPU-401 MIDI input port
MM_PC_JOYSTICK	12	IBM Game Control Adapter


MCI Command String Syntax Summary
  Appendix E    MCI Command String Syntax Summary

Introduction

This appendix provides a summary of the syntax of the MCI command strings. The following command tables are included in this chapter:

•	System command set

•	Required command set

•	Basic command set

•	Animation command set

•	CD audio command set

•	MIDI sequencer command set

•	Videodisc command set

•	Video overlay command set

•	Waveform audio command set


  About the Command Tables

Each command table has a Command column and an Arguments column. The Command column contains the MCI commands available for a device type. The Arguments column contains the options available for each MCI command. For example, the following table contains the MCI commands all devices support.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can save | compound device | device type | has audio | has video | uses files}
close device_name
info device_name	[product]
open device_name	[alias device_alias]
	[shareable]
	[type device_type]
status device_name	[mode | ready]
Each command also has a notify and wait flag that does not appear in the tables. These flags can be added to any command.

The following conventions are used in the previous example and for the other MCI command tables.

Type style	Used for
Bold	A specific term intended to be used literally. When used in the command column, it represents the MCI string command. When used in the arguments column, it represents a flag. For example, the capability command and the can play flag must be typed as shown.
Italics	Placeholders for information you must provide. The MCI command or flag associated with the information must precede it. For example, to use the alias words for the device_name with the capability command, type "capability words can play."
|	Divider for mutually exclusive arguments. When multiple arguments are separated by this symbol, only one of them can be used for each command. For example, the items in the list can eject, can play, can record, can save, compound device, device type, has audio, has video, uses files are mutually exclusive and you must select only one to use with the capability command. (Do not type the | with the argument.)
{}	Required argument. You must include an argument enclosed by braces. For example, you must use one of the arguments can eject, can play, can record, can save, compound device, device type, has audio, has video, uses files with the capability command. (Do not type the braces with the argument.)
[ ]	Optional argument. For example, the alias, type and shareable flags are optional for the open command. You can use any combination of these flags. You can also use optional arguments with a required argument. (Do not type the brackets with the argument.)


  System Command Set

The following table summarizes the MCI system commands. These commands are interpreted directly by MCI. System commands also support notify and wait as optional flags. You can add either or both of these flags to any system command.

Command	Arguments
break device_name	{off | on virtual key code}
sound sound_name
sysinfo device_name	{installname
	| name index | name index open | quantity | quantity open}


  Required Command Set

The following table lists the commands recognized by all devices. Extended commands can add other options to these commands. Required commands also support notify and wait as optional flags. You can add either or both of these flags to any required command.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can save | compound device | device type | has audio | has video | uses files}
close device_name
info device_name	[product]
open device_name	[alias device_alias]
	[shareable]
	[type device_type]
status device_name	[mode | ready]


  Basic Command Set

In addition to supporting the commands described previously, each device supports a set of commands specific to its device type. Although these commands are optional for a device, if a command is used it must support the options listed in this table as a minimum set of capabilities. Basic commands also support notify and wait as optional flags. You can add either or both of these flags to any basic command.

Command	Arguments
load device_name	{file_name}
pause device_name
play device_name	[from position]
	[to position]
	[insert | overwrite]
resume device_name
save device_name	[file_name]
seek device_name	{to position | to start | to end}
set device_name	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[door closed | door open]
	[time format milliseconds | time format ms]
status device_name	{current track
	| length | length track track_number | mode | number of tracks | position | position track track_number | ready | start position | time format}
stop device name


  Animation Command Set

Animation devices support the following set of commands. These devices also supporty notify and wait as optional flags. You can add either or both of these flags to any animation command.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can reverse | can save | can stretch | compound device | device type | fast play rate | has audio | has video | normal play rate | slow play rate | uses files | uses palettes | windows}
close device_name
info device_name	[file | product | window text]
open device_name	[alias device_alias]
	[nostatic]
	[parent hwnd]
	[shareable]
	[style child
	| style overlapped | style popup]
	[type device_type]
pause device_name
play device_name	[fast | slow | speed fps]
	[from position]
	[to position | reverse]
	[scan]
put device_name	{destination
	| destination at destination_rectangle | source | source at source_rectangle}
realize device_name	{background | normal}
resume device_name
seek device_name	[to position | to start | to end]
set device_name	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[time format milliseconds
	| time format ms | time format frames]
status device_name	{current track
	| forward | length | length track track_number | media present | mode | number of tracks | palette handle | position | position track track_number | ready | speed | start position | stretch | time format | window handle}
step device_name	[by frames]
stop device_name
update device_name	[at update_rect]
	[hdc hdc]
where device_name	{destination | source}
window device_name	[handle window_handle | handle default]
	[stretch | fixed]
	[state hide
	| state iconic | state maximized | state minimize | state minimized | state no action | state no active | state normal | state show]
	[text caption_text]


  Audio CD Command Set

Audio CD devices support the following core set of commands. Audio CD devices also support notify and wait as option flags. You can add either or both of these flags to any audio CD command.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can save | compound device | device type | has audio | has video | uses files}
close device_name	[product]
info device_name
open device_name	[alias device_name]
	[shareable]
pause device_name
play device_name	[from position]
	[to position]
resume device_name
seek device_name	[to position to start | to end]
set device_name	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[door closed | door open]
	[time format milliseconds
	| time format ms | time format msf | time format tmsf]
status device_name	{current track
	| length | length track track_number | media present | mode | number of tracks | position | position track track_number | ready | start position | time format}
stop device_name


  MIDI Sequencer Command Set

The MIDI sequencer supports the following set of commands. MIDI sequencers also support notify and wait as optional flags. You can add either or both of these flags to any MIDI sequencer command.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can save | compound device | device type | has audio | has video | uses files}
close device_name
info device_name	[file | product]
open device_name	[alias device_alias]
	[shareable]
	[type device_type]
pause device_name
play device_name	[from position]
	[to position]
record device_name	[from position]
	[to position]
	[insert | overwrite]
save device_name	[file_name]
seek device_name	[to position | to start | to end]
set device_name	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[master MIDI
	| master none | master SMPTE]
	[offset hmsf_value]
	[port port_number
	| port mapper | port none]
	[slave file
	| slave MIDI | slave none | slave SMPTE]
	[tempo tempo_value]
	[time format milliseconds
	| time format ms | time format smpte 24 | time format smpte 25 | time format smpte 30 | time format smpte 30 drop | time format song pointer]
status device_name	{current track
	| division type | length | length track track_number | master | media present | mode | number of tracks | offset | port | position | position track track_number | ready | slave | start position | tempo | time format}
stop device_name


  Videodisc Command Set

Videodisc players support the following set of commands. Videodisc devices also support notify and wait as optional flags. You can add either or both of these flags to any videodisc command.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can reverse | can save | compound device | device type | fast play rate | has audio | has video | normal play rate | slow play rate | uses files}
	[CAV | CLV]
close device_name
escape device_name	{command_string}
info device_name	[product]
open device_name	[alias device_alias]
	[shareable]
pause device_name
play device_name	[fast | slow | speed fps]
	[from position]
	[scan]
	[to position | reverse]
resume device_name
seek device_name	[reverse | to position | to start | to end]
set device_name	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[door closed | door open]
	[time format milliseconds
	| time format ms | time format frames | time format hms | time format track]
spin device_name	[down | up]
status device_name	{current track
	| disc size | forward | length | length track track_number | media present | media type | mode | number of tracks | position | position track track_number | ready | side | speed | start position | time format}
step device_name	[by] position
	[reverse]
stop device_name


  Video Overlay Command Set

Video overlay devices support the following set of commands. Video overlay devices also support notify and wait as optional flags. You can add either or both of these flags to any video overlay command.

Command	Arguments
capability device_name	{can eject
	| can freeze | can play | can record | can save | can stretch | compound device | device type | has audio | has video | uses files | windows}
close device_name
freeze device_name	[at rectangle]
info device_name	[product | file | window text]
load device_name	[file_name]
	at  buffer_rectangle
open device_name	[alias device_alias]
	[parent hwnd]
	[shareable]
	[style style_type
	| style child | style overlapped | style popup]
	[type device_type]
put device_name	{destination | at destination_rectangle
	| frame | frame at frame_rectangle | source | source at source_rectangle | video | video at video_rectangle}
save device_name	[file_name]
	at buffer_rectangle
set device_name	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[time format milliseconds
	| time format ms]
status device_name	{current track
	| length | length track track_number | media present | mode | number of tracks | position | position track track_number | ready | start position | stretch | time format | window handle}
unfreeze device_name	[at freeze_rectangle]
where device_name	{destination | frame | source | video}
window device_name	[handle window_handle | handle default]
	| [stretch | fixed]
	[state hide
	| state iconic | state maximized | state minimized | state no action | state no activate | state normal | state show]
	[text caption_text]


  Waveform Audio Command Set

Wave audio devices support the following set of commands. Wave audio devices also support notify and wait as optional flags. You can add either or both of these flags to any wave audio command.

Command	Arguments
capability device_name	{can eject
	| can play | can record | can save | compound device | device type | has audio | has video | inputs | outputs | uses files}
close device_name
cue device_name	[input | output]
delete device_name	[from position]
	[to position]
info device_name	[file
	| input | output | product]
open device_name	[alias device_alias]
	[buffer buffer_size]
	[shareable]
	[type device_type]
pause device_name
play device_name	[from position]
	[to position]
record device_name	[from position]
	[to position]
	[insert | overwrite]
resume device_name
save device_name	[file_name]
seek device_name	[to position | to start | to end]
set device_name	[alignment block_alignment]
	[any input]
	[any output]
	[audio all off
	| audio all on | audio left off | audio left on | audio right off | audio right on | video off | video on]
	[bitspersample bit_count]
	[bytespersec byte_rate]
	[channels channel_count]
	[format tag tag | format tag pcm]
	[input device_number]
	[output device_number]
	[samplespersec sample_rate]
	[timeformat milliseconds
	| time format ms | time format bytes | time format samples]
status device_name	{alignment
	| bitspersample | bytespersec | channels | current track | format tag | input | length | length track track_number | level | media present | mode | number of tracks | output | position | position track track_number | ready | samplespersec | start position | time format}
stop device_name


Raster Operation Codes
  Appendix F    Raster Operation Codes

This appendix lists and describes the binary and ternary raster operations used by graphics device interface (GDI). A binary raster operation involves two operands: a pen and a destination bitmap. A ternary raster operation involves three operands: a source bitmap, a brush, and a destination bitmap. Both binary and ternary raster operations use Boolean operators.


  Binary Raster Operations

This section lists the binary raster-operation codes used by the GetROP2 and SetROP2 functions. Raster-operation codes define how GDI combines the bits from the selected pen with the bits in the destination bitmap.

Each raster-operation code represents a Boolean operation in which the values of the pixels in the selected pen and the destination bitmap are combined. Following are the two operands used in these operations:

Operand	Meaning
P	Selected pen
D	Destination bitmap
The Boolean operators used in these operations follow:

Operator	Meaning
a	Bitwise AND
n	Bitwise NOT (inverse)
o	Bitwise OR
x	Bitwise exclusive OR (XOR)
All Boolean operations are presented in reverse Polish notation. For example, the following operation replaces the values of the pixels in the destination bitmap with a combination of the pixel values of the pen and the selected brush:

DPo

Each raster-operation code is a 32-bit integer whose high-order word is a Boolean operation index and whose low-order word is the operation code. The 16-bit operation index is a zero-extended 8-bit value that represents all possible outcomes resulting from the Boolean operation on two parameters (in this case, the pen and destination values). For example, the operation indexes for the DPo and DPan operations are shown in the following list:

P	D	DPo	DPan
0	0	0	1
0	1	1	1
1	0	1	1
1	1	1	0
The following list outlines the drawing modes and the Boolean operations that they represent:

Raster operation	Boolean operation
R2_BLACK	0
R2_COPYPEN	P
R2_MASKNOTPEN	DPna
R2_MASKPEN	DPa
R2_MASKPENNOT	PDna
R2_MERGENOTPEN	DPno
R2_MERGEPEN	DPo
R2_MERGEPENNOT	PDno
R2_NOP	D
R2_NOT	Dn
R2_NOTCOPYPEN	Pn
R2_NOTMASKPEN	DPan
R2_NOTMERGEPEN	DPon
R2_NOTXORPEN	DPxn
R2_WHITE	1
R2_XORPEN	DPx
For a monochrome device, GDI maps the value zero to black and the value 1 to white. If an application attempts to draw with a black pen on a white destination by using the available binary raster operations, the following results occur:

Raster operation	Result
R2_BLACK	Visible black line
R2_COPYPEN	Visible black line
R2_MASKNOTPEN	No visible line
R2_MASKPEN	Visible black line
R2_MASKPENNOT	Visible black line
R2_MERGENOTPEN	No visible line
R2_MERGEPEN	Visible black line
R2_MERGEPENNOT	Visible black line
R2_NOP	No visible line
R2_NOT	Visible black line
R2_NOTCOPYPEN	No visible line
R2_NOTMASKPEN	No visible line
R2_NOTMERGEPEN	Visible black line
R2_NOTXORPEN	Visible black line
R2_WHITE	No visible line
R2_XORPEN	No visible line
For a color device, GDI uses RGB values to represent the colors of the pen and the destination. An RGB color value is a long integer that contains a red, a green, and a blue color field, each specifying the intensity of the given color. Intensities range from 0 through 255. The values are packed in the three low-order bytes of the long integer. The color of a pen is always a solid color, but the color of the destination may be a mixture of any two or three colors. If an application attempts to draw with a white pen on a blue destination by using the available binary raster operations, the following results occur:

Raster operation	Result
R2_BLACK	Visible black line
R2_COPYPEN	Visible white line
R2_MASKNOTPEN	Visible black line
R2_MASKPEN	Invisible blue line
R2_MASKPENNOT	Visible red/green line
R2_MERGENOTPEN	Invisible blue line
R2_MERGEPEN	Visible white line
R2_MERGEPENNOT	Visible white line
R2_NOP	Invisible blue line
R2_NOT	Visible red/green line
R2_NOTCOPYPEN	Visible black line
R2_NOTMASKPEN	Visible red/green line
R2_NOTMERGEPEN	Visible black line
R2_NOTXORPEN	Invisible blue line
R2_WHITE	Visible white line
R2_XORPEN	Visible red/green line


  Ternary Raster Operations

This section lists the ternary raster-operation codes used by the BitBlt, PatBlt, and StretchBlt functions. Ternary raster-operation codes define how GDI combines the bits in a source bitmap with the bits in the destination bitmap.

Each raster-operation code represents a Boolean operation in which the values of the pixels in the source, the selected brush, and the destination are combined. Following are the three operands used in these operations:

Operand	Meaning
D	Destination bitmap
P	Selected brush (also called pattern)
S	Source bitmap
Boolean operators used in these operations follow:

Operator	Meaning
a	Bitwise AND
n	Bitwise NOT (inverse)
o	Bitwise OR
x	Bitwise exclusive OR (XOR)
All Boolean operations are presented in reverse Polish notation. For example, the following operation replaces the values of the pixels in the destination bitmap with a combination of the pixel values of the source and brush:

PSo

The following operation combines the values of the pixels in the source and brush with the pixel values of the destination bitmap (there are alternative spellings of the same function, so although a particular spelling may not be in the list, an equivalent form would be):

DPSoo

Each raster-operation code is a 32-bit integer whose high-order word is a Boolean operation index and whose low-order word is the operation code. The 16-bit operation index is a zero-extended, 8-bit value that represents the result of the Boolean operation on predefined brush, source, and destination values. For example, the operation indexes for the PSo and DPSoo operations are shown in the following list:

P	S	D	PSo	DPSoo
0	0	0	0	0
0	0	1	0	1
0	1	0	1	1
0	1	1	1	1
1	0	0	1	1
1	0	1	1	1
1	1	0	1	1
1	1	1	1	1
Operation index:			00FCh	00FEh
In this case, PSo has the operation index 00FC (read from the bottom up); DPSoo has the operation index 00FE. These values define the location of the corresponding raster-operation codes, as shown in Table A.1, "Raster-Operation Codes." The PSo operation is in line 252 (00FCh) of the table; DPSoo is in line 254 (00FEh).

The most commonly used raster operations have been given special names in the Windows include file, WINDOWS.H. You should use these names whenever possible in your applications.

When the source and destination bitmaps are monochrome, a bit value of zero represents a black pixel and a bit value of 1 represents a white pixel. When the source and the destination bitmaps are color, those colors are represented with RGB values. For more information about RGB values, see the RGB structure in Programmer's Reference, Volume 1, Chapter 3, "Structures."

Raster-Operation Codes

Boolean function (hexadecimal)	Raster operation (hexadecimal)	Boolean function in reverse Polish	Common name
00	00000042	0	BLACKNESS
01	00010289	DPSoon	−
02	00020C89	DPSona	−
03	000300AA	PSon	−
04	00040C88	SDPona	−
05	000500A9	DPon	−
06	00060865	PDSxnon	−
07	000702C5	PDSaon	−
08	00080F08	SDPnaa	−
09	00090245	PDSxon	−
0A	000A0329	DPna	−
0B	000B0B2A	PSDnaon	−
0C	000C0324	SPna	−
0D	000D0B25	PDSnaon	−
0E	000E08A5	PDSonon	−
0F	000F0001	Pn	−
10	00100C85	PDSona	−
11	001100A6	DSon	NOTSRCERASE
12	00120868	SDPxnon	−
13	001302C8	SDPaon	−
14	00140869	DPSxnon	−
15	001502C9	DPSaon	−
16	00165CCA	PSDPSanaxx	−
17	00171D54	SSPxDSxaxn	−
18	00180D59	SPxPDxa	−
19	00191CC8	SDPSanaxn	−
1A	001A06C5	PDSPaox	−
1B	001B0768	SDPSxaxn	−
1C	001C06CA	PSDPaox	−
1D	001D0766	DSPDxaxn	−
1E	001E01A5	PDSox	−
1F	001F0385	PDSoan	−
20	00200F09	DPSnaa	−
21	00210248	SDPxon	−
22	00220326	DSna	−
23	00230B24	SPDnaon	−
24	00240D55	SPxDSxa	−
25	00251CC5	PDSPanaxn	−
26	002606C8	SDPSaox	−
27	00271868	SDPSxnox	−
28	00280369	DPSxa	−
29	002916CA	PSDPSaoxxn	−
2A	002A0CC9	DPSana	−
2B	002B1D58	SSPxPDxaxn	−
2C	002C0784	SPDSoax	−
2D	002D060A	PSDnox	−
2E	002E064A	PSDPxox	−
2F	002F0E2A	PSDnoan	−
30	0030032A	PSna	−
31	00310B28	SDPnaon	−
32	00320688	SDPSoox	−
33	00330008	Sn	NOTSRCCOPY
34	003406C4	SPDSaox	−
35	00351864	SPDSxnox	−
36	003601A8	SDPox	−
37	00370388	SDPoan	−
38	0038078A	PSDPoax	−
39	00390604	SPDnox	−
3A	003A0644	SPDSxox	−
3B	003B0E24	SPDnoan	−
3C	003C004A	PSx	−
3D	003D18A4	SPDSonox	−
3E	003E1B24	SPDSnaox	−
3F	003F00EA	PSan	−
40	00400F0A	PSDnaa	−
41	00410249	DPSxon	−
42	00420D5D	SDxPDxa	−
43	00431CC4	SPDSanaxn	−
44	00440328	SDna	SRCERASE
45	00450B29	DPSnaon	−
46	004606C6	DSPDaox	−
47	0047076A	PSDPxaxn	−
48	00480368	SDPxa	−
49	004916C5	PDSPDaoxxn	−
4A	004A0789	DPSDoax	−
4B	004B0605	PDSnox	−
4C	004C0CC8	SDPana	−
4D	004D1954	SSPxDSxoxn	−
4E	004E0645	PDSPxox	−
4F	004F0E25	PDSnoan	−
50	00500325	PDna	−
51	00510B26	DSPnaon	−
52	005206C9	DPSDaox	−
53	00530764	SPDSxaxn	−
54	005408A9	DPSonon	−
55	00550009	Dn	DSTINVERT
56	005601A9	DPSox	−
57	00570389	DPSoan	−
58	00580785	PDSPoax	−
59	00590609	DPSnox	−
5A	005A0049	DPx	PATINVERT
5B	005B18A9	DPSDonox	−
5C	005C0649	DPSDxox	−
5D	005D0E29	DPSnoan	−
5E	005E1B29	DPSDnaox	−
5F	005F00E9	DPan	−
60	00600365	PDSxa	−
61	006116C6	DSPDSaoxxn	−
62	00620786	DSPDoax	−
63	00630608	SDPnox	−
64	00640788	SDPSoax	−
65	00650606	DSPnox	−
66	00660046	DSx	SRCINVERT
67	006718A8	SDPSonox	−
68	006858A6	DSPDSonoxxn	−
69	00690145	PDSxxn	−
6A	006A01E9	DPSax	−
6B	006B178A	PSDPSoaxxn	−
6C	006C01E8	SDPax	−
6D	006D1785	PDSPDoaxxn	−
6E	006E1E28	SDPSnoax	−
6F	006F0C65	PDSxnan	−
70	00700CC5	PDSana	−
71	00711D5C	SSDxPDxaxn	−
72	00720648	SDPSxox	−
73	00730E28	SDPnoan	−
74	00740646	DSPDxox	−
75	00750E26	DSPnoan	−
76	00761B28	SDPSnaox	−
77	007700E6	DSan	−
78	007801E5	PDSax	−
79	00791786	DSPDSoaxxn	−
7A	007A1E29	DPSDnoax	−
7B	007B0C68	SDPxnan	−
7C	007C1E24	SPDSnoax	−
7D	007D0C69	DPSxnan	−
7E	007E0955	SPxDSxo	−
7F	007F03C9	DPSaan	−
80	008003E9	DPSaa	−
81	00810975	SPxDSxon	−
82	00820C49	DPSxna	−
83	00831E04	SPDSnoaxn	−
84	00840C48	SDPxna	−
85	00851E05	PDSPnoaxn	−
86	008617A6	DSPDSoaxx	−
87	008701C5	PDSaxn	−
88	008800C6	DSa	SRCAND
89	00891B08	SDPSnaoxn	−
8A	008A0E06	DSPnoa	−
8B	008B0666	DSPDxoxn	−
8C	008C0E08	SDPnoa	−
8D	008D0668	SDPSxoxn	−
8E	008E1D7C	SSDxPDxax	−
8F	008F0CE5	PDSanan	−
90	00900C45	PDSxna	−
91	00911E08	SDPSnoaxn	−
92	009217A9	DPSDPoaxx	−
93	009301C4	SPDaxn	−
94	009417AA	PSDPSoaxx	−
95	009501C9	DPSaxn	−
96	00960169	DPSxx	−
97	0097588A	PSDPSonoxx	−
98	00981888	SDPSonoxn	−
99	00990066	DSxn	−
9A	009A0709	DPSnax	−
9B	009B07A8	SDPSoaxn	−
9C	009C0704	SPDnax	−
9D	009D07A6	DSPDoaxn	−
9E	009E16E6	DSPDSaoxx	−
9F	009F0345	PDSxan	−
A0	00A000C9	DPa	−
A1	00A11B05	PDSPnaoxn	−
A2	00A20E09	DPSnoa	−
A3	00A30669	DPSDxoxn	−
A4	00A41885	PDSPonoxn	−
A5	00A50065	PDxn	−
A6	00A60706	DSPnax	−
A7	00A707A5	PDSPoaxn	−
A8	00A803A9	DPSoa	−
A9	00A90189	DPSoxn	−
AA	00AA0029	D	−
AB	00AB0889	DPSono	−
AC	00AC0744	SPDSxax	−
AD	00AD06E9	DPSDaoxn	−
AE	00AE0B06	DSPnao	−
AF	00AF0229	DPno	−
B0	00B00E05	PDSnoa	−
B1	00B10665	PDSPxoxn	−
B2	00B21974	SSPxDSxox	−
B3	00B30CE8	SDPanan	−
B4	00B4070A	PSDnax	−
B5	00B507A9	DPSDoaxn	−
B6	00B616E9	DPSDPaoxx	−
B7	00B70348	SDPxan	−
B8	00B8074A	PSDPxax	−
B9	00B906E6	DSPDaoxn	−
BA	00BA0B09	DPSnao	−
BB	00BB0226	DSno	MERGEPAINT
BC	00BC1CE4	SPDSanax	−
BD	00BD0D7D	SDxPDxan	−
BE	00BE0269	DPSxo	−
BF	00BF08C9	DPSano	−
C0	00C000CA	PSa	MERGECOPY
C1	00C11B04	SPDSnaoxn	−
C2	00C21884	SPDSonoxn	−
C3	00C3006A	PSxn	−
C4	00C40E04	SPDnoa	−
C5	00C50664	SPDSxoxn	−
C6	00C60708	SDPnax	−
C7	00C707AA	PSDPoaxn	−
C8	00C803A8	SDPoa	−
C9	00C90184	SPDoxn	−
CA	00CA0749	DPSDxax	−
CB	00CB06E4	SPDSaoxn	−
CC	00CC0020	S	SRCCOPY
CD	00CD0888	SDPono	−
CE	00CE0B08	SDPnao	−
CF	00CF0224	SPno	−
D0	00D00E0A	PSDnoa	−
D1	00D1066A	PSDPxoxn	−
D2	00D20705	PDSnax	−
D3	00D307A4	SPDSoaxn	−
D4	00D41D78	SSPxPDxax	−
D5	00D50CE9	DPSanan	−
D6	00D616EA	PSDPSaoxx	−
D7	00D70349	DPSxan	−
D8	00D80745	PDSPxax	−
D9	00D906E8	SDPSaoxn	−
DA	00DA1CE9	DPSDanax	−
DB	00DB0D75	SPxDSxan	−
DC	00DC0B04	SPDnao	−
DD	00DD0228	SDno	−
DE	00DE0268	SDPxo	−
DF	00DF08C8	SDPano	−
E0	00E003A5	PDSoa	−
E1	00E10185	PDSoxn	−
E2	00E20746	DSPDxax	−
E3	00E306EA	PSDPaoxn	−
E4	00E40748	SDPSxax	−
E5	00E506E5	PDSPaoxn	−
E6	00E61CE8	SDPSanax	−
E7	00E70D79	SPxPDxan	−
E8	00E81D74	SSPxDSxax	−
E9	00E95CE6	DSPDSanaxxn	−
EA	00EA02E9	DPSao	−
EB	00EB0849	DPSxno	−
EC	00EC02E8	SDPao	−
ED	00ED0848	SDPxno	−
EE	00EE0086	DSo	SRCPAINT
EF	00EF0A08	SDPnoo	−
F0	00F00021	P	PATCOPY
F1	00F10885	PDSono	−
F2	00F20B05	PDSnao	−
F3	00F3022A	PSno	−
F4	00F40B0A	PSDnao	−
F5	00F50225	PDno	−
F6	00F60265	PDSxo	−
F7	00F708C5	PDSano	−
F8	00F802E5	PDSao	−
F9	00F90845	PDSxno	−
FA	00FA0089	DPo	−
FB	00FB0A09	DPSnoo	PATPAINT
FC	00FC008A	PSo	−
FD	00FD0A0A	PSDnoo	−
FE	00FE02A9	DPSoo	−
FF	00FF0062	1	WHITENESS


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


  Glossary


  Terms

Term	Definition
Adaptive Differential Pulse Code Modulation (ADPCM)	An audio-compression technique.
animation	The display of a series of graphic images that simulates motion. Animation can be frame based or cast based.
auxiliary audio device	Audio devices whose output is mixed with the Musical Instrument Digital Interface (MIDI) and waveform output devices in a multimedia computer. An example of an auxiliary audio device is the compact disc audio output from a CD-ROM drive.
break key	In media control interface (MCI), a keystroke that interrupts a wait operation. By default, MCI defines this key as CTRL+BREAK. An application can redefine this key by using the MCI_BREAK command message.
compact disc−digital audio (CD-DA)	An optical data-storage format that provides for the storage of up to 73 minutes of high-quality digital-audio data on a compact disc. Also known as Red Book audio.
compact disc−read-only memory (CD-ROM)	An optical data-storage technology that allows large quantities of data to be stored on a compact disc.
CD-XA (CD-ROM Extended Architecture)	An extension of the CD-ROM standard that provides for storage of compressed audio data along with other data on a CD-ROM disc. This standard also defines the way data is read from a disc. Audio signals are combined with text and graphic data on a single track so they can be read at virtually the same time.
channel	Musical Instrument Digital Interface (MIDI) provides a way to send messages to an individual device within a MIDI setup. There are 16 MIDI channel numbers. Devices in a MIDI setup can be directed to respond only to messages marked with a channel number specific to the device.
channel map	The MIDI Mapper provides a channel map that can redirect MIDI messages from one channel to another.
chunk	The basic building block of a Resource Interchange File Format (RIFF) file, consisting of an identifier (called a chunk identifier), a chunk-size variable, and a chunk data area of variable size.
command message	In media control interface (MCI), a command message is a symbolic constant that represents a unique command for an MCI device. Command messages have associated data structures that provide information a device requires to carry out a request.
command string	In media control interface (MCI), a command string is a null-terminated character string that represents a command for an MCI device. The text string contains all the information that an MCI device needs to carry out a request. MCI parses the text string and translates it into an equivalent command message and data structure that it then sends to an MCI device driver.
compound device	A media control interface (MCI) device that requires a device element, usually a data file. An example of a compound device is the MCI waveform-audio driver. See also device element.
compound file	A number of individual files bound together in one physical file. Each individual file in a compound file can be accessed as if it were a single physical file.
control change	See MIDI control-change message.
device element	Data required for operation of media control interface (MCI) compound devices. The device element is generally an input or output data file.
file element	A complete file contained in a Resource Interchange File Format (RIFF) compound file.
FM synthesizer	See Frequency Modulation Synthesizer.
form type	A four-character code (FOURCC) identifying the type of data contained in a Resource Interchange File Format (RIFF) chunk. For example, a RIFF chunk with a form type of WAVE contains waveform audio data.
FOURCC (Four-Character Code)	A code used to identify Resource Interchange File Format (RIFF) chunks. A FOURCC is a 32-bit quantity represented as a sequence of one to four ASCII alphanumeric characters, padded on the right with blank characters.
frequency modulation (FM) synthesizer	A synthesizer that creates sounds by combining the output of digital oscillators using a frequency modulation technique.
General MIDI	A synthesizer specification created by the MIDI Manufacturers Association (MMA) defining a common configuration and set of capabilities for consumer MIDI synthesizers.
HMS time format	A time format used by media control interface (MCI) to express time in hours, minutes, and seconds. The HMS time format is used primarily by videodisc devices.
IMA	See Interactive Multimedia Association and International MIDI Association.
Interactive Multimedia Association (IMA)	A professional trade association of companies, institutions, and individuals involved in producing and using interactive multimedia technology.
International MIDI Association (IMA)	The nonprofit organization that circulates information about the Musical Instrument Digital Interface (MIDI) specification.
LIST chunk	A Resource Interchange File Format (RIFF) chunk with a chunk ID of LIST. LIST chunks contain a series of subchunks.
list type	A four-character code (FOURCC) identifying the type of data contained in a Resource Interchange File Format (RIFF) chunk with a chunk ID of LIST. For example, a LIST chunk with a list type of INFO contains a list of information about a file, such as the creation date and author.
Media Control Interface (MCI)	High-level control software that provides a device-independent interface to multimedia devices and media files. MCI includes a command-message interface and a command-string interface.
musical instrument digital interface (MIDI)	A standard protocol for communication between musical instruments and computers.
MIDI control-change message	A Musical Instrument Digital Interface (MIDI) message sent to a synthesizer to change different synthesizer control settings. An example of a control-change message is the volume controller message, which changes the volume of a specific MIDI channel.
MIDI Mapper	Windows systems software that modifies Musical Instrument Digital Interface (MIDI) output messages and redirects them to a MIDI output device using values stored in a MIDI setup map. The MIDI Mapper can change the destination channel and output device for a message, as well as modify program-change messages, volume values, and key values.
MIDI mapping	The process of translating and redirecting Musical Instrument Digital Interface (MIDI) messages according to data defined in a MIDI map setup.
MIDI program-change message	A Musical Instrument Digital Interface (MIDI) message sent to a synthesizer to change the patch on a specific MIDI channel.
MIDI sequence	Instrument Digital Interface (MIDI) data that can be played by a MIDI sequencer.
MIDI sequencer	A program that creates or plays songs stored as Musical Instrument Digital Interface (MIDI) files. When a sequencer plays MIDI files, it sends MIDI data from the file to a MIDI synthesizer, which produces the sounds. Windows provides a MIDI sequencer, accessible through media control interface (MCI), that plays MIDI files. See also media control interface.
MIDI setup map	A complete set of data for the Musical Instrument Digital Interface (MIDI) Mapper to use when redirecting MIDI messages. Only one setup map can be in effect at a given time, but the user can have several setup maps available and can choose between them using the MIDI Mapper Control Panel option.
MMA	See MIDI Manufacturers Association.
MIDI Manufacturers Association (MMA)	A collective organization composed of Musical Instrument Digital Interface (MIDI) instrument manufacturers and MIDI software companies. The MMA works with the MIDI Standard Committee to maintain the MIDI specification.
MSF time format	A time format used by media control interface (MCI) to express time in minutes, seconds, and frames. The number of frames in a second depends on the device type being used. Compact disc audio devices use 75 frames per second. The MSF time format is used primarily by compact disc audio devices.
patch	A particular setup of a Musical Instrument Digital Interface (MIDI) synthesizer that results in a particular sound, usually a sound simulating a specific musical instrument. Patches are also called programs. A MIDI program-change message changes the patch setting in a synthesizer. Patch also refers to the connection or connections between MIDI devices.
patch caching	Some internal Musical Instrument Digital Interface (MIDI) synthesizer device drivers can preload, or cache, their patch data. Patch caching reduces the delay between the moment that the synthesizer receives a MIDI program-change message and when it plays a note using the new patch. Patch caching also ensures that required patches are available (the synthesizer might load only a subset of its patches).
pitch scale factor	An application can request that a waveform audio driver scale the pitch by a specified factor. A scale factor of two results in a one-octave increase in pitch. Pitch scaling requires specialized hardware. The playback rate and sample rate are not changed.
playback rate scale factor	In waveform audio, an application can request that the waveform audio driver scale the playback rate by a specified factor. Playback scaling is accomplished through software; the sample rate is not changed, but the driver interpolates by skipping or synthesizing samples. For example, if the playback rate is changed by a factor of two, the driver skips every other sample.
PPQN	See parts per quarter note.
parts per quarter note (PPQN)	A time format used for Musical Instrument Digital Interface (MIDI) sequences. PPQN is the most common time format used with standard MIDI files.
preimaging	The process of building a movie frame in a memory buffer before it is displayed.
Red Book audio	See compact disc−digital audio.
resolution	For joysticks, resolution refers to the minimum and maximum intervals between joystick messages sent for a captured joystick.
	For timers, resolution refers to the accuracy of the timer event. A resolution value of zero means that the event must occur at the exact time requested, while a resolution value of ten means that the event must occur within ten milliseconds of the requested time.
Resource Interchange File Format (RIFF)	A tagged-file specification used to define standard formats for multimedia files. Tagged-file structure helps prevent compatibility problems that often occur when file-format definitions change over time. Because each piece of data in the file is identified by a standard header, an application that does not recognize a given data element can skip over the unknown information.
RIFF chunk	A chunk with chunk ID Resource Interchange File Format (RIFF) that includes an identifying code and zero or more subchunks, the contents of which depend on the form type.
RIFF file	A file whose format complies with one of the published Resource Interchange File Format (RIFF) forms. Examples of RIFF files include WAVE files for waveform audio data, RMID files for Musical Instrument Digital Interface (MIDI) sequences, and RDIB files for device-independent bitmaps.
RIFF form	A file-format specification based on the Resource Interchange File Format (RIFF) standard.
sample	A discrete piece of waveform data represented by a single numerical value. Sampling is the process of converting analog data to digital data by taking samples of the analog waveform at regular intervals.
sampling rate	The rate at which a waveform audio driver performs audio-to-digital or digital- to-audio conversion. For compact disc−digital audio (CD-DA), the sampling rate is 44.1 kHz. See also compact disc−digital audio.
seek	(1) With file input and output (I/O), to change the current position in the file. (The current position is the location where the next read or write operation will take place.)
	(2) With a media device (such as a hard disk), to position the medium so a certain sector can be accessed. The seek operation involves a physical movement of the device, so the time it takes can often be perceived by the user.
sequence	See MIDI sequence.
sequencer	See MIDI sequencer.
simple device	A media control interface (MCI) device that does not require a device element (data file) for playback. The MCI compact disc audio driver is an example of a simple device.
SMPTE	See Society of Motion Picture and Television Engineers.
Society of Motion Picture and Television Engineers (SMPTE)	An association of engineers involved in movie, television, and video production. SMPTE also refers to SMPTE time, the timing standard that this group adopted.
SMPTE division type	One of four SMPTE timing formats. SMPTE time is expressed in hours, minutes, seconds, and frames. The SMPTE division type specifies the frames-per-second value corresponding to a given SMPTE time. For example, a SMPTE time of one hour, 30 minutes, 24 seconds, and 15 frames is useful only if the frames-per-second value, or SMPTE division type, is known.
SMPTE offset	A Musical Instrument Digital Interface (MIDI) event that designates the SMPTE time at which playback of a MIDI file is to start. SMPTE offsets are used only with MIDI files using SMPTE division type.
SMPTE time	A standard representation of time developed for the video and film industries. SMPTE time is used with Musical Instrument Digital Interface (MIDI) audio because many people use MIDI to score films and video. SMPTE time is an absolute time format expressed in hours, minutes, seconds, and frames. Standard SMPTE division types are 24, 25, and 30 frames per second.
square-wave synthesizer	A synthesizer that produces sound by adding square waves of various frequencies. A square wave is a rectangular waveform.
streaming	The process of transferring information from a storage device, such as a hard disk or CD-ROM, to a device driver.
system-exclusive data	In Musical Instrument Digital Interface (MIDI), messages understood only by MIDI devices from a specific manufacturer. MIDI device manufacturers can use system-exclusive data to define custom messages that can be exchanged between their MIDI devices. (The standard MIDI specification defines only a framework for system-exclusive messages.) See also Musical Instrument Digital Interface.
tagged file format	A file format in which data is tagged using standard headers that identify information type and length. See also Resource Interchange File Format.
tempo	The speed at which a Musical Instrument Digital Interface (MIDI) file is played. Tempo is measured in beats per minute (BPM); typical MIDI tempo is 120 BPM. See also Musical Instrument Digital Interface.
threshold	For the joystick interface, the amount, in device units, that the stick coordinates must change before the application is notified of the movement. A high threshold reduces the number of joystick messages sent to an application, but it also reduces the sensitivity of the joystick.
time stamp	A tag that enables a Musical Instrument Digital Interface (MIDI) sequencer to replay recorded MIDI data at the proper moment. See also Musical Instrument Digital Interface.
TMSF time format	A time format used by Media Control Interface (MCI) to express time in tracks, minutes, seconds, and frames. The number of frames in a second depends on the type of device being used; compact disc audio devices use 75 frames per second. The TMSF time format is used primarily by compact disc audio devices. See also Media Control Interface.
track	A sequence of sound on a compact disc−digital audio (CD-DA) disc. With a Musical Instrument Digital Interface (MIDI) file, information can be separated into tracks, defined by the creator of the file. MIDI file tracks can correspond to MIDI channels, or they can correspond to parts of a song (such as melody or chorus); a CD-DA track usually corresponds to a song. See also compact disc−digital audio.
volume scalar	A component of a Musical Instrument Digital Interface (MIDI) Mapper patch map that adjusts the volume of a patch on a synthesizer. For example, if the bass patch on a synthesizer is too loud relative to the piano patch, the volume scalar can reduce the volume for the bass or increase the volume for the piano. (Applications playing waveform audio can also adjust the output volume.) See also MIDI Mapper, patch.
WAVE file	A Microsoft standard file format for storing waveform audio data. WAVE files have a .WAV filename extension.
waveform audio	A technique of recreating an audio waveform from digital samples of the waveform.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Win32 Programmer's Reference, Volume 2
Systems Services, Multimedia, Extensions, and Application Notes


CreateWindow Function


DestroyWindow Function


CreateEvent Function


OpenEvent Function


Using the OpenEvent Function


Using the DuplicateHandle Function


Child Process Inherits Handle


Removing Object from Memory


More than One File Object Referring to Single File


Multiple File Handles Referring to Same File Object


Blocks of Security Information


Typical Network Structure


Scrolling the Screen Buffer


ScrollConsoleScreenBuffer Operation


Clipping


Windows Audio Architecture


MIDI Mapper


MIDI Mapper Architecture


The Channel Map


Patch Maps


The Volume Scalar


The Key Map


MIDI Channels in MIDI Files


Standard Key Assignments


Audio-signal Routing


RIFF Chunks


LIST Chunks


File I/O Buffer - I


File I/O Buffer - II


Color Dialog Box


RGB Color Model


HSL Color Model


Font Dialog Box


Open Dialog Box


Save As Dialog Box


Print Dialog Box


Print Setup Dialog Box


Find Dialog Box


Replace Dialog Box


Screen Saver Dialog Box


Control Panel Window


Introduction
Programmer's Reference, Volume 3: Functions A-G

Introduction

The Microsoft® Win32™ application programming interface (API) allows applications to exploit the power of 32-bits on the Microsoft® Windows™ family of operating systems. Applications written to the Win32 API are scalable on single and multiprocessor systems, and portable to RISC architectures. These manuals document the complete Win32 API including window management, graphics, file I/O, threading, memory management, security and networking.

This manual describes the Win32 API in alphabetic order (A through G). Each description includes the function's syntax, purpose, parameters, and possible return values. Many descriptions also contain additional information, including whether the function supports Unicode™ or whether it is new, obsolete, or has been deleted.


About the Microsoft Win32 Programmers Reference
  About the Microsoft Win32 Programmer's Reference

The Microsoft Win32 Programmer's Reference, a set of five volumes, fully describes the Win32 API, including functions and related data types, macros, structures, and messages. The Programmer's Reference is the source for specific information about programming for Windows.

Volumes 1 and 2 describe the purpose of the functions in the Win32 API and explains the concepts and principles behind the functions. These volumes are intended for programmers who are new to Windows or who are learning parts of it for the first time. These two volumes provide the basic information needed for an understanding of Windows programming.

Volumes 3 and 4 consist of an alphabetic listing of the Win32 functions. These volumes define the details of the syntax, parameters, and return values of each function. Volume 5 contains alphabetical listings of the Win32 data types, macros, messages, and structures. Volumes 3 through 5 are intended for programmers already acquainted with Windows programming and who need only specifics of particular functions.


  Microsoft Windows and the C Programming Language

The C programming language is the preferred development language for Windows-based applications. Many of the programming features of Windows were designed with C in mind. Windows-based applications can also be developed in other languages, but C is the most straightforward and easiest language to use to access Windows functions. For this reason, all syntax and program samples are written in the C programming language.

The Win32 API uses many types, macros, and structures that are not part of standard C language. These types, macros, and structures have been defined to make the task of creating Windows-based applications simpler and to make application sources clearer and easier to understand. All types, macros, and structures discussed in this manual are defined in the Win32 C-language header files.


  Document Conventions

The following conventions are used throughout this manual to define syntax.

Convention	Meaning
Bold text	Denotes a term or character to be typed literally, such as a predefined data type or function name (HWND or CreateWindowEx), a command, or a command-line option (/x). You must type these terms exactly as shown.
Italic text	Denotes a placeholder or variable: You must provide the actual value. For example, the statement SetCursorPos(X,Y) requires you to substitute values for the X and Y parameters.
[ ]	Enclose optional parameters.
|	Separates an either/or choice.
...	Specifies that the preceding item may be repeated.
.	Represents an omitted portion of a sample application.
.
.
In addition, certain text conventions are used to help you understand this material.

Convention	Meaning
SMALL CAPITALS	Indicate the names of keys, key sequences, and key combinations — for example, ALT+SPACEBAR.
FULL CAPITALS	Indicate filenames and paths, most type and structure names (which are also bold), and constants.
monospace	Sets off code examples and shows syntax spacing.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Programmer's Reference, Volume 3:
Functions A-G


  AbnormalTermination

BOOL AbnormalTermination(VOID)

The AbnormalTermination function indicates whether the try block of a try-finally statement terminated normally. The function can be called only from within the finally block of a try-finally statement.

Parameters

This function has no parameters.

Return Value

If the try block of the try-finally statement terminated abnormally, the return value is TRUE; otherwise, it is FALSE.

Comments

The try block terminates normally only if execution leaves the block sequentially after executing the last statement in the block. Statements (such as return, goto, continue, or break) that cause execution to leave the try block result in abnormal termination of the block. This is the case even if such a statement is the last statement in the try block.

Abnormal termination of a try block causes the system to search backward through all stack frames to determine whether any termination handlers must be called. This can result in the execution of hundreds of instructions, so it is important to avoid abnormal termination of a try block due to a return, goto, continue, or break statement. Note that these statements do not generate an exception, even though the termination is abnormal.


  AbortDoc

int AbortDoc(hdc)
HDC  hdc;   /* handle of device context */

The AbortDoc function stops the current print job and erases everything drawn since the last call to the StartDoc function. This function replaces the ABORTDOC printer escape.

Parameters

hdc

Identifies the device context for the print job.

Return Value

If the function succeeds, the return value is greater than zero.

If the function fails, the return value is SP_ERROR. To get extended error information, use the GetLastError function.

Comments

Applications should call the AbortDoc function to stop a print job in case an error occurred, or to stop a print job after the user cancels that job. To end a successful print job, an application should call the EndDoc function.

If Windows Print Manager was used to start the print job, calling the AbortDoc function erases the entire spool job, so that the printer receives nothing. If Print Manager was not used to start the print job, the data may already have been sent to the printer. In this case, the printer driver resets the printer (when possible) and ends the print job.

See Also

»EndDoc«, »SetAbortProc«, »StartDoc«


  AbortPath

BOOL AbortPath(hdc)
HDC  hdc;   /* handle of device context */

The AbortPath function closes and discards any paths in the given device context (DC).

Parameters

hdc

Identifies the DC from which a path will be discarded.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If there is an open path bracket in the given device context, the path bracket is closed and the path is discarded. If there is a closed path in the device context, the path is discarded.

See Also

»BeginPath«, »EndPath«


  AbortPrinter

BOOL AbortPrinter(hPrinter)
HANDLE  hPrinter;   /* handle of printer object */

The AbortPrinter function deletes a printer's spool file if the printer is configured for spooling.

Parameters

hPrinter

Identifies the printer from which the spool file is deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the printer is not configured for spooling, this function has no effect.

The handle hPrinter is returned by the OpenPrinter function.

See Also

»OpenPrinter«


  AbortProc

BOOL CALLBACK AbortProc(hdc, iError)
HDC  hdc;   /* handle of device context */
int  iError;   /* error value */

The AbortProc function is an application-defined callback function that is called when a print job is to be canceled during spooling.

Parameters

hdc

Identifies the device context.

iError

Specifies whether an error has occurred. This parameter is zero if no error has occurred; it is SP_OUTOFDISK if Windows Print Manager is currently out of disk space and more disk space will become available if the application waits.

Return Value

The callback function should return TRUE to continue the print job or FALSE to cancel the print job.

Comments

An application installs this callback function by calling the SetAbortProc function. AbortProc is a placeholder for the application-defined function name.

If the iError parameter is SP_OUTOFDISK, the application need not cancel the print job. If it does not cancel the job, it must yield to Print Manager by calling the PeekMessage or GetMessage function.

See Also

»GetMessage«, »PeekMessage«, »SetAbortProc«


  AbortSystemShutdown

BOOL AbortSystemShutdown(lpszMachineName)
LPTSTR  lpszMachineName;   /* addr. of name of computer to stop shutting down */

The AbortSystemShutdown function stops a system shutdown started by using the InitiateSystemShutdown function.

Parameters

lpszMachineName

Points to the null-terminated string that specifies the network name of the computer where the shutdown is to be stopped. If lpszMachineName is NULL or points to an empty string, the function stops the shutdown on the local computer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The InitiateSystemShutdown function displays a dialog box that notifies the user that the system is shutting down. During the InitiateSystemShutdown time-out period, the AbortSystemShutdown function can prevent the system from shutting down.

To stop the local computer from shutting down, the calling process must have the SE_SHUTDOWN_NAME privilege. To stop a remote computer from shutting down, the calling process must have the SE_REMOTE_SHUTDOWN_NAME privilege on the remote computer. By default, users can enable the SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers.

Failures of this function are typically due to an invalid computer name, an inaccessible computer, or insufficient privilege.

See Also

»InitiateSystemShutdown«


  AccessCheck

BOOL AccessCheck(pSD, hClientToken, dwDesiredAccess, pgm, pps, cbps,
lpdwGrantedAccess, lpfStatus)
PSECURITY_DESCRIPTOR  pSD;   /* address of security descriptor */
HANDLE  hClientToken;   /* handle of client access token */
DWORD  dwDesiredAccess;   /* access mask to request */
PGENERIC_MAPPING  pgm;   /* address of generic-mapping structure */
PPRIVILEGE_SET  pps;   /* address of privilege-set structure */
LPDWORD  cbps;   /* size of privilege-set structure */
LPDWORD  lpdwGrantedAccess;   /* address of granted access mask */
LPBOOL  lpfStatus;   /* address of flag indicating whether access granted */

The AccessCheck function is used by a server application to check a client's access to an object against the access control associated with the object.

Parameters

pSD

Points to a SECURITY_DESCRIPTOR structure against which access is checked.

hClientToken

Identifies an access token representing a client attempting to gain access.

This handle must be obtained from a communications session layer — for instance, a named pipe — to prevent possible security policy violations.

dwDesiredAccess

Specifies the access mask to be requested. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

pgm

Points to the GENERIC_MAPPING structure associated with the object for which access is being checked.

The GENERIC_MAPPING structure has the following form:

typedef struct _GENERIC_MAPPING { /* gm */

    ACCESS_MASK GenericRead;

    ACCESS_MASK GenericWrite;

    ACCESS_MASK GenericExecute;

    ACCESS_MASK GenericAll;

} GENERIC_MAPPING;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

pps

Points to a PRIVILEGE_SET structure the function fills with any privileges used to perform the access validation. If no privileges were used, the buffer contains a privilege set consisting of zero privileges.

The PRIVILEGE SET structure has the following form:

typedef struct _PRIVILEGE_SET { /* ps */

    DWORD PrivilegeCount;

    DWORD Control;

    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];

} PRIVILEGE_SET;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbps

Specifies the size, in bytes, of the buffer pointed to by the pps parameter.

lpdwGrantedAccess

Points to a variable the function fills with an access mask indicating which access rights were granted. If the function fails, this access mask is not supplied.

lpfStatus

Points to a flag indicating the success or failure of the access check. If lpfStatus is TRUE, the access token has the requested access to the object. If lpfStatus is FALSE, the access token does not have the requested access. When this parameter is FALSE, the application can use the GetLastError function to get extended error information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The AccessCheck function compares the specified security descriptor with the specified access token and indicates, in the lpfStatus parameter, whether access is granted or denied. If access is granted, the requested access mask becomes the object's granted access mask.

Only the discretionary access-control list is examined during an access check.

See Also

»AccessCheckAndAuditAlarm«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »MapGenericMask«, »PrivilegeCheck«


  AccessCheckAndAuditAlarm

BOOL AccessCheckAndAuditAlarm(lpszSubsystem, lpvHandleId, lpszObjectType,
lpszObject, psd, dwDesiredAccess, pgm, fObjectCreation, lpdwGrantedAccess, lpfAccessStatus,
lpfGenerateOnClose)
LPTSTR  lpszSubsystem;   /* address of string for subsystem name */
LPVOID  lpvHandleId;   /* address of handle identifier */
LPTSTR  lpszObjectType;   /* address of string for object type */
LPTSTR  lpszObject;   /* address of string for object name */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
DWORD  dwDesiredAccess;   /* mask for requested access rights */
PGENERIC_MAPPING  pgm;   /* address of GENERIC_MAPPING */
BOOL  fObjectCreation;   /* object-creation flag */
LPDWORD  lpdwGrantedAccess;   /* address of mask for granted rights */
LPBOOL  lpfAccessStatus;   /* address of flag for results */
LPBOOL  lpfGenerateOnClose;   /* address of flag for audit generation */

The AccessCheckAndAuditAlarm function performs an access validation and generates corresponding audit messages. An application can also use this function to determine whether necessary privileges are held by a client process. This function is generally used by a server application impersonating a client process. Alarms are not supported in the current version of Windows NT.

Parameters

lpszSubsystem

Points to a null-terminated string specifying the name of the subsystem calling the function — for example, "DEBUG" or "WIN32."

lpvHandleId

Points to a unique 32-bit value representing the client's handle of the object. If the access is denied, this value is ignored and may be reused.

lpszObjectType

Points to a null-terminated string specifying the type of object being created or accessed. This string appears in the audit log for the object.

lpszObject

Points to a null-terminated string specifying the name of the object being created or accessed. This string appears in the audit log for the object.

psd

Points to the SECURITY_DESCRIPTOR structure against which access is checked.

dwDesiredAccess

Specifies an access mask giving the requested access rights. This mask must have been mapped to contain no generic access rights by the MapGenericMask function.

pgm

Points to the GENERIC_MAPPING structure associated with the type of object being examined.

The GENERIC_MAPPING structure has the following form:

typedef struct _GENERIC_MAPPING { /* gm */

    ACCESS_MASK GenericRead;

    ACCESS_MASK GenericWrite;

    ACCESS_MASK GenericExecute;

    ACCESS_MASK GenericAll;

} GENERIC_MAPPING;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fObjectCreation

Specifies a flag that determines whether the calling application will create a new object when access is granted. If this flag is TRUE, the application creates a new object; if it is FALSE, the application opens an existing object.

lpdwGrantedAccess

Points to a buffer that receives an access mask indicating which access rights were granted, if the function succeeds.

lpfAccessStatus

Points to a flag that the function sets to indicate the success or failure of the access check. If access is granted, this flag is TRUE; otherwise, it is FALSE.

lpfGenerateOnClose

Points to a flag set by the audit-generation routine when the function returns. This flag must be passed to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The AccessCheckAndAuditAlarm function compares the specified security descriptor with the impersonation access token of the calling process and indicates whether access is granted or denied. If access is granted, the requested access mask becomes the granted access mask for the object. This function also generates any necessary audit messages as a result of the access attempt.

This function requires the calling process to have the SE_AUDIT_NAME privilege. The test for this privilege is performed against the primary token of the calling process, not the impersonation token of the thread.

See Also

»AccessCheck«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »MapGenericMask«, »ObjectCloseAuditAlarm«, »ObjectOpenAuditAlarm«, »ObjectPrivilegeAuditAlarm«, »PrivilegeCheck«, »PrivilegedServiceAuditAlarm«


  AccessResource

The AccessResource function has been deleted. For Win32 applications, use the LoadResource, LockResource, and FindResource functions.


  ActivateKeyboardLayout

BOOL ActivateKeyboardLayout(hkl, fuFlags)
HKL  hkl;   /* handle of keyboard layout */
UINT  fuFlags;   /* keyboard layout flags */

The ActivateKeyboardLayout function activates a different keyboard layout.

Parameters

hkl

Identifies the keyboard layout to be activated. The layout must have been loaded by a previous call to the LoadKeyboardLayout function. This parameter must be either the handle of a keyboard layout or one of the following values:

Value	Meaning
HKL_NEXT	Selects the next layout in the circular list of loaded layouts maintained by the system.
HKL_PREVIOUS	Selects the previous layout in the circular list of loaded layouts maintained by the system.
fuFlags

Specifies how the keyboard layout is to be activated. This parameter can be one of the following values:

Value	Meaning
KLF_REORDER	If this bit is set, the system's circular list of loaded keyboard layouts is reordered. If this bit is not set, the list is rotated without a change of order. For example if a user had an English layout active as well as having French, German and Spanish layouts loaded (in that order), then activating the German layout with the KLF_REORDER bit set would produce the following order: German, English, French, Spanish. Activating the German layout without the KLF_REORDER bit set would produce the following order: German, Spanish, English, French.
KLF_UNLOADPREVIOUS	The previously active layout is unloaded.
If less than three layouts are loaded, the value of this flag is irrelevant.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Several keyboard layouts can be loaded at any one time, but only one is active at a time. Loading multiple keyboard layouts makes it possible to rapidly switch between layouts.

See Also

»LoadKeyboardLayout«


  AddAccessAllowedAce

BOOL AddAccessAllowedAce(pAcl, dwAclRevision, dwAccessMask, pSid)
PACL  pAcl;   /* address of access-control list */
DWORD  dwAclRevision;   /* ACL revision level */
DWORD  dwAccessMask;   /* access mask */
PSID  pSid;   /* address of security identifier */

The AddAccessAllowedAce function adds an access-allowed ACE to an ACL. The access is granted to a specified SID.

An ACE is an access-control entry. An ACL is an access-control list. An SID is a security identifier.

Parameters

pAcl

Points to an ACL structure. This function adds an access-allowed ACE to this ACL. The ACE is in the form of an ACCESS_ALLOWED_ACE structure.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

The ACCESS_ALLOWED_ACE structure has the following form:

typedef struct _ACCESS_ALLOWED_ACE { /* aaace */

    ACE_HEADER Header;

    ACCESS_MASK Mask;

    DWORD SidStart;

} ACCESS_ALLOWED_ACE;

For a full description of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwAclRevision

Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.

dwAccessMask

Specifies the mask of access rights to be granted to the specified SID.

pSid

Points to the SID structure representing a process being granted access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The addition of an access-allowed ACE to an ACL is the most common form of ACL modification.

The ACE_HEADER structure placed in the ACE by this function specifies a type and size, but provides no inheritance and no ACE flags. The ACE_HEADER structure has the following form:

typedef struct _ACE_HEADER { /* acehdr */

    BYTE AceType;

    BYTE AceFlags;

    WORD AceSize;

} ACE_HEADER;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

See Also

»AddAccessDeniedAce«, »AddAce«, »AddAuditAccessAce«, »DeleteAce«, »GetAce«


  AddAccessDeniedAce

BOOL AddAccessDeniedAce(pAcl, dwAclRevision, dwAccessMask, pSid)
PACL  pAcl;   /* address of access-control list */
DWORD  dwAclRevision;   /* ACL revision level */
DWORD  dwAccessMask;   /* access mask */
PSID  pSid;   /* address of security identifier */

The AddAccessDeniedAce function adds an access-denied ACE to an ACL. The access is denied to a specified SID.

An ACE is an access-control entry. An ACL is an access-control list. An SID is a security identifier.

Parameters

pAcl

Points to an ACL structure. This function adds an access-denied ACE to this ACL. The ACE is in the form of an ACCESS_DENIED_ACE structure.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

The ACCESS_DENIED_ACE structure has the following form:

typedef struct _ACCESS_DENIED_ACE { /* adace */

    ACE_HEADER  Header;

    ACCESS_MASK Mask;

    DWORD       SidStart;

} ACCESS_DENIED_ACE;

For a full description of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwAclRevision

Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.

dwAccessMask

Specifies the mask of access rights being denied to the specified SID.

pSid

Points to the SID structure representing the process being denied access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ACE_HEADER structure placed in the ACE by this function specifies a type and size, but provides no ACE flags. The ACE_HEADER structure has the following form:

typedef struct _ACE_HEADER { /* acehdr */

    BYTE AceType;

    BYTE AceFlags;

    WORD AceSize;

} ACE_HEADER;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

See Also

»AddAccessAllowedAce«, »AddAce«, »AddAuditAccessAce«, »DeleteAce«, »GetAce«


  AddAce

BOOL AddAce(pAcl, dwAclRevision, dwStartingAceIndex, lpvAceList, cbAceList)
PACL  pAcl;   /* address of access-control list */
DWORD  dwAclRevision;   /* ACL revision level */
DWORD  dwStartingAceIndex;   /* index of ACE position in ACL */
LPVOID  lpvAceList;   /* address of one or more ACEs */
DWORD  cbAceList;   /* size of buffer for ACEs */

The AddAce function adds one or more ACEs to a specified ACL.

An ACE is an access-control entry. An ACL is an access-control list.

Parameters

pAcl

Points to an ACL structure. This function adds an ACE to this ACL.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwAclRevision

Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.

dwStartingAceIndex

Specifies the position in the ACL's list of ACEs at which to add new ACEs. A value of zero inserts the ACEs at the beginning of the list. A value of MAXDWORD appends the ACEs to the end of the list.

lpvAceList

Points to a list of one or more ACEs to be added to the specified ACL. The ACEs in the list must be stored contiguously.

cbAceList

Specifies the size, in bytes, of the input buffer pointed to by the lpvAceList parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Applications frequently use the FindFirstFreeAce and GetAce functions when using the AddAce function to manipulate an ACL. In addition, the ACL_SIZE_INFORMATION structure retrieved by the GetAclInformation function contains the size of the ACL and the number of ACEs it contains.

See Also

»AddAccessAllowedAce«, »AddAccessDeniedAce«, »AddAuditAccessAce«, »DeleteAce«, »FindFirstFreeAce«, »GetAce«, »GetAclInformation«


  AddAtom

ATOM AddAtom(lpszName)
LPCTSTR  lpszName;   /* address of string to add */

The AddAtom function adds a character string to the local atom table and returns a unique value (an atom) identifying the string.

Parameters

lpszName

Points to the null-terminated string to be added. Strings differing only in case are considered identical. The case of the first string added is preserved and returned by the GetAtomName function.

Return Value

If the function succeeds, the return value is the newly created atom; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The AddAtom function stores no more than one copy of a given string in the atom table. If the string is already in the table, the function returns the existing atom and, in the case of a string atom, increments the string's reference count.

The MAKEINTATOM macro can be used to convert a WORD value into a string that can be added to the atom table by using the AddAtom function.

AddAtom returns a string atom whose value is in the range 0xC000 through 0xFFFF.

If lpszName has the form "#1234", AddAtom returns an integer atom whose value is the 16-bit representation of the decimal number specified in the string (0x04D2, in this example). If the decimal value specified is 0x0000 or a value in the range 0xC000 through 0xFFFF, the return value is zero, indicating an error. If lpszName is in the range 0x0001 through 0xBFFF, the return value is the low-order word of lpszName.

»DeleteAtom«, »FindAtom«, »GetAtomName«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«, »GlobalGetAtomName«, »MAKEINTATOM«


  AddAuditAccessAce

BOOL AddAuditAccessAce(pAcl, dwAclRevision, dwAccessMask, pSid, fAuditSuccess,
fAuditFailure)
PACL  pAcl;   /* address of access-control list */
DWORD  dwAclRevision;   /* ACL revision level */
DWORD  dwAccessMask;   /* access mask */
PSID  pSid;   /* address of security identifier */
BOOL  fAuditSuccess;   /* flag for auditing successful access */
BOOL  fAuditFailure;   /* flag for auditing unsuccessful access attempts */

The AddAuditAccessAce function adds a system-audit ACE to a system ACL. The access of a specified SID is audited.

An ACE is an access-control entry. An ACL is an access-control list. An SID is a security identifier.

Parameters

pAcl

Points to an ACL structure. This function adds a system-audit ACE to this ACL. The ACE is in the form of an SYSTEM_AUDIT_ACE structure.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

The SYSTEM_AUDIT_ACE structure has the following form:

typedef struct _SYSTEM_AUDIT_ACE { /* sada */

    ACE_HEADER  Header;

    ACCESS_MASK Mask;

    DWORD       SidStart;

} SYSTEM_AUDIT_ACE;

For a full description of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwAclRevision

Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.

dwAccessMask

Specifies the mask of access rights to be audited for the specified SID.

pSid

Points to the SID structure representing the process whose access is being audited.

fAuditSuccess

Specifies whether successful access attempts are to be audited. Set this flag to TRUE to enable auditing; otherwise, set it to FALSE.

fAuditFailure

Specifies whether unsuccessful access attempts are to be audited. Set this flag to TRUE to enable auditing; otherwise, set it to FALSE.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ACE_HEADER structure placed in the ACE by this function specifies a type and size, but provides no ACE flags. The ACE_HEADER structure has the following form:

typedef struct _ACE_HEADER { /* acehdr */

    BYTE AceType;

    BYTE AceFlags;

    WORD AceSize;

} ACE_HEADER;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

See Also

»AddAccessAllowedAce«, »AddAccessDeniedAce«, »AddAce«, »DeleteAce«, »GetAce«


  AddFontModule

int AddFontModule(hmodFontRes)
HMODULE  hmodFontRes;   /* handle of font resource */

The AddFontModule function adds a font from a resource in a Windows executable file or a Windows dynamic link library to the Windows font table.

Parameters

hmodFontRes

Identifies a loaded font-resource module.

Return Value

If the function succeeds, the return value specifies the number of fonts added.

If the function fails, the return value is zero. Call GetLastError for extended error information.

Comments

Any application that adds or removes fonts from the Windows font table should notify other windows of the change by sending a WM_FONTCHANGE message to all top-level windows in the operating system. The application should send this message by calling the SendMessage function, and setting the hWnd parameter set to HWND_BROADCAST.

When an application no longer needs a font that it loaded by calling the AddFontModule function, it must remove the font by calling the RemoveFontModule function.

See Also

»RemoveFontModule«


  AddFontResource

int AddFontResource(lpszFilename)
LPCTSTR  lpszFilename;   /* address of font-resource filename */

The AddFontResource function adds the font resource from the specified file to the Windows font table. The font can subsequently be used for text output by any Windows-based application.

Parameters

lpszFilename

Points to a null-terminated character string that contains a valid font file filename. The filename may specify either a .FON font resource file, a .FNT raw bitmap font file, a .TTF raw TrueType file, or a .FOT TrueType resource file.

Return Value

If the function succeeds, the return value specifies the number of fonts added.

If the function fails, the return value is zero. Call GetLastError for extended error information.

Comments

Any application that adds or removes fonts from the Windows font table should notify other windows of the change by sending a WM_FONTCHANGE message to all top-level windows in the operating system. The application should send this message by calling the SendMessage function and setting the hwnd parameter to HWND_BROADCAST.

When an application no longer needs a font resource that it loaded by calling the AddFontResource function, it must remove the resource by calling the RemoveFontResource function.

See Also

»RemoveFontResource«


  AddForm

BOOL AddForm(hPrinter, cLevel, pForm)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  cLevel;   /* data-structure level */
LPBYTE  pForm;   /* address of data structure */

The AddForm function adds a form to the list of available forms that can be selected for the given printer.

Parameters

hPrinter

Identifies the printer that supports printing with the specified form.

cLevel

Specifies the version of the structure to which pForm points. This value must be 1.

pForm

Points to a FORM_INFO_1 structure. The FORM_INFO_1 structure has the following form:

typedef struct _FORM_INFO_1 { /* fi1 */

    LPTSTR pName;

    SIZEL  Size;

    RECTL  ImageableArea;

} FORM_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The handle hPrinter is returned by the OpenPrinter function.

An application can determine which forms are available for a printer by calling the EnumForms function.

See Also

»EnumForms«, »OpenPrinter«


  AddJob

BOOL AddJob(hPrinter, cLevel, pData, cbBuf, pcbNeeded)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  cLevel;   /* data-structure level */
LPBYTE  pData;   /* address of data-structure array */
DWORD  cbBuf;   /* count of bytes in array */
LPDWORD  pcbNeeded;   /* address of variable that contains count of bytes required */

The AddJob function returns a full path and filename of a file that can be used to store a print job.

Parameters

hPrinter

Identifies the printer for which the print job is intended.

cLevel

Specifies the version of the structure to which pData points. This value must be 1.

pData

Points to an ADDJOB_INFO_1 structure. The ADDJOB_INFO_1 structure has the following form:

typedef struct _ADDJOB_INFO_1 { /* aji1 */

    LPTSTR  Path;

    DWORD   JobId;

} ADDJOB_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the buffer pointed to by pData.

pcbNeeded

Points to a variable that will be updated with the number of bytes copied or the number of bytes required. If cbBuf is less than the required number of bytes, pcbNeeded specifies the number of bytes required; if cbBuf is large enough, pcbNeeded specifies the number of bytes copied.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The filename returned in the ADDJOB_INFO_1 structure can be opened with the CreateFile function. Once the file is opened, data can be written to the file by calling the WriteFile function.

The job identifier returned in the ADDJOB_INFO_1 structure can be passed to the SetJob and ScheduleJob functions in order to control the print job.

See Also

»OpenPrinter«, »ScheduleJob«, »SetJob«


  AddMonitor

BOOL AddMonitor (pName, Level, pMonitors)
LPTSTR  pName;   /* address of server name */
DWORD  Level;   /* monitor info structure level */
LPBYTE  pMonitors;   /* address of monitor info structure */

The AddMonitor function installs a local printer monitor and links the configuration, data, and monitor files. Future releases of Windows NT may allow remote installation of printer monitors.

Parameters

pName

Points to a null-terminated string that specifies the name of the server on which the monitor should be installed. For this release of Windows NT,  monitors may only be installed locally, so this string should be NULL.

Level

Specifies the version of the structure to which pMonitors points. This value must be 2.

pMonitors

Points to a MONITOR_INFO_2 structure. The MONITOR_INFO_2 structure has the following form:

typedef struct _MONITOR_INFO_2 { /* mi2 */

    LPTSTR pName;

    LPTSTR pEnvironment ;

    LPTSTR pDLLName ;

} MONITOR_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before an application calls this function, all files required by the monitor must be copied to the system32 directory.

An application can determine which printer monitors are currently installed by calling the EnumMonitors function.

A monitor added by AddMonitor may be removed by calling DeleteMonitor.

See Also

»DeleteMonitor«, »EnumMonitors«


  AddPort

BOOL AddPort(lpszName, hwnd, lpszMonitorName)
LPTSTR  lpszName;   /* address of a server name */
HWND  hwnd;   /* handle of parent window */
LPTSTR  lpszMonitorName;   /* address of a monitor name */

The AddPort function adds the name of a port to the list of supported ports.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server to which the port is connected. If this string is NULL, the port is local.

hwnd

Identifies the parent window of the AddPort dialog box.

lpszMonitorName

Points to a null-terminated string that specifies the monitor associated with the port.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The monitor name specified in lpszMonitorName can be retrieved by calling the EnumMonitors function.

An application can determine which ports are currently supported by calling the EnumPorts function.

See Also

»EnumMonitors«, »EnumPorts«


  AddPrinter

HANDLE AddPrinter(lpszName, dwLevel, lpbPrinter)
LPTSTR  lpszName;   /* address of server name */
DWORD  dwLevel;   /* printer info structure level */
LPBYTE  lpbPrinter;   /* address of structure */

The AddPrinter function adds a printer to the list of supported printers for a specified server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the printer's print processor should be installed. If this string is NULL, the print processor is installed locally.

dwLevel

Specifies the version of the structure to which lpbPrinter points. This value must be 2.

lpbPrinter

Points to a PRINTER_INFO_2 structure. The pPrinterName, pPortName, and pDriverName members of this structure must be set before calling this function. The PRINTER_INFO_2 structure has the following form:

typedef struct _PRINTER_INFO_2 { /* pri2 */

    LPTSTR    pServerName;

    LPTSTR    pPrinterName;

    LPTSTR    pShareName;

    LPTSTR    pPortName;

    LPTSTR    pDriverName;

    LPTSTR    pComment;

    LPTSTR    pLocation;

    LPDEVMODE pDevMode;

    LPTSTR    pSepFile;

    LPTSTR    pPrintProcessor;

    LPTSTR    pDatatype;

    LPTSTR    pParameters;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD     Attributes;

    DWORD     Priority;

    DWORD     DefaultPriority;

    DWORD     StartTime;

    DWORD     UntilTime;

    DWORD     Status;

    DWORD     cJobs;

    DWORD     AveragePPM;

} PRINTER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of a new printer object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The following list identifies the members of the PRINTER_INFO_2 structure that can be set before this function is called.

Attributes
DefaultPriority
pComment
pDatatype
pDevMode
pLocation
pParameters
pPrintProcessor
Priority
pSecurityDescriptor
pSepFile
pShareName
StartTime
UntilTime

The following list identifies the members of the PRINTER_INFO_2 structure that are reserved for use by the GetPrinter function (that must not be set before calling AddPrinter).

Status
cJobs
AveragePPM

After an application creates a printer object with the AddPrinter function, it must use the PrinterProperties function to specify the correct settings for the printer driver associated with the printer object.

The AddPrinter function returns an error if a printer object with the same name already exists, unless that object is marked as pending deletion. In that case, the existing printer will not be deleted, and the AddPrinter creation parameters will be used to change the existing printer settings (as if the application had used the SetPrinter function).

See Also

»DeletePrinter«, »GetPrinter«, »PrinterProperties«, »SetPrinter«


  AddPrinterDriver

BOOL AddPrinterDriver(lpszName, dwLevel, lpbDriverInfo)
LPTSTR  lpszName;   /* address of server name */
DWORD  dwLevel;   /* printer info structure level */
LPBYTE  lpbDriverInfo;   /* address of structure */

The AddPrinterDriver function installs a local or remote printer driver and links the configuration, data, and driver files.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the driver should be installed. If the driver will be installed locally, this string should be NULL.

dwLevel

Specifies the version of the structure to which lpbDriverInfo points. This value must be 2.

lpbDriverInfo

Points to a DRIVER_INFO_2 structure. The DRIVER_INFO_2 structure has the following form:

typedef struct _DRIVER_INFO_2 { /* dri2 */

    DWORD  cVersion;

    LPTSTR pName;

    LPTSTR pEnvironment;

    LPTSTR pDriverPath;

    LPTSTR pDataFile;

    LPTSTR pConfigFile;

} DRIVER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If the pEnvironment member of the DRIVER_INFO_2 structure is NULL,  the current environment of the caller/client (not of the destination/server) is used.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before an application calls this function, all files required by the driver must be copied to the system's printer-driver directory. An application can retrieve the name of this directory by calling the GetPrinterDriverDirectory function.

An application can determine which printer drivers are currently installed by calling the EnumPrinterDrivers function.

See Also

»EnumPrinterDrivers«, »GetPrinterDriverDirectory«


  AddPrintProcessor

BOOL AddPrintProcessor(lpszServer, lpszEnvir, lpszPath, lpszPPName)
LPTSTR  lpszServer;   /* address of server name */
LPTSTR  lpszEnvir;   /* address of environment name */
LPTSTR  lpszPath;   /* address of path */
LPTSTR  lpszPPName;   /* address of print-processor name */

The AddPrintProcessor function installs a print processor on the specified server and adds the print-processor name to an internal list of supported print processors.

Parameters

lpszServer

Points to a null-terminated string that specifies the name of the server on which the print processor should be installed. If this pointer is NULL, the print processor is installed locally.

lpszEnvir

Points to a null-terminated string that specifies the environment. For example, "Windows NT x86" specifies Windows NT running on an Intel® 80386 or 80486 processor. If this string is NULL, the current environment of the caller/client (not of the destination/server) is used.

lpszPath

Points to a null-terminated string that specifies the name of the file that contains the print processor. This file must be in the system print-processor directory.

lpszPPName

Points to a null-terminated string that specifies the name of the print processor.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before calling this function, an application should verify that the file containing the print processor is stored in the system print-processor directory. An application can retrieve the name of the system print-processor directory by calling the GetPrintProcessorDirectory function.

An application can determine the name of existing print processors by calling the EnumPrintProcessors function.

See Also

»EnumPrintProcessors«, »GetPrintProcessorDirectory«


  AddPrintProvidor

BOOL AddPrintProvidor (pName, Level, pProvidorInfo)
LPTSTR  pName;   /* address of server name */
DWORD  Level;   /* providor info structure level */
LPBYTE  pProvidorInfo;   /* address of providor info structure */

The AddPrintProvidor function installs a local printer providor and links the configuration, data, and providor files. Future releases of Windows NT may allow remote installation of printer providors.

Parameters

pName

Points to a null-terminated string that specifies the name of the server on which the providor should be installed. For this release of Windows NT,  providors may only be installed locally, so this string should be NULL.

Level

Specifies the version of the structure to which pProvidorInfo points. This value must be 1.

pProvidorInfo

Points to a PROVIDOR_INFO_1 structure. The PROVIDOR_INFO_1 structure has the following form:

typedef struct _PROVIDOR_INFO_1 { /* pi1 */

    LPTSTR pName;

    LPTSTR pEnvironment ;

    LPTSTR pDLLName ;

} PROVIDOR_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before an application calls this function, all files required by the providor must be copied to the system32 directory.

A providor added by AddProvidor may be removed by calling DeleteProvidor.

See Also

»DeletePrintProvidor«


  AdjustTokenGroups

BOOL AdjustTokenGroups(hToken, fResetToDefault, ptgNew, cbtgPrevious,
ptgPrevious, pcbtgPreviousRequired)
HANDLE  hToken;   /* handle of token that contains groups */
BOOL  fResetToDefault;   /* flag for default settings */
PTOKEN_GROUPS  ptgNew;   /* address of new group information */
DWORD  cbtgPrevious;   /* size of buffer for previous information */
PTOKEN_GROUPS  ptgPrevious;   /* address of previous group information */
PDWORD  pcbtgPreviousRequired;   /* address of required buffer size */

The AdjustTokenGroups function adjusts groups in the specified access token. TOKEN_ADJUST_GROUPS access is required to enable or disable groups in an access token.

Parameters

hToken

Identifies the access token containing the groups to be modified.

fResetToDefault

Specifies whether the groups are to be set to their default enabled and disabled states. If this value is TRUE, the groups are set to their default states and the ptgNew parameter is ignored. If this value is FALSE, the groups are set according to the information pointed to by the ptgNew parameter.

ptgNew

Points to a TOKEN_GROUPS structure containing the groups whose states are to be set. If the fResetToDefault parameter is FALSE, the function sets each of the groups to the value of that group's SE_GROUP_ENABLED flag in the TOKEN_GROUPS structure. If fResetToDefault is TRUE, this parameter is ignored.

The TOKEN_GROUPS structure has the following form:

typedef struct _TOKEN_GROUPS { /* tg */

    DWORD GroupCount;

    SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];

} TOKEN_GROUPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbtgPrevious

Specifies the size, in bytes, of the buffer pointed to by the ptgPrevious parameter. If the ptgPrevious parameter is NULL, this parameter can be also.

ptgPrevious

Points to a buffer receiving a TOKEN_GROUPS structure containing the previous state of any groups the function modifies. The token must be open for TOKEN_QUERY access to use this parameter. This parameter can be NULL.

If a buffer is specified but it does not contain enough space to receive the complete list of modified groups, no group states are changed and the function fails. In this case, the function sets the variable pointed to by the pcbtgPreviousRequired parameter to the number of bytes required to hold the complete list of modified groups.

pcbtgPreviousRequired

Points to a variable set by the function that contains the actual number of bytes needed for the buffer pointed to by the ptgPrevious parameter. This parameter can be NULL and is ignored if ptgPrevious is NULL.

Return Value

This function always returns TRUE. To get extended error information, use the GetLastError function.

Comments

The information retrieved in the ptgPrevious parameter is formatted as a TOKEN_GROUPS structure. This means a pointer to the buffer can be passed as the ptgNew parameter in a subsequent call to the AdjustTokenGroups function, restoring the original state of the groups.

The ptgNew parameter can list groups to be changed that are not present in the access token. This does not affect the successful modification of the groups in the token.

Mandatory groups cannot be disabled. They are identified by the SE_GROUP_MANDATORY flag in the TOKEN_GROUPS structure. If an attempt is made to disable any mandatory groups, AdjustTokenGroups fails and leaves the state of all groups unchanged.

See Also

»AdjustTokenPrivileges«, »GetTokenInformation«, »OpenProcessToken«, »OpenThreadToken«, »SetTokenInformation«


  AdjustTokenPrivileges

BOOL AdjustTokenPrivileges(hToken, fDisableAll, ptpNew, cbtpPrevious, ptpPrevious,
pcbtpPreviousRequired)
HANDLE  hToken;   /* handle of token that contains privileges */
BOOL  fDisableAll;   /* flag for disabling all privileges */
PTOKEN_PRIVILEGES  ptpNew;   /* address of new privilege information */
DWORD  cbtpPrevious;   /* size of previous information buffer */
PTOKEN_PRIVILEGES  ptpPrevious;   /* address of previous information */
PDWORD  pcbtpPreviousRequired;   /* address of required buffer size */

The AdjustTokenPrivileges function adjusts privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access.

Parameters

hToken

Identifies the access token that contains the privileges to be modified.

fDisableAll

Specifies whether the function is to disable all of the token's privileges. If this value is TRUE, the privileges are disabled, and the ptpNew parameter is ignored. If it is FALSE, the function modifies privileges based on the information pointed to by the ptpNew parameter.

ptpNew

Points to a TOKEN_PRIVILEGES structure containing the privileges to be changed. If the fDisableAll parameter is FALSE, the function sets each of the token's privileges to the value of that privilege's SE_PRIVILEGE_ENABLED flag in the TOKEN_PRIVILEGES structure. If fDisableAll is TRUE, this parameter is ignored.

The TOKEN_PRIVILEGES  structure has the following form:

typedef struct _TOKEN_PRIVILEGES { /* tp */

    DWORD PrivilegeCount;

    LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];

} TOKEN_PRIVILEGES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbtpPrevious

Specifies the size, in bytes, of the buffer pointed to by the ptpPrevious parameter. If the ptpPrevious parameter is NULL, this parameter can be also.

ptpPrevious

Points to a buffer the function fills with a TOKEN_PRIVILEGES structure containing the previous state of any privileges the function modifies. The token must be open for TOKEN_QUERY access to use this parameter. This parameter can be NULL.

If a buffer is specified but does not contain enough space to receive the complete list of modified privileges, no privileges are changed and the function fails. In this case, the function sets the variable pointed to by the pcbtpPreviousRequired parameter to the number of bytes required to hold the complete list of modified privileges.

pcbtpPreviousRequired

Points to a variable receiving the actual number of bytes needed for the buffer pointed to by the ptpPrevious parameter. This parameter can be NULL and is ignored if ptpPrevious is NULL.

Return Value

This function always returns TRUE. To get extended error information, use the GetLastError function.

Comments

The information retrieved in the ptpPrevious parameter is formatted as a TOKEN_PRIVILEGES structure. This means that a pointer to the buffer can be passed as the ptpNew parameter in a subsequent call to the AdjustTokenPrivileges function, restoring the original state of the privileges.

The ptpNew parameter can list privileges to be changed that are not present in the access token. This does not affect the successful modification of the privileges in the token.

See Also

»AdjustTokenGroups«, »GetTokenInformation«, »OpenProcessToken«, »OpenThreadToken«, »SetTokenInformation«


  AdjustWindowRect

BOOL AdjustWindowRect(lprc, fdwStyle, fMenu)
LPRECT  lprc;   /* address of client-rectangle structure */
DWORD  fdwStyle;   /* window styles */
BOOL  fMenu;   /* menu-present flag */

The AdjustWindowRect function calculates the required size of the window rectangle based on the desired client-rectangle size. The window rectangle can then be passed to the CreateWindow function to create a window whose client area is the desired size.

Parameters

lprc

Points to a RECT structure that contains the coordinates of the client rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fdwStyle

Specifies the window styles of the window whose required size is to be calculated.

fMenu

Specifies whether the window has a menu.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A client rectangle is the smallest rectangle that completely encloses a client area. A window rectangle is the smallest rectangle that completely encloses a window.

The AdjustWindowRect function does not take window titles and borders into account when calculating the size of the client area. For window styles that include titles and borders, an application must add the title and border sizes after calling AdjustWindowRect. This function also does not take the extra rows into account when a menu bar wraps to two or more rows.

See Also

»AdjustWindowRectEx«, »CreateWindowEx«


  AdjustWindowRectEx

BOOL AdjustWindowRectEx(lprc, fdwStyle, fMenu, fdwExStyle)
LPRECT  lprc;   /* address of client-rectangle structure */
DWORD  fdwStyle;   /* window styles */
BOOL  fMenu;   /* menu-present flag */
DWORD  fdwExStyle;   /* extended style */

The AdjustWindowRectEx function calculates the required size of the rectangle of a window with extended style based on the desired client-rectangle size. The window rectangle can then be passed to the CreateWindowEx function to create a window whose client area is the desired size.

Parameters

lprc

Points to a RECT structure that contains the coordinates of the client rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fdwStyle

Specifies the window styles of the window whose required size is to be calculated.

fMenu

Specifies whether the window has a menu.

fdwExStyle

Specifies the extended style of the window whose required size is to be calculated.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A client rectangle is the smallest rectangle that completely encloses a client area. A window rectangle is the smallest rectangle that completely encloses a window.

The AdjustWindowRectEx function does not take window titles and borders into account when computing the size of the client area. For window styles that include titles and borders, an application must add the title and border sizes after calling AdjustWindowRectEx. This function also does not add extra space when a menu bar wraps to two or more rows.

See Also

»AdjustWindowRect«, »CreateWindowEx«


  AdvancedDocumentProperties

LONG AdvancedDocumentProperties(hwnd, hPrinter, lpszDevName, pdmOutput, pdmInput)
HWND  hwnd;   /* handle of dialog box's parent window */
HANDLE  hPrinter;   /* handle of printer object */
LPTSTR  lpszDevName;   /* address of driver name */
PDEVMODE  pdmOutput;   /* address of modified device mode structure */
PDEVMODE  pdmInput;   /* address of original device mode structure */

The AdvancedDocumentProperties function displays a printer-configuration dialog box for the given printer, allowing the user to configure that printer.

Parameters

hwnd

Identifies the parent window of the printer-configuration dialog box.

hPrinter

Identifies a printer object.

lpszDevName

Points to a null-terminated string specifying the name of the device for which a printer-configuration dialog box should be displayed.

pdmOutput

Points to a DEVMODE structure that will contain the configuration data specified by the user. An application can retrieve the number of bytes required for this structure by calling the AdvancedDocumentProperties function and setting pdmOutput to NULL.

typedef struct _devicemode {    /* dvmd */

    TCHAR  dmDeviceName[32];

    WORD   dmSpecVersion;

    WORD   dmDriverVersion;

    WORD   dmSize;

    WORD   dmDriverExtra;

    DWORD  dmFields;

    short  dmOrientation;

    short  dmPaperSize;

    short  dmPaperLength;

    short  dmPaperWidth;

    short  dmScale;

    short  dmCopies;

    short  dmDefaultSource;

    short  dmPrintQuality;

    short  dmColor;

    short  dmDuplex;

    short  dmYResolution;

    short  dmTTOption;

    short  dmCollate;

    TCHAR  dmFormName[32];

    WORD   dmUnusedPadding;

    USHORT dmBitsPerPel;

    DWORD  dmPelsWidth;

    DWORD  dmPelsHeight;

    DWORD  dmDisplayFlags;

    DWORD  dmDisplayFrequency;

} DEVMODE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

pdmInput

Points to a DEVMODE structure that contains the configuration data used to initialize the controls of the printer-configuration dialog box.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can obtain the hPrinter parameter by calling the OpenPrinter or AddPrinter function.

An application can obtain the lpszDevName parameter by calling the GetPrinter function and examining the pPrinterName member of the PRINTER_INFO_2 structure.

See Also

»GetPrinter«


  AllocateAndInitializeSid

BOOL AllocateAndInitializeSid(psia, cSubAuthorities, dwSubAuthority0,
dwSubAuthority1, dwSubAuthority2, dwSubAuthority3, dwSubAuthority4, dwSubAuthority5, dwSubAuthority6, dwSubAuthority7, lppsid)
PSID_IDENTIFIER_AUTHORITY  psia;   /* address of identifier authority */
BYTE  cSubAuthorities;   /* count of subauthorities */
DWORD  dwSubAuthority0;   /* subauthority 0 */
DWORD  dwSubAuthority1;   /* subauthority 1 */
DWORD  dwSubAuthority2;   /* subauthority 2 */
DWORD  dwSubAuthority3;   /* subauthority 3 */
DWORD  dwSubAuthority4;   /* subauthority 4 */
DWORD  dwSubAuthority5;   /* subauthority 5 */
DWORD  dwSubAuthority6;   /* subauthority 6 */
DWORD  dwSubAuthority7; * subauthority 7 */
PSID  *lppsid;   /* address of pointer to SID */

The AllocateAndInitializeSid function allocates and initializes a security identifier (SID) with up to eight subauthorities.

Parameters

psia

Points to an SID_IDENTIFIER_AUTHORITY structure, giving the top-level identifier authority value to set in the SID.

The SID_IDENTIFIER_AUTHORITY structure has the following form:

typedef struct _SID_IDENTIFIER_AUTHORITY { /* sia */

    BYTE Value[6];

} SID_IDENTIFIER_AUTHORITY ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cSubAuthorities

Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 through 8.

For example, a value of 3 indicates that the subauthority values specified by the dwSubAuthority0, dwSubAuthority1, and dwSubAuthority2 parameters have meaningful values and to ignore the remainder.

dwSubAuthority0 through dwSubAuthority7

Specify subauthority values to place in the SID.

lppsid

Points to a variable that receives the address of the allocated and initialized SID structure.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An SID allocated with this function must be freed by using the FreeSid function.

See Also

»FreeSid«, »GetSidIdentifierAuthority«, »InitializeSid«


  AllocateLocallyUniqueId

BOOL AllocateLocallyUniqueId(pluid)
PLUID  pluid;   /* address of locally unique identifier */

The AllocateLocallyUniqueId function allocates a locally unique identifier (LUID).

Parameters

pluid

Points to a buffer that receives the allocated LUID.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An LUID is unique only within a single session. The same LUID value can be used on different computers or on the same computer after it has been restarted.

See Also

»LookupPrivilegeValue«


  AllocConsole

BOOL AllocConsole(VOID)

The AllocConsole function allocates a new console for the calling process.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A process can only be associated with one console, so AllocConsole fails if the calling process already has a console. A process can use the FreeConsole function to detach itself from its current console, and then it can call AllocConsole to create a new console. If the calling process creates a child process, the child inherits the new console.

AllocConsole also sets up standard input, standard output, and standard error handles for the new console. The standard input handle is a handle to the console's input buffer, and the standard output and standard error handles are handles to the console's screen buffer. To retrieve these handles, use the GetStdHandle function.

This function is primarily used by graphics applications to create a console window. Graphics applications are initialized without a console. Console applications are normally initialized with a console, unless they are created as detached processes (by calling the CreateProcess function with the DETACHED_PROCESS flag specified).

See Also

»CreateProcess«, »FreeConsole«, »GetStdHandle«


  AllocDStoCSAlias

The AllocDStoCSAlias function is obsolete.


  AllocResource

The AllocResource function has been deleted. For Win32 applications, use the LoadResource, LockResource, and FindResource functions.


  AllocSelector

The AllocSelector function has been deleted.


  AngleArc

BOOL AngleArc(hdc, X, Y, dwRadius, eStartAngle, eSweepAngle)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of circle's center */
int  Y;   /* y-coordinate of circle's center */
DWORD  dwRadius;   /* circle's radius */
FLOAT  eStartAngle;   /* arc's start angle */
FLOAT  eSweepAngle;   /* arc's sweep angle */

The AngleArc function draws a line segment and an arc. The line segment is drawn from the current position to the beginning of the arc. The arc is drawn along the perimeter of a circle with the given radius and center. The length of the arc is defined by the given start and sweep angles.

Parameters

hdc

Identifies a device context.

X

Specifies the logical x-coordinate of the center of the circle.

Y

Specifies the logical y-coordinate of the center of the circle.

dwRadius

Specifies the radius, in logical units, of the circle in logical units. This value must be positive.

eStartAngle

Specifies the start angle in degrees relative to the x-axis.

eSweepAngle

Specifies the sweep angle in degrees relative to the starting angle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The AngleArc function moves the current position to the ending point of the arc.

The arc drawn by this function may appear to be elliptical, depending on the current transformation and mapping mode. Before drawing the arc, this function draws the line segment from the current position to the beginning of the arc.

The arc is drawn by constructing an imaginary circle around the specified center point with the specified radius. The starting point of the arc is determined by measuring counterclockwise from the x-axis of the circle by the number of degrees in the start angle. The ending point is similarly located by measuring counterclockwise from the starting point by the number of degrees in the sweep angle.

If the sweep angle is greater than 360 degrees the arc is swept multiple times.

This function draws lines by using the current pen. The figure is not filled.

See Also

»Arc«, »ArcTo«, »MoveToEx«,


  AnimatePalette

BOOL AnimatePalette(hpal, iStartIndex, cEntries, ppe)
HPALETTE  hpal;   /* handle of logical color palette */
UINT  iStartIndex;   /* first entry in logical palette */
UINT  cEntries;   /* count of entries in logical palette */
CONST PALETTEENTRY  *ppe;   /* address of first replacement */

The AnimatePalette function replaces entries in the given logical palette.

Parameters

hpal

Identifies the logical palette.

iStartIndex

Specifies the first logical palette entry to be replaced.

cEntries

Specifies the number of entries to be replaced.

ppe

Points to the first member of an array of PALETTEENTRY structures used to replace the current entries. The PALETTEENTRY structure has the following form:

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

The AnimatePalette function only changes entries with the PC_RESERVED flag set in the corresponding palPalEntry member of the LOGPALETTE structure.

If the given palette is associated with the active window, the colors in the palette are replaced immediately.

See Also

»CreatePalette«, »GetDeviceCaps«


  AnsiLower

The AnsiLower function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharLower function.


  AnsiLowerBuff

The AnsiLowerBuff function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharLowerBuff function.


  AnsiNext

The AnsiNext function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharNext function.


  AnsiPrev

The AnsiPrev function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharPrev function.


  AnsiToOem

The AnsiToOem function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharToOem function.


  AnsiToOemBuff

The AnsiToOemBuff function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharToOemBuff function.


  AnsiUpper

The AnsiUpper function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharUpper function.


  AnsiUpperBuff

The AnsiUpperBuff function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the CharUpperBuff function.


  AnyPopup

BOOL AnyPopup(VOID)

The AnyPopup function indicates whether an unowned, visible, top-level pop-up, or overlapped window exists on the screen. The function searches the entire Windows screen, not just the calling application's client area.

Parameters

This function has no parameters.

Return Value

If a pop-up window exists, the return value is TRUE even if the pop-up window is completely covered by other windows. Otherwise, it is FALSE.

Comments

The AnyPopup function is a Windows version 1.x function and is retained for compatibility purposes. It is generally not useful.

This function does not detect unowned pop-up windows or windows that do not have the WS_VISIBLE style bit set.

See Also

»GetLastActivePopup«, »ShowOwnedPopups«


  AppendMenu

BOOL AppendMenu(hmenu, fuFlags, idNewItem, lpszNewItem)
HMENU  hmenu;   /* handle of menu */
INT  fuFlags;   /* menu item flags */
UINT  idNewItem;   /* menu item identifier or pop-up menu handle */
LPCTSTR  lpszNewItem;   /* menu item content */

The AppendMenu function appends a new item to the end of the given menu. An application can use this function to specify the content, appearance, and behavior of the menu item.

Parameters

hmenu

Identifies the menu to be changed.

fuFlags

Specifies flags to control the appearance and behavior of the new menu item. This parameter can be a combination of the values listed in the following Comments section.

idNewItem

Specifies either the identifier of the new menu item or, if the fuFlags parameter is set to MF_POPUP, the handle of the pop-up menu.

lpszNewItem

Specifies the content of the new menu item. The interpretation of lpszNewItem depends on whether the fuFlags parameter includes the MF_BITMAP, MF_OWNERDRAW, or MF_STRING flag, as follows:

Value	Meaning
MF_BITMAP	Contains a bitmap handle.
MF_OWNERDRAW	Contains a 32-bit value supplied by the application that can be used to maintain additional data related to the menu item. The value is in the itemData member of the structure pointed to by the lparam parameter of the WM_MEASURE or WM_DRAWITEM message sent when the menu is created its appearance or updated.
MF_STRING	Contains a pointer to a null-terminated string.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The application must call the DrawMenuBar function whenever a menu changes, whether or not the menu is in a displayed window.

Following are the flags that must be set in the fuFlags parameter:

Value	Meaning
MF_BITMAP	Uses a bitmap as the item. The lpszNewItem parameter contains the handle of the bitmap.
MF_CHECKED	Places a check mark next to the item. If the application provides check mark bitmaps (see the »SetMenuItemBitmaps« function), this flag displays the check mark bitmap next to the menu item.
MF_DISABLED	Disables the menu item so that it cannot be selected, but the flag does not gray it.
MF_ENABLED	Enables the menu item so that it can be selected and restores it from its grayed state.
MF_GRAYED	Disables the menu item and grays it so it cannot be selected.
MF_MENUBARBREAK	Functions the same as the MF_MENUBREAK flag except for pop-up menus where the new column is separated from the old column by a vertical line.
MF_MENUBREAK	Places the item on a new line (for menu bars) or in a new column (for pop-up menus) without separating columns.
MF_OWNERDRAW	Specifies that the item is an owner-drawn item. Before the menu is displayed for the first time, the window that owns the menu receives a WM_MEASUREITEM message to retrieve the width and height of the menu item. The WM_DRAWITEM message is then sent to the window procedure of the owner window whenever the appearance of the menu item must be updated.
MF_POPUP	Specifies that the menu item is a pop-up item; that is, selecting it activates a pop-up menu. The idNewItem parameter specifies the handle of the pop-up menu. This flag is used to add a pop-up item to a menu bar or to a pop-up menu.
MF_SEPARATOR	Draws a horizontal dividing line. This flag is only used in a pop-up menu. The line cannot be grayed, disabled, or highlighted. The lpszNewItem and idNewItem parameters are ignored.
MF_STRING	Specifies that the menu item is a text string; the lpszNewItem parameter points to the string.
MF_UNCHECKED	Does not place a check mark next to the item (default). If the application supplies check mark bitmaps (see the »SetMenuItemBitmaps« function), this flag displays the unchecked bitmap next to the menu item.
The following list shows groups of flags that cannot be used together:

•	MF_DISABLED, MF_ENABLED, and MF_GRAYED

•	MF_BITMAP, MF_STRING, and MF_OWNERDRAW

•	MF_MENUBARBREAK and MF_MENUBREAK

•	MF_CHECKED and MF_UNCHECKED

See Also

»CreateMenu«, »DeleteMenu«, »DestroyMenu«, »DrawMenuBar«, »InsertMenu«, »ModifyMenu«, »RemoveMenu«, »SetMenuItemBitmaps«


  Arc

BOOL Arc(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect, nXStartArc, nYStartArc,
nXEndArc, nYEndArc)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coord. of upper-left corner of bounding rectangle */
int  nTopRect;   /* y-coord. of upper-left corner of bounding rectangle */
int  nRightRect;   /* x-coord. of lower-right corner of bounding rectangle */
int  nBottomRect;   /* y-coord. of lower-right corner of bounding rectangle */
int  nXStartArc;   /* first radial ending point */
int  nYStartArc;   /* first radial ending point */
int  nXEndArc;   /* second radial ending point */
int  nYEndArc;   /* second radial ending point */

The Arc function draws an elliptical arc.

Parameters

hdc

Identifies the device context where drawing takes place.

nLeftRect

Specifies the logical x-coordinate of the upper left corner of the bounding rectangle.

nTopRect

Specifies the logical y-coordinate of the upper left corner of the bounding rectangle.

nRightRect

Specifies the logical x-coordinate of the lower right corner of the bounding rectangle.

nBottomRect

Specifies the logical y-coordinate of the lower right corner of the bounding rectangle.

nXStartArc

Specifies the logical x-coordinate of the ending point of the radial line defining the starting point of the arc.

nYStartArc

Specifies the logical y-coordinate of the ending point of the radial line defining the starting point of the arc.

nXEndArc

Specifies the logical x-coordinate of the ending point of the radial line defining the ending point of the arc.

nYEndArc

Specifies the logical y-coordinate of the ending point of the radial line defining the ending point of the arc.

Return Value

If the arc is drawn, the return value is TRUE; otherwise, it is FALSE.

Comments

The points (nLeftRect, nTopRect) and (nRightRect, nBottomRect) specify the bounding rectangle. An ellipse formed by the given bounding rectangle defines the curve of the arc. The arc extends counterclockwise from the point where it intersects the radial from the center of the bounding rectangle to (nXStartArc, nYStartArc). The arc ends where it intersects the radial from the center of the bounding rectangle to (nXEndArc, nYEndArc). If the starting point and ending point are the same, a complete ellipse is drawn.

The arc is drawn using the current pen; it is not filled.

The current position is neither used nor updated by this function.

See Also

»AngleArc«, »ArcTo«, »Chord«, »Ellipse«, »Pie«, »SetArcDirection«


  ArcTo

BOOL ArcTo(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect, nXRadial1,
nYRadial1, nXRadial2, nYRadial2)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coordinate of upper-left corner of bounding rectangle */
int  nTopRect;   /* y-coordinate of upper-left corner of bounding rectangle */
int  nRightRect;   /* x-coordinate of lower-right corner of bounding rectangle */
int  nBottomRect;   /* y-coordinate of lower-right corner of bounding rectangle */
int  nXRadial1;   /* first radial ending point */
int  nYRadial1;   /* first radial ending point */
int  nXRadial2;   /* second radial ending point */
int  nYRadial2;   /* second radial ending point */

The ArcTo function draws an elliptical arc.

Parameters

hdc

Identifies the device context where drawing takes place.

nLeftRect

Specifies the logical x-coordinate of the upper left corner of the bounding rectangle.

nTopRect

Specifies the logical y-coordinate of the upper left corner of the bounding rectangle.

nRightRect

Specifies the logical x-coordinate of the lower right corner of the bounding rectangle.

nBottomRect

Specifies the logical y-coordinate of the lower right corner of the bounding rectangle.

nXRadial1

Specifies the logical x-coordinate of the endpoint of the radial defining the starting point of the arc.

nYRadial1

Specifies the logical y-coordinate of the endpoint of the radial defining the starting point of the arc.

nXRadial2

Specifies the logical x-coordinate of the endpoint of the radial defining the ending point of the arc.

nYRadial2

Specifies the logical y-coordinate of the endpoint of the radial defining the ending point of the arc.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function is similar to Arc, except that the current position is updated.

The points (nLeftRect, nTopRect) and (nRightRect, nBottomRect) specify the bounding rectangle. An ellipse formed by the given bounding rectangle defines the curve of the arc. The arc extends counterclockwise, default arc direction, from the point where it intersects the radial line from the center of the bounding rectangle to (nXRadial1, nYRadial1). The arc ends where it intersects the radial line from the center of the bounding rectangle to (nXRadial2, nYRadial2). If the starting point and ending point are the same, a complete ellipse is drawn.

A line is drawn from the current position to the starting point of the arc. If no error occurs, the current position is set to the ending point of the arc.

The arc is drawn using the current pen; it is not filled.

See Also

»AngleArc«, »Arc«, »SetArcDirection«


  AreAllAccessesGranted

BOOL AreAllAccessesGranted(dwGrantedAccess, dwDesiredAccess)
DWORD  dwGrantedAccess;   /* access mask for granted access rights */
DWORD  dwDesiredAccess;   /* access mask for requested access rights */

The AreAllAccessesGranted function checks whether all the access rights in an access mask to be requested are present in a granted access mask.

Parameters

dwGrantedAccess

Specifies the granted access mask.

dwDesiredAccess

Specifies the access mask to be requested. This mask must have been mapped from generic to specific and standard access rights, usually by calling the MapGenericMask function.

Return Value

If all the requested access rights have been granted, the return value is TRUE; otherwise, it is FALSE.

Comments

The AreAllAccessesGranted function is commonly used by a server application to check the access rights of a client attempting to gain access to an object. When the bits set in the dwDesiredAccess parameter match the bits set in the dwGrantedAccess parameter, all requested rights have been granted.

See Also

»AccessCheck«, »AreAnyAccessesGranted«, »MapGenericMask«


  AreAnyAccessesGranted

BOOL AreAnyAccessesGranted(dwGrantedAccess, dwDesiredAccess)
DWORD  dwGrantedAccess;   /* access mask for granted access rights */
DWORD  dwDesiredAccess;   /* access mask for access rights requested */

The AreAnyAccessesGranted function tests whether any of a requested set of access rights are granted by a granted access mask.

Parameters

dwGrantedAccess

Specifies the granted access mask.

dwDesiredAccess

Specifies the access mask to be requested. This mask must have been mapped from generic to specific and standard access rights, usually by calling the MapGenericMask function.

Return Value

If any of the requested access rights have been granted, the return value is TRUE; otherwise, it is FALSE.

Comments

The AreAnyAccessesGranted function is often used by a server application to check the access rights of a client attempting to gain access to an object. When any of the bits set in the dwDesiredAccess parameter match the bits set in the dwGrantedAccess parameter, at least one of the requested access rights has been granted.

See Also

»AccessCheck«, »AreAllAccessesGranted«, »MapGenericMask«


  ArrangeIconicWindows

UINT ArrangeIconicWindows(hwnd)
HWND  hwnd;   /* handle of parent window */

The ArrangeIconicWindows function arranges all the minimized (iconic) child windows of the given parent window.

Parameters

hwnd

Identifies the parent window.

Return Value

If the function succeeds, the return value is the height of one row of icons; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

An application that maintains its own minimized child windows can use ArrangeIconicWindows to arrange icons in a parent window. This function can also arrange icons on the desktop. To retrieve the window handle of the desktop window, use the GetDesktopWindow function.

An application sends the WM_MDIICONARRANGE message to the multiple document interface (MDI) client window to prompt the client window to arrange its minimized MDI child windows.

See Also

»CloseWindow«, »GetDesktopWindow«


  AttachThreadInput

BOOL AttachThreadInput(idAttach, idAttachTo, fAttach)
DWORD  idAttach;   /* thread to attach */
DWORD  idAttachTo;   /* thread to attach to */
BOOL  fAttach;   /* attach or detach */

Parameters

idAttach

Specifies the identifier of the thread to be attached to another thread.

idAttachTo

Specifies the identifier of the thread to be attached to.

fAttach

Specifies whether to attach or detach the threads. If this parameter is TRUE, the two threads are attached. If the parameter FALSE, the threads are detached.

Return Value

If the function succeeds, the return value is TRUE. Otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Normally, windows created in different threads process input independently of each other. That is, they have their own input states (focus, active, capture windows, key-state, queue status, and so on), and they are not synchronized with the input processing of other threads. By using this function, a thread can attach its input processing to another thread. This also allows a thread to share its input states, so they can call the SetFocus function to set the keyboard focus to a window of a different thread; this also allows threads to get key state information. These capabilities are not normally possible.

See Also

»GetCurrentThreadId«, »GetWindowThreadProcessId«


  auxGetDevCaps

MMRESULT auxGetDevCaps(IDAuxDev, lpauxc, cbAuxc)
UINT  IDAuxDev;   /* identifier of aux device to query */
LPAUXCAPS  lpauxc;   /* address of AUXCAPS structure for results */
UINT  cbAuxc;   /* size of AUXCAPS structure, in bytes */

The auxGetDevCaps function queries a specified auxiliary output device to determine its capabilities.

Parameters

IDAuxDev

Identifies the auxiliary output device to be queried. Specify a valid device identifier. The device identifier varies from zero to one less than the number of devices present. Use auxGetNumDevs to determine the number of auxiliary devices present in the system. The special value AUX_MAPPER also be used to specify an auxiliary audo mapper. If AUX_MAPPER is used, the function will return an error if no auxiliary audio mapper is installed.

lpauxc

Points to an AUXCAPS structure that receives information about the capabilities of the device. The AUXCAPS structure has the following format:

typedef struct auxcaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    WORD  wTechnology;

    DWORD  dwSupport;

} AUXCAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbAuxc

Specifies the size, in bytes, of the AUXCAPS structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error number. Following are possible error returns.

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_NODRIVER	The driver failed to install.
Comments

The device identifier specified by IDAuxDev varies from zero to one less than the number of devices present. AUX_MAPPER may also be used. Use the auxGetNumDevs function to determine the number of auxiliary devices present in the system.

See Also

»auxGetNumDevs«


  auxGetNumDevs

UINT auxGetNumDevs(VOID)

The auxGetNumDevs function retrieves the number of auxiliary output devices present in the system.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of auxiliary output devices present in the system.

See Also

»auxGetDevCaps«


  auxGetVolume

MMRESULT auxGetVolume(IDAuxDev, lpdwVolume)
UINT  IDAuxDev;   /* identifier of aux device to query */
LPDWORD  lpdwVolume;   /* address of buffer for volume settings */

The auxGetVolume function returns the current volume setting of an auxiliary output device.

Parameters

IDAuxDev

Identifies the auxiliary output device to be queried.

lpdwVolume

Points to a variable that receives the current volume setting. The low-order word of this variable contains the left-channel volume setting, and the high-order word contains the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.

If a device does not support both left and right volume control, the low-order word of the specified variable contains the volume level.

The full 16-bit settings set with the auxSetVolume function are returned, regardless of whether the device supports the full 16 bits of volume-level control.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_NODRIVER	The driver failed to install.
Comments

Not all devices support volume control. To determine whether the device supports volume control, use the AUXCAPS_VOLUME flag to test the dwSupport member of the AUXCAPS structure (filled by the auxGetDevCaps function).

To determine whether the device supports volume control on both the left and right channels, use the AUXCAPS_LRVOLUME flag to test the dwSupport member of the AUXCAPS structure (filled by auxGetDevCaps).

See Also

»auxGetDevCaps«, »auxSetVolume«


  auxOutMessage

MMRESULT auxOutMessage(IDAuxDev, uMsg, dwParam1, dwParam2)
UINT  IDAuxDev;   /* identifier of aux device to send message to */
UINT  uMsg;   /* message */
DWORD  dwParam1;   /* message-specific parameter */
DWORD  dwParam2;   /* message-specific parameter */

The auxOutMessage function sends a message to an auxiliary output device.

Parameters

IDAuxDev

Identifies the auxiliary output device to send the message to. Specify a valid device identifier. The device identifier varies from zero to one less than the number of devices present. Use auxGetNumDevs to determine the number of auxiliary devices present in the system. The special value AUX_MAPPER can also be used to specify an auxiliary audio mapper. If AUX_MAPPER is used, the function will return an error if no auxiliary audio mapper is installed.

uMsg

The message to send.

dwParam1

Parameter.

dwParam2

Parameter.

Return Value

If the function succeeds, the return value is the value returned by the device driver.

See Also

»auxGetNumDevs«


  auxSetVolume

MMRESULT auxSetVolume(IDAuxDev, dwVolume)
UINT  IDAuxDev;   /* identifier of aux device to set volume for */
DWORD  dwVolume;   /* new volume setting */

The auxSetVolume function sets the volume in an auxiliary output device.

Parameters

IDAuxDev

Identifies the auxiliary output device to set the volume for. Device-identifiers are determined implicitly from the number of devices present in the system. Device identifier values range from zero to one less than the number of devices present. Use auxGetNumDevs to determine the number of auxiliary devices in the system.

dwVolume

Specifies the new volume setting. The low-order word specifies the left-channel volume setting, and the high-order word specifies the right-channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.

If a device does not support both left and right volume control, the low-order word of the dwVolume parameter specifies the volume level, and the high-order word is ignored.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_NODRIVER	The driver failed to install.
Comments

Not all devices support volume control. To determine whether the device supports volume control, use the AUXCAPS_VOLUME flag to test the dwSupport member of the AUXCAPS structure (filled by the auxGetDevCaps function).

To determine whether the device supports volume control on both the left and right channels, use the AUXCAPS_LRVOLUME flag to test the dwSupport member of the AUXCAPS structure (filled by auxGetDevCaps).

Most devices do not support the full 16 bits of volume-level control and will use only the high-order bits of the requested volume setting. For example, for a device that supports 4 bits of volume control, requested volume level values of 0x4000, 0x4fff, and 0x43be will all produce the same physical volume setting, 0x4000. The auxGetVolume function will return the full 16-bit setting set with the auxSetVolume function.

Volume settings are interpreted logarithmically. This means the perceived volume increase is the same from volume level 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

See Also

»auxGetDevCaps«, »auxGetVolume«


  BackupEventLog

BOOL BackupEventLog(hEventLog, lpszBackupFileName)
HANDLE  hEventLog;   /* handle to event log */
LPTSTR  lpszBackupFileName;   /* name of backup file */

The BackupEventLog function saves the given event log to a backup file. The function does not clear the event log.

Parameters

hEventLog

Identifies the open event log. This handle is returned by the OpenEventLog or OpenBackupEventLog function.

lpszBackupFileName

Points to a null-terminated string that names the backup file. The backup filename may contain a server name to save the backup file on a remote server.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the backup filename specifies a remote server, the event log handle must identify a log on the local computer. You cannot back up an event logfile from a remote server to a file on a remote server (even if the backup file and the original log are on the same server).

See Also

»OpenBackupEventLog«


  BackupRead

BOOL BackupRead(hFileHandle, lpBuffer, dwNumberOfBytesToRead,
lpdwNumberOfBytesRead, bAbort, bProcessSecurity, lpContext)
HANDLE  hFileHandle;   /* handle of open file */
LPBYTE  lpBuffer;   /* address of buffer to read to */
DWORD  dwNumberOfBytesToRead;   /* number of bytes to read */
LPDWORD  lpdwNumberOfBytesRead;   /* address of no. of bytes read */
BOOL  bAbort;   /* termination type */
BOOL  bProcessSecurity;   /* process security flag */
LPCONTEXT  *lpContext;   /* internal context information */

The BackupRead function reads into a buffer the data associated with a file.

Parameters

hFileHandle

Identifies the file or directory being backed up. This handle is created by using the CreateFile function.

lpBuffer

Points to the buffer where the data stream is to be placed.

dwNumberOfBytesToRead

Specifies the length of the buffer. The buffer size must be greater than the size of a WIN32_STREAM_ID structure. This structure has the following form:

struct WIN32_STREAM_ID {

    DWORD dwStreamId;

    DWORD dwStreamAttributes;

    LARGE_INTEGER Size;

    DWORD dwStreamNameSize;

    WCHAR  cStreamName[ ] ;

}

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpdwNumberOfBytesRead

Points to a doubleword that, when the function returns, contains the number of bytes read. If this parameter is zero and the return value is TRUE, all the data associated with the file handle has been read.

bAbort

Indicates whether BackupRead terminated abnormally. If this value is TRUE, the operation terminates abnormally and all buffers were deallocated.

bProcessSecurity

Indicates whether the access-control list (ACL) data for the opened object will be backed up. If this value is TRUE, the ACL data will be backed up.

lpContext

Points to an internal CONTEXT structure used only by this function. Storage for this structure is allocated by BackupRead. This parameter must point to a NULL value before the first call to the file or directory to be read. When the function returns, this parameter contains reserved information. This parameter must not be changed between calls to BackupRead. To deallocate the storage for this information, your application should call BackupRead with the bAbort parameter set to TRUE before exiting.

Return Value

If the transfer of data to the buffer succeeds, the return value is TRUE; otherwise it is FALSE, indicating that an I/O error occurred. To get extended error information, use the GetLastError function.

Comments

BackupRead processes all of the data pertaining to an opened object as a series of discrete byte streams. Each stream is preceded by a 32-bit aligned WIN32_STREAM_ID structure.

Streams must be processed in the same order in which they were written to the tape, to enable applications to compare the data backed up against the data on the source device. The data returned by BackupRead is to be used only as input to the BackupWrite function. This data is returned as one large data stream divided into substreams. The substreams are separated by WIN32_STREAM_ID headers.

If an error occurs while BackupRead is reading, the calling process can skip the bad data by calling the BackupSeek function.

See Also

»BackupWrite«, »BackupSeek«


  BackupSeek

BOOL BackupSeek(hFile, dwLowBytesToSeek, dwHighBytesToSeek,
lpdwLowByteSeeked, lpdwHighByteSeeked, lpContext)
HANDLE  hFile;   /* handle of open file */
DWORD  dwLowBytesToSeek;   /* low-order 32 bits of number of bytes */
DWORD  dwHighBytesToSeek;   /* high-order 32 bits of number of bytes */
LPDWORD  lpdwLowBytesSeeked;   /* address of no. of bytes func. seeks */
LPDWORD  lpdwHighBytesSeeked;   /* address of no. of bytes func. seeks */
LPCONTEXT *  lpContext;   /* internal context information */

The BackupSeek function seeks forward in a data stream initially accessed with the BackupRead or BackupWrite function.

Parameters

hFile

Identifies the file or directory being backed up. This handle is created by using the CreateFile function.

dwLowBytesToSeek

Specifies the low-order 32 bits of the number of bytes to seek.

dwHighBytesToSeek

Specifies the high-order 32 bits of the number of bytes to seek.

lpdwLowBytesSeeked

Points to a doubleword that, when the function returns, contains the low-order 32 bits of the number of bytes the function actually seeks.

lpdwHighBytesSeeked

Points to a doubleword that, when the function returns, contains the high-order 32 bits of the number of bytes the function actually seeks.

lpContext

Address of a pointer to an internal CONTEXT data structure used by the function. This must be the same CONTEXT data structure that was initialized by the BackupRead function. An application must not touch the contents of this structure.

Return Value

If the function could seek the requested amount, the function returns TRUE. Otherwise, it is FALSE.

Comments

Applications use this function to skip portions of a data stream that cause errors. This function does not seek across stream headers. If an application attempts to seek past the end of a substream, the function fails, the lpdwLowBytesSeeked and lpdwHighBytesSeeked parameters indicate the actual number of bytes the function seeks, and the file position is placed at the start of the next stream header.

See Also

»BackupRead«, »BackupWrite«


  BackupWrite

BOOL BackupWrite(hFileHandle, lpBuffer, dwNumberOfBytesToWrite,
lpdwNumberOfBytesWritten, bAbort, bProcessSecurity, lpContext)
HANDLE  hFileHandle;   /* handle of open file */
LPBYTE  lpBuffer;   /* address of buffer to write */
DWORD  dwNumberOfBytesToWrite;   /* number of bytes to write */
LPDWORD  lpdwNumberOfBytesWritten;   /* address of no. of bytes written */
BOOL  bAbort;   /* termination type */
BOOL  bProcessSecurity;   /* process security */
LPCONTEXT  *lpContext;   /* internal context information */

The BackupWrite function transfers data from a buffer to the specified file or directory. The data must be divided into substreams separated by WIN32_STREAM_ID structures.

Parameters

hFileHandle

Identifies the handle of the file or directory being restored. This handle is created by using the CreateFile function.

lpBuffer

Points to the buffer that contains the data stream.

dwNumberOfBytesToWrite

Specifies the length of the buffer. The buffer size must be greater than the size of a WIN32_STREAM_ID structure.

This structure has the following form:

struct WIN32_STREAM_ID {

    DWORD dwStreamId;

    DWORD dwStreamAttributes;

    LARGE_INTEGER Size;

    DWORD dwStreamNameSize;

    WCHAR  cStreamName[ ] ;

}

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpNumberOfBytesWritten

Points to a doubleword that, when the function returns, contains the number of bytes written.

bAbort

Indicates whether BackupWrite terminated abnormally. If this value is TRUE, the operation terminated abnormally and all buffers were deallocated.

bProcessSecurity

Indicates whether the access-control list (ACL) data for the opened object will be restored. If this value is TRUE, the ACL data will be restored.

lpContext

Points to an internal CONTEXT structure used only by this function. Storage for this structure is allocated by the BackupRead function. This parameter must point to a NULL value before the first call to the file or directory to be written. When the function returns, this parameter contains reserved information. This parameter must not be changed between calls to BackupWrite. To deallocate the storage for this information, your application should call BackupWrite with the bAbort parameter set to TRUE before exiting.

For a description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE, indicating that an I/O error occurred. To get extended error information, use the GetLastError function.

Comments

The BACKUP_LINK stream type enables you to restore files with hard links. The data returned by BackupRead is to be used only as input to BackupWrite.

See Also

»BackupRead«, »BackupSeek«


  Beep

BOOL Beep(dwFreq, dwDuration)
DWORD  dwFreq;   /* sound frequency, in hertz */
DWORD  dwDuration;   /* sound duration, in milliseconds */

The Beep function generates simple tones on the speaker.

Parameters

dwFreq

Specifies the frequency, in hertz, of the sound. This parameter must be in the range 37 through 32,767 (0x25 through 0x7FFF).

dwDuration

Specifies the duration, in milliseconds, of the sound.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function returns immediately to the application and does not wait for the sound to stop. If the application makes another call to Beep while a previous sound is still in progress, the previous sound stops and the new sound starts.


  BeginDeferWindowPos

HDWP BeginDeferWindowPos(cWindows)
int  cWindows;   /* number of windows */

The BeginDeferWindowPos function allocates memory for a multiple-window-position structure and returns the handle of the structure.

Parameters

cWindows

Specifies the initial number of windows for which to store position information. The DeferWindowPos function increases the size of the structure, if necessary.

Return Value

If the function succeeds, the return value identifies the multiple-window-position structure. If insufficient system resources are available to allocate the structure, the return value is NULL.

Comments

The multiple-window-position structure is an internal structure; an application cannot access it directly.

The DeferWindowPos function fills the multiple-window-position structure with information about the target position for one or more windows about to be moved. The EndDeferWindowPos function accepts the handle of this structure and repositions the windows by using the information stored in the structure.

If any of the windows in the multiple-window-position structure have the SWP_HIDEWINDOW flag set, none of the windows repositioned.

If Windows must increase the size of the multiple-window-position structure beyond the initial size specified by the cWindows parameter but cannot allocate enough memory to do so, Windows fails the entire window positioning sequence (BeginDeferWindowPos, DeferWindowPos, and EndDeferWindowPos). By specifying the maximum size needed, an application can detect and handle failure early in the process.

See Also

»DeferWindowPos«, »EndDeferWindowPos«, »SetWindowPos«


  BeginPaint

HDC BeginPaint(hwnd, lpps)
HWND  hwnd;   /* handle of window */
LPPAINTSTRUCT  lpps;   /* address of structure for paint information */

The BeginPaint function prepares the given window for painting and fills a PAINTSTRUCT structure with information about the painting.

Parameters

hwnd

Identifies the window to be repainted.

lpps

Points to the PAINTSTRUCT structure that will receive painting information. The PAINTSTRUCT structure has the following form:

typedef struct tagPAINTSTRUCT { /* ps */

    HDC  hdc;

    BOOL fErase;

    RECT rcPaint;

    BOOL fRestore;

    BOOL fIncUpdate;

    BYTE rgbReserved[32];

} PAINTSTRUCT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of a display device context (DC) for the given window. Otherwise, it is NULL, indicating that no display DC is available.

Comments

BeginPaint automatically sets the clipping region of the DC to exclude any area outside the update region. The update region is set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, scrolling, or any other operation that affects the client area. If the update region is marked for erasing, BeginPaint sends a WM_ERASEBKGND message to the window.

An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to the EndPaint function.

If the caret is in the area to be painted, BeginPaint automatically hides the caret to prevent it from being erased.

If the window's class has a background brush, BeginPaint uses that brush to erase the background of the update region before returning.

See Also

»EndPaint«, »InvalidateRect«, »InvalidateRgn«, »ValidateRect«, »ValidateRgn«


  BeginPath

BOOL BeginPath(hdc)
HDC  hdc;   /* handle of device context */

The BeginPath function opens a path bracket in the given device context (DC).

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE. To obtain extended error information, use the GetLastError function.

Comments

After a path bracket is open, an application can begin calling GDI drawing functions to define the points that lie in the path. An application can close an open path bracket by calling the EndPath function.

When an application calls the BeginPath function for a DC, any previous paths are discarded from that DC.

The following drawing functions define points in a path:

AngleArc	LineTo	Polyline
Arc	MoveToEx	PolylineTo
ArcTo	Pie	PolyPolygon
Chord	PolyBezier	PolyPolyline
CloseFigure	PolyBezierTo	Rectangle
Ellipse	PolyDraw	RoundRect
ExtTextOut	Polygon	TextOut
See Also

»EndPath«, »FillPath«, »PathToRegion«, »SelectClipPath«, »StrokeAndFillPath«, »StrokePath«, »WidenPath«


  BeginUpdateResource

HANDLE BeginUpdateResource(lpszExeFile, bDeleteExistingResources)
LPTSTR  lpszExeFile;   /* addr. of file in which to update resources */
BOOL  bDeleteExistingResources;   /* deletion option */

The BeginUpdateResource function returns a handle that can be used by the UpdateResource function to add, delete, or replace resources in an executable file.

Parameters

lpszExeFile

Points to a null-terminated string that specifies a Windows executable file in which to update resources. An application must be able to obtain write access to this file; it cannot be currently executing. If lpszExeFile does not specify a full path, Windows searches for the file in the current directory.

bDeleteExistingResources

Specifies whether to delete the lpszExeFile parameter's existing resources. If this parameter is TRUE, existing resources are deleted and the updated executable file includes only resources added with the UpdateResource function. If this parameter is FALSE, the updated executable file includes existing resources unless they are explicitly deleted or replaced by using UpdateResource.

Return Value

If the function succeeds, the return value is a handle that can be used by the UpdateResource and EndUpdateResource functions. The return value is NULL if the specified file is not an executable file, the executable file is already loaded, the file does not exist, or the file cannot be opened for writing. To get extended error information, use the GetLastError function.

See Also

»EndUpdateResource«, »UpdateResource«


  BitBlt

BOOL BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop)
HDC  hdcDest;   /* handle of destination device context */
int  nXDest;   /* x-coordinate of destination rect. upper left corner */
int  nYDest;   /* y-coordinate of destination rect. upper left corner */
int  nWidth;   /* width of destination rect. */
int  nHeight;   /* height of destination rect. */
HDC  hdcSrc;   /* handle of source device context */
int  nXSrc;   /* x-coordinate of source rect. upper left corner */
int  nYSrc;   /* y-coordinate of source rect. upper left corner */
DWORD  dwRop;   /* raster operation code */

The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into the given destination device context.

Parameters

hdcDest

Identifies the destination device context.

nXDest

Specifies the logical x-coordinate of the upper left corner of the destination rectangle.

nYDest

Specifies the logical y-coordinate of the upper left corner of the destination rectangle.

nWidth

Specifies the logical width of the source and destination rectangles.

nHeight

Specifies the logical height of the source and the destination rectangles.

hdcSrc

Identifies the source device context.

nXSrc

Specifies the logical x-coordinate of the upper left corner of the source rectangle.

nYSrc

Specifies the logical y-coordinate of the upper left corner of the source rectangle.

dwRop

Specifies a raster-operation code. These codes define how the color data for the source rectangle is to be combined with the color data for the destination rectangle to achieve the final color.

The following list shows some common raster operation codes:

Value	Description
BLACKNESS	Fills the destination rectangle using the color associated with index 0 in the physical palette. (This color is black for the default physical palette.)
DSTINVERT	Inverts the destination rectangle.
MERGECOPY	Merges the colors of the source rectangle with the specified pattern by using the Boolean AND operator.
MERGEPAINT	Merges the colors of the inverted source rectangle with the colors of the destination rectangle by using the Boolean OR operator.
NOTSRCCOPY	Copies the inverted source rectangle to the destination.
NOTSRCERASE	Combines the colors of the source and destination rectangles by using the Boolean OR operator and then inverts the resultant color.
PATCOPY	Copies the specified pattern into the destination bitmap.
PATINVERT	Combines the colors of the specified pattern with the colors of the destination rectangle by using the Boolean XOR operator.
PATPAINT	Combines the colors of the pattern with the colors of the inverted source rectangle by using the Boolean OR operator. The result of this operation is combined with the colors of the destination rectangle by using the Boolean OR operator.
SRCAND	Combines the colors of the source and destination rectangles by using the Boolean AND operator.
SRCCOPY	Copies the source rectangle directly to the destination rectangle.
SRCERASE	Combines the inverted colors of the destination rectangle with the colors of the source rectangle by using the Boolean AND operator.
SRCINVERT	Combines the colors of the source and destination rectangles by using the Boolean XOR operator.
SRCPAINT	Combines the colors of the source and destination rectangles by using the Boolean OR operator.
WHITENESS	Fills the destination rectangle using the color associated with index 1 in the physical palette. (This color is white for the default physical palette.)
For further information on raster operations, and complete lists of all the raster operation codes, see Appendix F, "Raster Operation Codes," in Microsoft Win32 Programmer's Reference, Volume 2.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If a rotation or shear transformation is in effect in the source device context, BitBlt returns an error. If other transformations exist in the source device context (and a matching transformation is not in effect in the destination device context), the rectangle in the destination device context is stretched, compressed, or rotated as necessary.

If the color formats of the source and destination device contexts do no match, the BitBlt function converts the source color format to match the destination format.

When an enhanced metafile is being recorded, an error occurs if the source device context identifies an enhanced-metafile device context.

Not all devices support the BitBlt function. For more information, see the RC_BITBLT raster capability entry in the »GetDeviceCaps« function description.

BitBlt returns an error if the source and destination device contexts represent different devices.

See Also

»GetDeviceCaps«, »MaskBlt«, »PlgBlt«, »StretchBlt«


  BringWindowToTop

BOOL BringWindowToTop(hwnd)
HWND  hwnd;   /* handle of window */

The BringWindowToTop function brings the given window to the top of the Z order. If the window is a top-level window, it is activated. If the window is a child window, the top-level parent window associated with the child window is activated.

Parameters

hwnd

Identifies the window to bring to the top of the Z order.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Use BringWindowToTop to uncover any window that is partially or completely obscured by other windows.

Calling this function is similar to calling the SetWindowPos function to change a window's position in the Z order. The BringWindowToTop function does not make a window a top-level window.

See Also

»SetWindowPos«


  BuildCommDCB

BOOL BuildCommDCB(lpszDef, lpdcb)
LPSTR  lpszDef;   /* address of device-control string */
LPDCB  lpdcb;   /* address of device-control block */

The BuildCommDCB function fills a specified DCB structure with the values in a specified string.

Parameters

lpszDef

Points to a null-terminated string that specifies device-control information. The string must have the same form as the MS-DOS MODE command-line arguments. For example, the following line specifies a baud rate of 1200, no parity, 8 data bits, and 1 stop bit:

1200,N,8,1

The device name is ignored if it is included in the string, except that it must specify a valid device, as follows:

COM1:1200,N,8,1

lpdcb

Points to the DCB structure to be filled in. The DCB structure has the following form:

typedef struct _DCB { /* dcb */

    DWORD DCBlength;           /* sizeof(DCB)                */

    DWORD BaudRate;            /* current baud rate          */

    DWORD fBinary: 1;          /* binary mode, no EOF check  */

    DWORD fParity: 1;          /* enable parity checking     */

    DWORD fOutxCtsFlow:1;      /* CTS output flow control    */

    DWORD fOutxDsrFlow:1;      /* DSR output flow control    */

    DWORD fDtrControl:2;       /* DTR flow control type      */

    DWORD fDsrSensitivity:1;   /* DSR sensitivity            */

    DWORD fTXContinueOnXoff:1; /* XOFF continues Tx          */

    DWORD fOutX: 1;        /* XON/XOFF out flow control      */

    DWORD fInX: 1;         /* XON/XOFF in flow control       */

    DWORD fErrorChar: 1;   /* enable error replacement       */

    DWORD fNull: 1;        /* enable null stripping          */

    DWORD fRtsControl:2;   /* RTS flow control               */

    DWORD fAbortOnError:1; /* abort reads/writes on error    */

    DWORD fDummy2:17;      /* reserved                       */

    WORD wReserved;        /* not currently used             */

    WORD XonLim;           /* transmit XON threshold         */

    WORD XoffLim;          /* transmit XOFF threshold        */

    BYTE ByteSize;         /* number of bits/byte, 4-8       */

    BYTE Parity;           /* 0-4=no,odd,even,mark,space     */

    BYTE StopBits;         /* 0,1,2 = 1, 1.5, 2              */

    char XonChar;          /* Tx and Rx XON character        */

    char XoffChar;         /* Tx and Rx XOFF character       */

    char ErrorChar;        /* error replacement character    */

    char EofChar;          /* end of input character         */

    char EvtChar;          /* received event character       */

} DCB;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The BuildCommDCB function adjusts only those members of the DCB structure specifically affected by the lpszDef parameter, with the following exceptions:

•	If the specified baud rate is 110, the function sets the stop bits to 2 to remain compatible with the MS-DOS MODE command.

•	By default, BuildCommDCB disables XON/XOFF and hardware flow control. To enable flow control, you must explicitly set the appropriate members of the DCB structure.

The BuildCommDCB function only fills in the members of DCB structure. To apply these settings to a serial port, use the SetCommState function.

See Also

»SetCommState«


  BuildCommDCBAndTimeouts

BOOL BuildCommDCBAndTimeouts(lpDef, lpDCB, lpCommTimeouts)
LPTSTR  lpDef;   /* address of a device control string */
LPDCB  lpDCB;   /* address of a device control block */
LPCOMMTIMEOUTS  lpCommTimeouts;   /* address of a comm timeout structure */

The BuildCommDCBAndTimeouts function translates a device definition string into appropriate device-control block codes and places these codes into a device control block. The function can also set up timeout values, including the possibility of no timeouts, for the device; the function's behavior in this regard varies based on the contents of the device definition string.

Parameters

lpDef

Points to a null terminated character string that specifies device control information for the device. The function will take this string, parse it, then set appropriate values in the DCB data structure pointed to by lpDCB.

lpDCB

Points to a DCB data structure that the function fills with information it gleans from the device control information string pointed to by lpDef. This DCB structure defines the control settings for a communications device. The DCB structure has the following form:

typedef struct _DCB { /* dcb */

    DWORD DCBlength;           /* sizeof(DCB)                */

    DWORD BaudRate;            /* current baud rate          */

    DWORD fBinary: 1;          /* binary mode, no EOF check  */

    DWORD fParity: 1;          /* enable parity checking     */

    DWORD fOutxCtsFlow:1;      /* CTS output flow control    */

    DWORD fOutxDsrFlow:1;      /* DSR output flow control    */

    DWORD fDtrControl:2;       /* DTR flow control type      */

    DWORD fDsrSensitivity:1;   /* DSR sensitivity            */

    DWORD fTXContinueOnXoff:1; /* XOFF continues Tx          */

    DWORD fOutX: 1;        /* XON/XOFF out flow control      */

    DWORD fInX: 1;         /* XON/XOFF in flow control       */

    DWORD fErrorChar: 1;   /* enable error replacement       */

    DWORD fNull: 1;        /* enable null stripping          */

    DWORD fRtsControl:2;   /* RTS flow control               */

    DWORD fAbortOnError:1; /* abort reads/writes on error    */

    DWORD fDummy2:17;      /* reserved                       */

    WORD wReserved;        /* not currently used             */

    WORD XonLim;           /* transmit XON threshold         */

    WORD XoffLim;          /* transmit XOFF threshold        */

    BYTE ByteSize;         /* number of bits/byte, 4-8       */

    BYTE Parity;           /* 0-4=no,odd,even,mark,space     */

    BYTE StopBits;         /* 0,1,2 = 1, 1.5, 2              */

    char XonChar;          /* Tx and Rx XON character        */

    char XoffChar;         /* Tx and Rx XOFF character       */

    char ErrorChar;        /* error replacement character    */

    char EofChar;          /* end of input character         */

    char EvtChar;          /* received event character       */

} DCB;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpCommTimeouts

Points to a COMMTIMEOUTS structure that the function can use to set device timeout values. The COMMTIMEOUTS structure has the following form:

typedef struct _COMMTIMEOUTS { /* ctmo */

    DWORD ReadIntervalTimeout;

    DWORD ReadTotalTimeoutMultiplier;

    DWORD ReadTotalTimeoutConstant;

    DWORD WriteTotalTimeoutMultiplier;

    DWORD WriteTotalTimeoutConstant;

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The BuildCommDcbAndTimeouts function modifies its timeout setting behavior based on the presence, setting, or absence of a "TO=xxx" substring in the string specified by lpDef:

•	If that string contains the substring "TO=ON", the function sets up total read and write timeout values for the device based on the timeout structure pointed to by lpCommTimeouts.

•	If that string contains the substring "TO=OFF", the function sets up the device with no timeouts.

•	If that string contains neither of the aforementioned "TO=xxx" substrings, the function ignores the timeout structure pointed to by lpCommTimeouts. The timeout structure will not be accessed in any way.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetCommTimeouts«, »SetCommTimeouts«, »BuildCommDCB«


  CallMsgFilter

BOOL CallMsgFilter(lpmsg, nCode)
LPMSG  lpmsg;   /* address of structure with message data */
int  nCode;   /* hook code */

The CallMsgFilter function passes the specified message and hook code to the hook procedures associated with the WH_SYSMSGFILTER and WH_MSGFILTER hooks. A WH_SYSMSGFILTER or WH_MSGFILTER hook procedure is an application-defined callback function that examines and, optionally, modifies messages for a dialog box, message box, menu, or scroll bar.

Parameters

lpmsg

Points to an MSG structure that contains the message to be passed to the hook procedures. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

nCode

Specifies an application-defined code used by the hook procedure to determine how to process the message. The code must not have the same value as system-defined hook codes (MSGF_ and HC_) associated with the WH_SYSMSGFILTER and WH_MSGFILTER hooks.

Return Value

If the application should process the message further, the return value is zero; otherwise, it is nonzero.

Comments

Windows calls CallMsgFilter to enable applications to examine and control the flow of messages during internal processing of dialog boxes, message boxes, menus, and scroll bars, or when the user activates a different window by pressing the ALT+TAB key combination.

An application installs a hook procedure by using the SetWindowsHookEx function.

See Also

»MessageProc«, »SetWindowsHookEx«, »SysMsgProc«


  CallNamedPipe

BOOL CallNamedPipe(lpszPipeName, lpvWriteBuf, cbWriteBuf, lpvReadBuf, cbReadBuf,
lpcbRead, dwTimeout)
LPTSTR  lpszPipeName;   /* address of pipe name */
LPVOID  lpvWriteBuf;   /* address of write buffer */
DWORD  cbWriteBuf;   /* size in bytes of write buffer */
LPVOID  lpvReadBuf;   /* address of read buffer */
DWORD  cbReadBuf;   /* size in bytes of read buffer */
LPDWORD  lpcbRead;   /* number of bytes read */
DWORD  dwTimeout;   /* time-out time in milliseconds */

The CallNamedPipe function connects to a message-type pipe (and waits if an instance of the pipe is not available), writes to and reads from the pipe, and then closes the pipe.

Parameters

lpszPipeName

Points to a null-terminated string specifying the pipe name.

lpvWriteBuf

Points to the buffer containing the data written to the pipe.

cbWriteBuf

Specifies the size, in bytes, of the write buffer.

lpvReadBuf

Points to the buffer that receives the data read from the pipe.

cbReadBuf

Specifies the size, in bytes, of the read buffer.

lpcbRead

Points to a 32-bit variable that receives the number of bytes read from the pipe.

dwTimeout

Specifies the number of milliseconds to wait for the named pipe to be available. In addition to numeric values, the following special values are available:

Value	Meaning
NMPWAIT_NOWAIT	Do not wait for the named pipe. If the named pipe is not available, the function returns an error.
NMPWAIT_WAIT_FOREVER	Wait indefinitely.
NMPWAIT_USE_DEFAULT_WAIT	Use default timeout specified in call to CreateNamedPipe.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Calling the CallNamedPipe function is equivalent to calling CreateFile (or WaitNamedPipe, if CreateFile cannot open the pipe immediately), TransactNamedPipe, and CloseHandle. CreateFile is called with an access flag of GENERIC_READ | GENERIC_WRITE, an inherit handle flag of FALSE, and a share mode of zero (indicating no sharing of this pipe instance).

If the message written to the pipe by the server process is longer than cbReadBuf, CallNamedPipe returns FALSE, and the GetLastError function returns ERROR_MORE_DATA. The remainder of the message is discarded, because CallNamedPipe closes the handle to the pipe before returning.

CallNamedPipe fails if the pipe is a byte-type pipe.

See Also

»CloseHandle«, »CreateFile«, »CreateNamedPipe«, »TransactNamedPipe«, »WaitNamedPipe«


  CallNextHookEx

LRESULT CallNextHookEx(hhook, nCode, wParam, lParam)
HHOOK  hhook;   /* handle of current hook */
int  nCode;   /* hook code passed to hook procedure */
WPARAM  wParam;   /* value passed to hook procedure */
LPARAM  lParam;   /* value passed to hook procedure */

The CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain.

Parameters

hhook

Identifies the current hook. An application receives this handle as a result of a previous call to the SetWindowsHookEx function.

nCode

Specifies the hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information.

wParam

Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.

lParam

Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.

Return Value

If the function succeeds, the return value is the value returned by the next hook procedure in the chain. The current hook procedure must also return this value. The meaning of the return value depends on the hook type. For more information, see the descriptions of the individual hook procedures.

Comments

Hook procedures are installed in chains for particular hook types. CallNextHookEx calls the next hook in the chain.

Calling CallNextHookEx is optional. A hook procedure can call this function either before or after processing the hook information. If a hook procedure does not call CallNextHookEx, Windows does not call the hook procedures installed before the current hook procedure was installed.

See Also

»SetWindowsHook«, »SetWindowsHookEx«, »UnhookWindowsHook«, »UnhookWindowsHookEx«


  CallWindowProc

LRESULT CallWindowProc(wndprcPrev, hwnd, uMsg, wParam, lParam)
WNDPROC  wndprcPrev;   /* address of previous procedure */
HWND  hwnd;   /* handle of window */
UINT  uMsg;   /* message */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The CallWindowProc function passes message information to the specified window procedure.

Parameters

wndprcPrev

Points to the previous window procedure.

hwnd

Identifies the window procedure to receive the message.

uMsg

Specifies the message.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message sent.

Comments

Use the CallWindowProc function for window subclassing. Usually, all windows with the same class share one window procedure. A subclass is a window or set of windows with the same class whose messages are intercepted and processed by another window procedure (or procedures) before being passed to the window procedure of the class.

The SetWindowLong function creates the subclass by changing the window procedure associated with a particular window, causing Windows to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures.

If STRICT is defined, the wndprcPrev parameter is typed as WNDPROC. The WNDPROC type is declared as:

LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);

If STRICT is not defined, the wndprcPrev parameter is typed as FARPROC. The FARPROC type is declared as:

int (FAR WINAPI * FARPROC)()

In C, the FARPROC declaration indicates a callback function that has an unspecified parameters list. In C++, however, the empty parameter list in the declaration indicates that a function has no parameters. This subtle distinction can break careless code. The following code shows one way to handle this situation:

#ifdef STRICT

  WNDPROC MyWindowProcedure

#else

  FARPROC MyWindowProcedure

#endif

...

    lResult = CallWindowProc(MyWindowProcedure, ...) ;

For further information on functions declared with empty argument lists, refer to Section r.18.2 of The C++ Programming Language, Second Edition by Bjarne Stroustrup.

See Also

»SetClassLong«, »SetWindowLong«


  CallWndProc

LRESULT CALLBACK CallWndProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* current-process flag */
LPARAM  lParam;   /* address of structure with message data */

The CallWndProc hook procedure is an application-defined or library-defined callback function the system calls whenever the SendMessage function is called. Before passing the message to the destination window procedure, the system passes the message to the hook procedure.

Parameters

nCode

Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies whether the message is sent by the current process. If the message is sent by the current process, it is nonzero; otherwise, it is NULL.

lParam

Points to a CWPSTRUCT structure that contains details about the message. The CWPSTRUCT structure has the following form:

typedef struct tagCWPSTRUCT { /* cwps */

    LPARAM lParam;

    WPARAM wParam;

    DWORD  message;

    HWND   hwnd;

} CWPSTRUCT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

The return value should be zero.

Comments

The CallWndProc hook procedure can examine or modify the message, as necessary. After the hook procedure returns control to the system, the message, with any modifications, is passed to the window procedure.

An application installs the hook procedure by specifying the WH_CALLWNDPROC hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

CallWndProc is a placeholder for the application-defined or library-defined function name.

See Also

»CallNextHookEx«, »SendMessage«, »SetWindowsHookEx«


  CancelDC

BOOL CancelDC(hdc)
HDC  hdc;   /* handle of device context */

The CancelDC function cancels any pending operation on the given device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is TRUE. Otherwise, it is FALSE.

Comments

The CancelDC function is used by multithreaded applications to cancel lengthy drawing operations. If thread A initiates a lengthy drawing operation, thread B may cancel that operation by calling this function.

If an operation is canceled, the affected thread returns an error and the result of its drawing operation is undefined. The results are also undefined if no drawing operation was in progress when the function was called.

See Also

»CreateThread«, »GetCurrentThread«


  Catch

The Catch function has been deleted.

Structured exception handling is built into the Win32 application programming interface. For more information about structured exception handling, see Chapter 64, "Structured Exception Handling," in Microsoft Win32 Programmer's Reference, Volume 2.


  CBTProc

LRESULT CALLBACK CBTProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* depends on hook code */
LPARAM  lParam;   /* depends on hook code */

The CBTProc hook procedure is an application-defined or library-defined callback function the system calls before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue. The value returned by the hook procedure determines whether Windows allows or prevents one of these operations. A computer-based training (CBT) application uses this hook procedure to receive useful notifications from the system.

Parameters

nCode

Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:

Value	Meaning
HCBT_ACTIVATE	The system is about to activate a window.
HCBT_CLICKSKIPPED	The system has removed a mouse message from the system message queue. Upon receiving this hook code, a CBT application must install a WH_JOURNALPLAYBACK hook procedure in response to the mouse message.
HCBT_CREATEWND	A window is about to be created. The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window. If the hook procedure returns a nonzero value, the system destroys the window; the CreateWindow function returns NULL, but the WM_DESTROY message is not sent to the window. If the hook procedure returns zero, the window is created normally.
	At the time of the HCBT_CREATEWND notification, the window has been created, but its final size and position may not have been determined and its parent window may not have been established. It is possible to send messages to the newly created window, although it has not yet received WM_NCCREATE or WM_CREATE messages. It is also possible to change the position in the Z order of the newly created window by modifying the hwndInsertAfter member of the CBT_CREATEWND structure.
HCBT_DESTROYWND	A window is about to be destroyed.
HCBT_KEYSKIPPED	The system has removed a keyboard message from the system message queue. Upon receiving this hook code, a CBT application must install a WH_JOURNALPLAYBACK hook procedure in response to the keyboard message.
HCBT_MINMAX	A window is about to be minimized or maximized.
HCBT_MOVESIZE	A window is about to be moved or sized.
HCBT_QS	The system has retrieved a WM_QUEUESYNC message from the system message queue.
HCBT_SETFOCUS	A window is about to receive the keyboard focus.
HCBT_SYSCOMMAND	A system command is about to be carried out. This allows a CBT application to prevent task switching by means of hot keys.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Depends on the nCode parameter. For details, see the following Comments section.

lParam

Depends on the nCode parameter. For details, see the following Comments section.

Return Value

For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation or 1 to prevent it:

HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SYSCOMMAND

For operations corresponding to the following CBT hook codes, the return value is ignored:

HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED
HCBT_QS

Comments

The hook procedure should not install a WH_JOURNALPLAYBACK hook procedure except in the situations described in the preceding list of hook codes.

This hook procedure must be in a dynamic-link library (DLL). An application installs the hook procedure by specifying the WH_CBT hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

The following table describes the wParam and lParam parameters for each HCBT_ hook code:

Value	wParam	lParam
HCBT_ACTIVATE	Specifies the handle of the window about to be activated.	Specifies a long pointer to a CBTACTIVATESTRUCT structure containing the handle of the active window and specifies whether the activation is changing because of a mouse click. For a description of the CBTACTIVATESTRUCT structure, see the Microsoft Win32 Programmer's Reference, Volume 5.
HCBT_CLICKSKIPPED	Identifies the mouse message removed from the system message queue.	Specifies a long pointer to a MOUSEHOOKSTRUCT structure containing the hit-test code and the handle of the window for which the mouse message is intended. For a list of hit-test codes, see the description of the »WM_NCHITTEST« message. For a description of the MOUSEHOOKSTRUCT structure, see the Microsoft Win32 Programmer's Reference, Volume 5.
HCBT_CREATEWND	Specifies the handle of the new window.	Specifies a long pointer to a CBT_CREATEWND structure containing initialization parameters for the window. For a description of the CBT_CREATEWND structure, see the Microsoft Win32 Programmer's Reference, Volume 5.
HCBT_DESTROYWND	Specifies the handle of the window about to be destroyed.	Is undefined and must be set to zero.
HCBT_KEYSKIPPED	Identifies the virtual-key code.	Specifies the repeat count, scan code, key-transition code, previous key state, and context code. For more information, see the description of the »WM_KEYUP« or »WM_KEYDOWN« message.
HCBT_MINMAX	Specifies the handle of the window being minimized or maximized.	Specifies, in the low-order word, a show-window value (SW_) specifying the operation. For a list of show-window values, see the description of the »ShowWindow« function. The high-order word is undefined.
HCBT_MOVESIZE	Specifies the handle of the window to be moved or sized.	Specifies a long pointer to a RECT structure containing the coordinates of the window. For a description of the RECT structure, see the Microsoft Win32 Programmer's Reference, Volume 5.
HCBT_QS	Is undefined and must be zero.	Is undefined and must be zero.
HCBT_SETFOCUS	Specifies the handle of the window gaining the keyboard focus.	Specifies, in the low-order word, the handle of the window losing the keyboard focus. The high-order word is undefined.
HCBT_SYSCOMMAND	Specifies a system-command value (SC_) specifying the system command. Formore information about system-command values, see the description of the »WM_SYSCOMMAND« message.	If the wParam parameter is SC_HOTKEY, specifies, in the low-order word, the handle of the window that task switching will bring to the foreground. Otherwise, lParam is undefined.
CBTProc is a placeholder for the application-defined or library-defined function name.

pbSee Also

»CallNextHookEx«, »SetWindowsHookEx«


  ChangeClipboardChain

BOOL ChangeClipboardChain(hwndRemove, hwndNext)
HWND  hwndRemove;   /* handle of window to remove */
HWND  hwndNext;   /* handle of next window */

The ChangeClipboardChain function removes a given window from the chain of clipboard viewers.

Parameters

hwndRemove

Identifies the window to be removed from the chain. The handle must have been passed to the SetClipboardViewer function.

hwndNext

Identifies the window that follows the hwndRemove window in the clipboard viewer chain. (This is the handle returned by the SetClipboardViewer function, unless the sequence was changed in response to a WM_CHANGECBCHAIN message.)

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use GetLastError function.

Comments

The window identified by hwndNext replaces the hwndRemove window in the chain. The SetClipboardViewer function sends a WM_CHANGECBCHAIN message to the first window in the clipboard viewer chain.

See Also

»SetClipboardViewer«, »WM_CHANGECBCHAIN«


  ChangeMenu

The ChangeMenu function has been replaced with the following five specialized functions.

Function	Description
AppendMenu	Appends a menu item to the end of a menu.
DeleteMenu	Deletes a menu item from a menu, destroying the menu item.
InsertMenu	Inserts a menu item into a menu.
ModifyMenu	Modifies a menu item in a menu.
RemoveMenu	Removes a menu item from a menu but does not destroy the menu item.
Applications written for versions earlier than Windows 3.0 may continue to call ChangeMenu as previously documented. Applications written for Windows versions 3.0 and later should call the new functions listed above.

Example

This example illustrates how a call to ChangeMenu should be rewritten to the AppendMenu function.

ChangeMenu(hMenu,                          /* handle of the menu      */

    0,                                     /* not used                */

    "&White",                              /* menu item string        */

    IDM_PATTERN1,                          /* identifier of menu item */

    MF_APPEND | MF_STRING | MF_CHECKED);   /* flags                   */

AppendMenu(hMenu,                          /* handle of the menu      */

    MF_STRING | MF_CHECKED,                /* flags                   */

    IDM_PATTERN1,                          /* identifier of menu item */

    "&White");                             /* menu item string        */

See Also

»AppendMenu«, »DeleteMenu«, »InsertMenu«, »ModifyMenu«, »RemoveMenu«


  ChangeSelector

The ChangeSelector function has been deleted.


  ChangeServiceConfig

BOOL ChangeServiceConfig(schService, fdwServiceType, fdwStartType,
fdwErrorControl, lpszBinaryPathName, lpszLoadOrderGroup, lpszDependencies,
lpszServiceStartName, lpszPassword, lpszDisplayName)
SC_HANDLE  schService;   /* handle of service */
DWORD  fdwServiceType;   /* type of service */
DWORD  fdwStartType;   /* when to start service */
DWORD  fdwErrorControl;   /* severity if service fails to start */
LPCTSTR  lpszBinaryPathName;   /* address of service binary file name */
LPCTSTR  lpszLoadOrderGroup;   /* address of load ordering group name */
LPDWORD  lpdwTagID;   /* address of variable to get tag identifier */
LPCTSTR  lpszDependencies;   /* address of array of dependency names */
LPCTSTR  lpszServiceStartName;   /* address of account name of service */
LPCTSTR  lpszPassword;   /* address of password for service account */
LPCTSTR  lpszDisplayName;   /* address of display name */

The ChangeServiceConfig function changes the configuration parameters of a service.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function and must have SERVICE_CHANGE_CONFIG access.

fdwServiceType

Specifies the type of service. This value can be SERVICE_NO_CHANGE if the existing service type is not modified, or one of the following values can be specified:

Type	Meaning
SERVICE_WIN32_OWN_PROCESS	Specifies a service that runs in its own Win32 process.
SERVICE_WIN32_SHARE_PROCESS	Specifies a service that shares a Win32 process with other services.
SERVICE_KERNEL_DRIVER	Specifies a Windows NT device driver.
SERVICE_FILE_SYSTEM_DRIVER	Specifies a Windows NT file system driver.
fdwStartType

Specifies when to start the service. This value can be the service type SERVICE_NO_CHANGE if the existing start type is not modified, or one of the following values can be specified:

Value	Meaning
SERVICE_BOOT_START	Specifies a device driver started by the operating system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_SYSTEM_START	Specifies a device driver started by the IoInitSystem function. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_AUTO_START	Specifies a device driver or Win32 service started by the service control manager automatically during system startup.
SERVICE_DEMAND_START	Specifies a device driver or Win32 service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED	Specifies a device driver or Win32 service that can no longer be started.
fdwErrorControl

Specifies the severity of the error if the service fails to start during system startup, and determines the action taken by the startup program if failure occurs. This value should be the SERVICE_ERROR_NORMAL flag, which causes the startup program to log the error but continue the startup process. The SERVICE_ERROR_SEVERE and SERVICE_ERROR_CRITICAL flags are not currently supported. This value can be the SERVICE_NO_CHANGE flag if the existing error control value is not modified.

lpszBinaryPathName

Points to a null-terminated string that contains the fully qualified path to the service binary file. If the pointer is NULL, the path is not modified.

lpszLoadOrderGroup

Points to a null-terminated string that names the load ordering group of which this service is a member. If the pointer is NULL, the group is not modified. If it points to an empty string, the service does not belong to a group.

The registry has a list of load ordering groups at HKEY_LOCAL_MACHINES\System \CurrentControlSet\Control\ServiceGroupOrder. The startup program uses this list to load groups of services in a specified order with respect to the other groups in the list. You can place a service in a group so that another service can depend on the group.

The order in which a service starts is determined by these criteria:

1.	The order of groups in the registry's load-ordering group list. Services in groups in the load-ordering group list are started first, followed by services in groups not in the load-ordering group list and then services that do not belong to a group.

2.	The service's dependencies listed in the lpszDependencies parameter and the dependencies of other services dependent on the service.

lpdwTagID

Points to a 32-bit variable that receives a unique tag value for this service in the group specified in the lpszLoadOrderGroup parameter. If no tag is requested, this parameter can be NULL.

You can use a tag for ordering service startup within a load ordering group by specifying a tag order vector in the registry at HKEY_LOCAL_MACHINE\System\ CurrentControlSet\Control\GroupOrderList. Tags are only evaluated for SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER type services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.

lpszDependencies

Points to an array of null-separated names of services or load ordering groups that must start before this service. The array is double null-terminated. If the pointer is NULL, the dependencies are not modified. If it points to an empty string, the service has no dependencies. If a group name is specified, it must be prefixed by the SC_GROUP_IDENTIFIER character (defined in the WINSVC.H files) to differentiate it from a service name, because services and service groups share the same name space. Dependency on a service means that this service can only run if the service it depends on is running. Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.

lpszServiceStartName

Points to a null-terminated string. If NULL is specified, the name is not modified. If the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, this name is the account name in the form of "DomainName\Username", which the service process will be logged on as when it runs. If the account belongs to the built-in domain, ".\Username" can be specified.

If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this name is the Windows NT driver object name (that is, \FileSystem\Rdr or \Driver\Xns), which the input and output (I/O) system uses to load the device driver. If NULL is specified, the driver is run with a default object name created by the I/O system, based on the service name.

lpszPassword

Points to a null-terminated string that contains the password to the account name specified by the lpszServiceStartName parameter if the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS. If the pointer is NULL, the password is not modified. If it points to an empty string, the service has no password. If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this parameter is ignored.

lpszDisplayName

Points to a null-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the Service Control Manager. Display name comparisons are always case-insensitive.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with SERVICE_CHANGE_CONFIG access.
ERROR_CIRCULAR_DEPENDENCY
	A circular service dependency was specified.
ERROR_DUP_NAME
	The display name already exists in the service controller's database, either as a service name or as another display name.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_INVALID_PARAMETER
	A parameter that was specified is invalid.
ERROR_INVALID_SERVICE_ACCOUNT
	The account name does not exist, or a service is specified to share the same binary file as an already installed service but with an account name that is not the same as the installed service.
ERROR_SERVICE_MARKED_FOR_DELETE
	The service has been marked for deletion.
Comments

The ChangeServiceConfig function changes the configuration information for the specified service in the service control manager database. This configuration information is initially specified by the CreateService function and can be queried (except for the password parameter) by using the QueryServiceConfig function.

Any of the configuration parameters specified for this function can be left unchanged by specifying NULL for a string parameter or SERVICE_NO_CHANGE for a doubleword parameter.

If the configuration is changed for a service that is running, with the exception of lpszDisplayName, the changes do not take effect until the service is stopped.

See Also

»CreateService«, »QueryServiceConfig«


  CharLower

LPTSTR CharLower(lpszString)
LPTSTR  lpszString;   /* address of string or single character */

The CharLower function converts a character or a character string to lowercase.

Parameters

lpszString

Points to a null-terminated string or specifies a single character. If the high-order word of this parameter is zero, the low-order word must contain a single character to be converted.

Return Value

If the function succeeds and the value to be converted is a character string, the return value is a pointer to the converted string. Otherwise, the return value is the converted character.

Comments

The language driver makes the conversion for the current language selected by the user at setup or by using Control Panel. If no language driver has been selected, Windows completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

See Also

»CharLowerBuff«, »CharUpper«, »CharUpperBuff«


  CharLowerBuff

DWORD CharLowerBuff(lpszString, cchString)
LPTSTR  lpszString;   /* address of string to convert */
DWORD  cchString;   /* number of characters to convert */

The CharLowerBuff function converts a character string to lowercase. The string is converted in place.

Parameters

lpszString

Points to a buffer containing one or more characters.

cchString

Specifies the number of characters in the buffer to convert.

Return Value

If the function succeeds, the return value is the number of characters converted.

Comments

The language driver for the current language selected by the user at setup or by using Control Panel makes the conversion. If no language driver has been selected, Windows completes the conversion using internal default mapping. The conversion is made based on the code page associated with the process locale.

See Also

»CharLower«, »CharUpper«, »CharUpperBuff«


  CharNext

LPTSTR CharNext(lpszCurrentChar)
LPCTSTR  lpszCurrentChar;   /* address of current character */

The CharNext function returns a pointer to the next character in a string.

Parameters

lpszCurrentChar

Points to a character in a null-terminated string.

Return Value

If the function succeeds, the return value is a pointer to the next character in the string, or to the terminating null character if at the end of the string.

See Also

»CharPrev«


  CharPrev

LPTSTR CharPrev(lpszStart, lpszCurrentChar)
LPCTSTR  lpszStart;   /* address of first character */
LPCTSTR  lpszCurrentChar;   /* address of current character */

The CharPrev function returns a pointer to the preceding character in a string.

Parameters

lpszStart

Points to the beginning of the string.

lpszCurrentChar

Points to a character in a null-terminated string.

Return Value

If the function succeeds, the return value is a pointer to the preceding character in the string, or to the first character in the string if the lpszCurrentChar parameter equals the lpszStart parameter.

See Also

»CharNext«


  CharToOem

BOOL CharToOem(lpszSrc, lpszDest)
LPCTSTR  lpszSrc;   /* address of string to translate */
LPSTR  lpszDest;   /* address of translated string */

The CharToOem function translates a string into the OEM-defined character set. (OEM stands for original equipment manufacturer.)

Parameters

lpszSrc

Points to the null-terminated string to translate.

lpszDest

Points to the buffer for the translated string. If the string buffer is large enough and the CharToOem function is being used as an ANSI function, the string can be translated in place by setting the lpszDest parameter to the same address as the lpszSrc parameter. This cannot be done if CharToOem is being used as a wide-character function.

Return Value

The return value is always TRUE.

See Also

»CharToOemBuff«, »OemToChar«, »OemToCharBuff«


  CharToOemBuff

BOOL CharToOemBuff(lpszSrc, lpszDest, cchSrc)
LPCTSTR  lpszSrc;   /* address of string to translate */
LPSTR  lpszDest;   /* address of translated string */
DWORD  cchSrc;   /* length of string to translate, in characters */

The CharToOemBuff function translates a specified number of characters in a string into the OEM-defined character set. (OEM stands for original equipment manufacturer.)

Parameters

lpszSrc

Points to the null-terminated string to translate.

lpszDest

Points to the buffer for the translated string. If the string buffer is large enough and the CharToOemBuff function is being used as an ANSI function, the string can be translated in place by setting the lpszDest parameter to the same address as the lpszSrc parameter. This cannot be done if CharToOemBuff is being used as a wide-character function.

cchSrc

Specifies the number of characters to translate in the string identified by the lpszSrc parameter.

Return Value

The return value is always TRUE.

See Also

»CharToOem«, »OemToChar«, »OemToCharBuff«


  CharUpper

LPTSTR CharUpper(lpszString)
LPTSTR  lpszString;   /* address of string or single character */

The CharUpper function converts a character string to uppercase.

Parameters

lpszString

Points to a null-terminated string or specifies a single character. If the high-order word of this parameter is zero, the low-order word must contain a single character to be converted.

Return Value

If the function succeeds and the value to be converted is a character string, the return value is a pointer to the converted string. Otherwise, the return value is the converted character.

Comments

The language driver for the current language selected by the user at setup or by using Control Panel makes the conversion. If no language driver has been selected, Windows completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

See Also

»CharLower«, »CharLowerBuff«, »CharUpperBuff«


  CharUpperBuff

DWORD CharUpperBuff(lpszString, cchString)
LPTSTR  lpszString;   /* address of string to convert */
DWORD  cchString;   /* number of characters to convert */

The CharUpperBuff function converts a character string to uppercase. The string is converted in place.

Parameters

lpszString

Points to a buffer containing one or more characters.

cchString

Specifies the number of characters in the buffer to convert.

Return Value

If the function succeeds, the return value is the number of characters converted.

Comments

The language driver for the current language selected by the user at setup or by using Control Panel makes the conversion. If no language driver has been selected, Windows completes the conversion using internal default mapping. The conversion is made based on the code page associated with the process locale.

See Also

»CharLower«, »CharLowerBuff«, »CharUpper«


  CheckDlgButton

BOOL CheckDlgButton(hwndDlg, idButton, uCheck)
HWND  hwndDlg;   /* handle of dialog box */
int  idButton;   /* button-control identifier */
UINT  uCheck;   /* check state */

The CheckDlgButton function places a check mark next to (checks) or removes a check mark from (clears) a button control, or it changes the state of a three-state button.

Parameters

hwndDlg

Identifies the dialog box that contains the button.

idButton

Identifies the button to modify.

uCheck

Specifies the check state of the button. If this parameter is nonzero, CheckDlgButton selects the button; if the parameter is zero, the function clears the button. For a three-state check box, if uCheck is 2, the button is grayed; if uCheck is 1, it is selected; if uCheck is 0, it is cleared.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CheckDlgButton function sends a BM_SETCHECK message to the specified button control in the given dialog box.

See Also

»CheckRadioButton«, »IsDlgButtonChecked«


  CheckMenuItem

DWORD CheckMenuItem(hmenu, idCheckItem, fuFlags)
HMENU  hmenu;   /* handle of menu */
UINT  idCheckItem;   /* menu item to check or uncheck */
UINT  fuFlags;   /* menu item flags */

The CheckMenuItem function sets the state of the given menu item's check mark attribute to either checked or unchecked.

Parameters

hmenu

Identifies the menu.

idCheckItem

Specifies the menu item whose check mark attribute is to be set, as determined by the fuFlags parameter.

fuFlags

Specifies flags that control the interpretation of the idCheckItem parameter and the state of the menu item's check mark attribute. This parameter can be a combination of either MF_BYCOMMAND or MF_BYPOSITION and MF_CHECKED or MF_UNCHECKED.

Value	Meaning
MF_BYCOMMAND	Indicates that the idCheckItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default, if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the idCheckItem parameter gives the zero-based relative position of the menu item.
MF_CHECKED	Sets the check mark attribute to the checked state.
MF_UNCHECKED	Sets the check mark attribute to the unchecked state.
Return Value

The return value specifies the previous state of the menu item (either MF_CHECKED or MF_UNCHECKED). If the menu item does not exist, the return value is 0xFFFFFFFF.

Comments

An item in a menu bar cannot have a check mark.

The idCheckItem parameter identifies a pop-up item or a command item. For a pop-up item, the idCheckItem parameter must specify the position of the item, because a pop-up item does not have an identifier. For a command item, the idCheckItem parameter can specify either the item's position or its identifier.

See Also

»EnableMenuItem«, »GetMenuCheckMarkDimensions«, »GetMenuItemID«, »SetMenuItemBitmaps«


  CheckRadioButton

BOOL CheckRadioButton(hwndDlg, idFirstButton, idLastButton, idCheckButton)
HWND  hwndDlg;   /* handle of dialog box */
int  idFirstButton;   /* identifier of first radio button in group */
int  idLastButton;   /* identifier of last radio button in group */
int  idCheckButton;   /* identifier of radio button to select */

The CheckRadioButton function adds a check mark to (checks) a given radio button in a group and removes a check mark from (clears) all other radio buttons in the group.

Parameters

hwndDlg

Identifies the dialog box that contains the radio button.

idFirstButton

Specifies the identifier of the first radio button in the group.

idLastButton

Specifies the identifier of the last radio button in the group.

idCheckButton

Specifies the identifier of the radio button to select.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CheckRadioButton function sends a BM_SETCHECK message to the specified radio button control in the given dialog box.

See Also

»CheckDlgButton«, »IsDlgButtonChecked«


  ChildWindowFromPoint

HWND ChildWindowFromPoint(hwndParent, pt)
HWND  hwndParent;   /* handle of parent window */
POINT  pt;   /* structure with point coordinates */

The ChildWindowFromPoint function determines which, if any, of the child windows belonging to the given parent window contains the specified point.

Parameters

hwndParent

Identifies the parent window.

pt

Specifies a POINT structure that defines the client coordinates of the point to be checked. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the child window that contains the point, even if the child window is hidden or disabled. If the point lies outside the parent window, the return value is NULL. If the point is within the parent window but not within any child window, the return value is the handle of the parent window.

Comments

Windows maintains an internal list, containing the handles of the child windows associated with a parent window. The order of the handles in the list depends on the Z order of the child windows. If more than one child window contains the given point, Windows returns the handle of the first window in the list that contains the point.

See Also

»WindowFromPoint«


  ChooseColor

BOOL ChooseColor(lpcc)
LPCHOOSECOLOR  lpcc;   /* address of structure with initialization data */

The ChooseColor function creates system-defined dialog box from which the user can select a color.

Parameters

lpcc

Points to a CHOOSECOLOR structure that, when the function is called, contains information necessary to initialize the dialog box. When ChooseColor returns, this structure contains information about the user's color selection. The CHOOSECOLOR structure has the following form:

typedef struct {   /* cc */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HWND         hInstance;

    DWORD        rgbResult;

    LPDWORD      lpCustColors;

    DWORD        Flags;

    DWORD        lCustData;

    LPCCHOOKPROC lpfnHook;

    LPCSTR       lpTemplateName;

} CHOOSECOLOR;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the user selects a color, the return value is TRUE; it is FALSE if an error occurs, the user chooses the Cancel button, or the user chooses the Close command on the System menu (often called the Control menu) to close the dialog box.

Use the CommDlgExtendedError function to retrieve extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE
CDERR_INITIALIZATION
CDERR_LOCKRESFAILURE
CDERR_LOADRESFAILURE
CDERR_LOADSTRFAILURE
CDERR_MEMALLOCFAILURE
CDERR_MEMLOCKFAILURE
CDERR_NOHINSTANCE
CDERR_NOHOOK
CDERR_NOTEMPLATE
CDERR_STRUCTSIZE

Comments

The dialog box does not support palettes. The color choices offered by the dialog box are limited to the system colors and dithered versions of those colors.

If the hook function (pointed to by the lpfnHook member of the CHOOSECOLOR structure) processes the WM_CTLCOLOR message, this function must return a handle for the brush that should be used to paint the control background.

See Also

»CommDlgExtendedError«.


  ChooseFont

BOOL ChooseFont(lpcf)
LPCHOOSEFONT  lpcf;   /* pointer to structure with initialization data */

The ChooseFont function creates a system-defined dialog box from which the user can select a font, a font style (such as bold or italic), a point size, an effect (such as strikeout or underline), and a text color.

Parameters

lpcf

Points to a CHOOSEFONT structure that, when the structure is called, contains information necessary to initialize the dialog box. When ChooseFont returns, this structure contains information about the user's font selection. The CHOOSEFONT structure has the following form:

typedef struct {    /* cf */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HDC          hDC;

    LPLOGFONT    lpLogFont;

    INT          iPointSize;

    DWORD        Flags;

    DWORD        rgbColors;

    DWORD        lCustData;

    LPCFHOOKPROC lpfnHook;

    LPCTSTR      lpTemplateName;

    HANDLE       hInstance;

    LPTSTR       lpszStyle;

    WORD         nFontType;

    WORD         ___MISSING_ALIGNMENT__;

    INT          nSizeMin;

    INT          nSizeMax;

} CHOOSEFONT;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Use the CommDlgExtendedError function to retrieve extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE
CDERR_INITIALIZATION
CDERR_LOCKRESFAILURE
CDERR_LOADRESFAILURE
CDERR_LOADSTRFAILURE
CDERR_MEMALLOCFAILURE
CDERR_MEMLOCKFAILURE
CDERR_NOHINSTANCE
CDERR_NOHOOK
CDERR_NOTEMPLATE
CDERR_STRUCTSIZE
CFERR_MAXLESSTHANMIN
CFERR_NOFONTS

Comments

If the hook function (to which the lpfnHook member of the CHOOSEFONT structure points) processes the WM_CTLCOLOR message, this function must return a handle for the brush that should be used to paint the control background.

An application can use the WM_CHOOSEFONT_GETLOGFONT message to retrieve a LOGFONT structure for the current logical font while the Font dialog box is open.

See Also

»CommDlgExtendedError«, »WM_CHOOSEFONT_GETLOGFONT«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  Chord

BOOL Chord(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect, nXRadial1,
nYRadial1, nXRadial2, nYRadial2)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coord. of bounding rect. upper-left corner */
int  nTopRect;   /* y-coord. of bounding rect. upper-left corner */
int  nRightRect;   /* x-coord. of bounding rect. lower-right corner */
int  nBottomRect;   /* y-coord. of bounding rect. lower-right corner */
int  nXRadial1;   /* x-coord. of first radial's endpoint */
int  nYRadial1;   /* y-coord. of first radial's endpoint */
int  nXRadial2;   /* x-coord. of second radial's endpoint */
int  nYRadial2;   /* y-coord. of second radial's endpoint */

The Chord function draws a chord (a region bounded by the intersection of an ellipse and a line segment, called a secant). The chord is outlined by using the current pen and filled by using the current brush.

Parameters

hdc

Identifies the device context in which the chord appears.

nLeftRect

Specifies the x-coordinate of the upper-left corner of the bounding rectangle.

nTopRect

Specifies the y-coordinate of the upper-left corner of the bounding rectangle.

nRightRect

Specifies the x-coordinate of the lower-right corner of the bounding rectangle.

nBottomRect

Specifies the y-coordinate of the lower-right corner of the bounding rectangle.

nXRadial1

Specifies the x-coordinate of the endpoint of the radial defining the beginning of the chord.

nYRadial1

Specifies the y-coordinate of the endpoint of the radial defining the beginning of the chord.

nXRadial2

Specifies the x-coordinate of the endpoint of the radial defining the end of the chord.

nYRadial2

Specifies the y-coordinate of the endpoint of the radial defining the end of the chord.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The curve of the chord is defined by an ellipse that fits the specified bounding rectangle. The curve begins at the point where the ellipse intersects the first radial and extends counterclockwise to the point where the ellipse intersects the second radial. (A radial is a line segment drawn from the center of the ellipse to the specified endpoint on the ellipse.) The chord is closed by drawing a line from the intersection of the first radial and the curve to the intersection of the second radial and the curve.

If the starting point and ending point of the curve are the same, a complete ellipse is drawn.

The current position is neither used nor updated by this function.

See Also

»AngleArc«, »Arc«, »ArcTo«, »Pie«


  ClearCommBreak

BOOL ClearCommBreak(hCommDev)
HANDLE  hCommDev;   /* handle of the communications device */

The ClearCommBreak function restores character transmission for a given communications device and places the transmission line in a nonbreak state.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A communications device is placed in a break state by the SetCommBreak or EscapeCommFunction function. This suspends character transmission until the break state is cleared by calling ClearCommBreak.

See Also

»ClearCommError«, »EscapeCommFunction«, »SetCommBreak«


  ClearCommError

BOOL ClearCommError(hCommDev, lpdwErrors, lpcst)
HANDLE  hCommDev;   /* handle of the communications device */
LPDWORD  lpdwErrors;   /* address of variable to receive error codes */
LPCOMSTAT  lpcst;   /* address of buffer for communication status */

The ClearCommError function retrieves information about a communications error and reports the current status of a communications device. The function is called when a communications error occurs, and it clears the device's error flag to enable additional input and output (I/O) operations.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpdwErrors

Points to a 32-bit variable to be filled with a mask indicating the type of error. This parameter can be one or more of the following values is specified:

Value	Meaning
CE_BREAK	The hardware detected a break condition.
CE_FRAME	The hardware detected a framing error.
CE_IOE	An I/O error occurred during communications with the device.
CE_MODE	The requested mode is not supported, or the hCommDev parameter is invalid. If this bit set, this is the only valid error.
CE_OOP	The parallel device signaled that it is out of paper.
CE_OVERRUN	A character-buffer overrun has occurred. The next character is lost.
CE_RXOVER	An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character was received.
CE_RXPARITY	The hardware detected a parity error.
CE_TXFULL	The application tried to transmit a character, but the output buffer was full.
CE_DNS	The parallel device is not selected.
CE_PTO	A timeout occurred on a parallel device.
lpcst

Points to a COMSTAT structure in which the device's status information is returned. If lpcst is NULL, no status information is returned. The COMSTAT structure has the following form:

typedef struct _COMSTAT { /* cst */

    DWORD fCtsHold : 1;   /* Tx waiting for CTS signal    */

    DWORD fDsrHold : 1;   /* Tx waiting for DSR signal    */

    DWORD fRlsdHold : 1;  /* Tx waiting for RLSD signal   */

    DWORD fXoffHold : 1;  /* Tx waiting, XOFF char rec'd  */

    DWORD fXoffSent : 1;  /* Tx waiting, XOFF char sent   */

    DWORD fEof : 1;       /* EOF character sent           */

    DWORD fTxim : 1;      /* character waiting for Tx     */

    DWORD fReserved : 25; /* reserved                     */

    DWORD cbInQue;        /* bytes in input buffer        */

    DWORD cbOutQue;       /* bytes in output buffer       */

} COMSTAT, *LPCOMSTAT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If a communications port has been set up with a TRUE value for the fAbortOnError member of the setup DCB structure, the communications software will terminate all read and write operations on the communications port when a communications error occurs. No new read or write operations are accepted until the application has acknowledged the communications error by calling the ClearCommError function.

The ClearCommError function fills the status buffer pointed to by the lpcst parameter with the current status of the communications device specified by thehCommDev parameter.

See Also

»ClearCommBreak«


  ClearEventLog

BOOL ClearEventLog(hEventLog, lpszBackupFile)
HANDLE  hEventLog;   /* handle to event log */
LPTSTR  lpszBackupFile;   /* name of backup file */

The ClearEventLog function clears the given event log, and optionally saves the current copy of the logfile to a backup file.

Parameters

hEventLog

Identifies the event log to be cleared. This handle is returned by the OpenEventLog function.

lpszBackupFile

Points to the null-terminated string specifying the name of a file in which a current copy of the event logfile will be placed. If this file already exists, the function fails.

The backup filename may contain a server name to save the backup file on a remote server.

If lpszBackupFile is NULL, the current event logfile is not backed up.

Return Value

If the function succeeds, the return value is TRUE. The given event log has been backed up (if lpszBackupFile is not NULL) and then cleared. Otherwise, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

This function fails if the event log is empty.

After this function returns, any handles that reference the cleared event log cannot be used to read the log.

If the backup filename specifies a remote server, the event log handle must identify a log on the local computer. You cannot back up an event logfile from a remote server to a file on a remote server (even if the backup file and the original log are on the same server).

ClearEventLog is used to optionally back up an existing logfile of the module represented by hEventLog. The function backs up the logfile to another file, and then clears the existing logfile. The caller must have write permission for the path specified, and must also have permission to move the current logfile. If a file already exists with the same name as lpszBackupFile, ClearEventLog fails.

See Also

»OpenEventLog«


  ClientToScreen

BOOL ClientToScreen(hwnd, lppt)
HWND  hwnd;   /* window handle for source coordinates */
LPPOINT  lppt;   /* address of structure containing screen coordinates */

The ClientToScreen function converts the client coordinates of a given point to screen coordinates.

Parameters

hwnd

Identifies the window whose client area is used for the conversion.

lppt

Points to a POINT structure that contains the client coordinates to be converted. The new screen coordinates are copied into this structure if the function succeeds. The POINT structure has the following form.

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The ClientToScreen function replaces the client coordinates in the POINT structure with the screen coordinates. The screen coordinates are relative to the upper left corner of the screen.

See Also

»MapWindowPoints«, »ScreenToClient«


  ClipCursor

BOOL ClipCursor(lprc)
CONST RECT  *lprc;   /* address of structure with rectangle */

The ClipCursor function confines the cursor to a rectangular area on the screen. If a subsequent cursor position (set by the SetCursorPos function or the mouse), lies outside the rectangle, Windows automatically adjusts the position to keep the cursor inside the rectangular area.

Parameters

lprc

Points to the RECT structure that contains the screen coordinates of the upper-left and lower-right corners of the confining rectangle. If this parameter is NULL, the cursor is free to move anywhere on the screen. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The cursor is a shared resource. If an application confines the cursor, it must release the cursor by using ClipCursor before relinquishing control to another application.

The calling process must have WINSTA_WRITEATTRIBUTES access to the window station.

See Also

»GetClipCursor«, »GetCursorPos«, »SetCursorPos«


  CloseClipboard

BOOL CloseClipboard(VOID)

The CloseClipboard function closes the clipboard.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When the window has finished examining or changing the clipboard, close the clipboard by calling the CloseClipboard function. This enables other windows to access the clipboard.

Do not use an object on the clipboard after calling the CloseClipboard function. Instead, use the DuplicateHandle function to create a copy of the data before calling CloseClipboard.

See Also

»DuplicateHandle«, »GetOpenClipboardWindow«, »OpenClipboard«


  CloseEnhMetaFile

HENHMETAFILE CloseEnhMetaFile(hdc)
HDC  hdc;   /* handle of an enhanced-metafile device context */

The CloseEnhMetaFile function closes an enhanced-metafile device context (DC) and returns a handle that identifies an enhanced-format metafile.

Parameters

hdc

Identifies an enhanced-metafile device context.

Return Value

If the function succeeds, the return value is a handle of an enhanced metafile; otherwise, it is NULL.

Comments

An application can use the enhanced-metafile handle returned by this function to perform the following tasks:

•	Display a picture stored in an enhanced metafile

•	Create copies of the enhanced metafile

•	Enumerate, edit, or copy individual records in the enhanced metafile

•	Retrieve an optional description of the metafile contents from the enhanced-metafile header

•	Retrieve a copy of the enhanced-metafile header

•	Retrieve a binary copy of the enhanced metafile

•	Enumerate the colors in the optional palette

•	Convert an enhanced-format metafile into a Windows-format metafile

When the application no longer needs the enhanced metafile handle, it should release the handle by calling the DeleteEnhMetaFile function.

See Also

»CopyEnhMetaFile«, »CreateEnhMetaFile«, »DeleteEnhMetaFile«, »EnumEnhMetaFile«, »GetEnhMetaFileBits«, »GetWinMetaFileBits«, »PlayEnhMetaFile«


  CloseEventLog

BOOL CloseEventLog(hEventLog)
HANDLE  hEventLog;   /* handle to event log */

The CloseEventLog function closes the given event log.

Parameters

hEventLog

Identifies the event log to be closed. This handle is returned by the OpenEventLog function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»OpenEventLog«


  CloseFigure

BOOL CloseFigure(hdc)
HDC  hdc;   /* handle of device context */

The CloseFigure function closes an open figure in a path.

Parameters

hdc

Identifies the device context in which the figure will be closed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To obtain extended error information, use the GetLastError function.

Comments

The CloseFigure function closes the figure by drawing a line from the current position to the first point of the figure (usually, the point specified by the most recent call to the MoveTo function), and connects the lines by using the line join style. If a figure is closed by using the LineTo function instead of CloseFigure, end caps are used to create the corner instead of a join.

The CloseFigure function should only be called if there is an open path bracket in the specified device context.

A figure in a path is open unless it is explicitly closed by using this function. (A figure can be open even if the current point and the starting point of the figure are the same.)

Any line or curve added to the path after CloseFigure starts a new figure.

See Also

»BeginPath«, »EndPath«, »ExtCreatePen«


  CloseHandle

BOOL CloseHandle(hObject)
HANDLE  hObject;   /* handle of object to close */

The CloseHandle function closes an open object handle.

Parameters

hObject

Identifies an open object handle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CloseHandle function closes handles to the following objects:

•	Console input or output

•	Event file

•	File mapping

•	Mutex

•	Named pipe

•	Process

•	Semaphore

•	Thread

CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. Once the last handle of an object is closed, the object is removed from the operating system.

This function does not close module objects.

Use CloseHandle to close handles returned by calls to CreateFile.

See Also

»CreateFile«, »DeleteFile«


  CloseMetaFile

HMETAFILE CloseMetaFile(hdc)
HDC  hdc;   /* handle of metafile device context */

The CloseMetaFile function closes a metafile device context (DC) and returns a handle that identifies a Windows-format metafile.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the CloseEnhMetaFile function.

Parameters

hdc

Identifies a metafile device context used to create a Windows-format metafile.

Return Value

If the function succeeds, the return value is a handle of a Windows-format metafile; otherwise, it is NULL.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions, such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should call the enhanced-format metafile functions.

To convert a Windows-format metafile into a new enhanced-format metafile, use the SetWinMetaFileBits function.

When an application no longer needs the Windows-format metafile handle, it should delete the handle by calling the DeleteMetaFile function.

See Also

»BeginPath«, »CopyMetaFile«, »CreateMetaFile«, »DeleteMetaFile«, »EnumMetaFile«, »GetMetaFileBitsEx«, »PlayMetaFile«, »PolyBezier«, »SetWinMetaFileBits«, »SetWorldTransform«


  ClosePrinter

BOOL ClosePrinter(hPrinter)
HANDLE  hPrinter;   /* handle of printer object */

The ClosePrinter function closes the given printer object.

Parameters

hPrinter

Identifies the printer object to be closed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrinter«, »OpenPrinter«


  CloseProfileUserMapping

BOOL CloseProfileUserMapping(VOID)

The CloseProfileUserMapping function closes all handles to registry keys that are associated with initialization-file mapping.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function is used by applications that impersonate clients and that must be able to change the mapping of initialization files. After an application calls this function, any attempt to read data from or write data to in an initialization file that is mapped to some location under the HKEY_CURRENT_USER key will fail with ERROR_ACCESS_DENIED.

Calls to functions that read data from or write data to in initialization files may be mapped to the registry instead of to the specified files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

See Also

»OpenProfileUserMapping«


  CloseServiceHandle

BOOL CloseServiceHandle(schSCObject)
SC_HANDLE  schSCObject;   /* handle of service or service control manager database */

The CloseServiceHandle function closes a handle to a service control manager database as returned by the OpenSCManager function, or it closes a handle to a service object as returned by either the OpenService or CreateService function.

Parameters

schSCObject

Identifies the service control manager database or the service object to close.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error code may be set by the service control manager. Other error codes may be set by registry functions that are called by the service control manager.

Value	Meaning
ERROR_INVALID_HANDLE	The specified handle is invalid.
Comments

The CloseServiceHandle function does not destroy the service control manager object referred to by the handle. An service control manager object cannot be destroyed. A service object can be destroyed by calling the DeleteService function.

See Also

»CreateService«, »DeleteService«, »OpenSCManager«, »OpenService«


  CloseSound

The CloseSound function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  CloseWindow

BOOL CloseWindow(hwnd)
HWND  hwnd;   /* handle of window to minimize */

The CloseWindow function minimizes (but does not destroy) the given window.

Parameters

hwnd

Identifies the window to be minimized.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The window is minimized by reducing it to the size of an icon and moving the window to the icon area of the screen. Windows displays the window's icon instead of the window and draws the window's title below the icon.

To destroy a window, an application must use the DestroyWindow function.

See Also

»ArrangeIconicWindows«, »IsIconic«, »OpenIcon«


  CombineRgn

int CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, fnCombineMode)
HRGN  hrgnDest;   /* handle of destination region */
HRGN  hrgnSrc1;   /* handle of source region */
HRGN  hrgnSrc2;   /* handle of source region */
int  fnCombineMode;   /* region combining mode */

The CombineRgn function combines two regions and stores the result in a third region. The two regions are combined according to the specified mode.

Parameters

hrgnDest

Identifies a new region with dimensions defined by combining two other regions. (This region must exist before CombineRgn is called.)

hrgnSrc1

Identifies the first of two regions to be combined.

hrgnSrc2

Identifies the second of two regions to be combined.

fnCombineMode

Specifies how the two regions will be combined. This parameter can be one of the following values:

Value	Description
RGN_AND	Creates the intersection of the two combined regions.
RGN_COPY	Creates a copy of the region identified by hrgnSrc1.
RGN_DIFF	Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.
RGN_OR	Creates the union of two combined regions.
RGN_XOR	Creates the union of two combined regions except for any overlapping areas.
Return Value

The return value specifies the type of the resulting region. It can be one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than a single rectangle.
ERROR	No region created.
Comments

The three regions need not be distinct. For example, hrgnSrc1 can equal hrgnDest.

See Also

»CreateEllipticRgn«, »CreateEllipticRgnIndirect«, »CreatePolygonRgn«, »CreatePolyPolygonRgn«, »CreateRectRgn«, »CreateRectRgnIndirect«, »CreateRoundRectRgn«


  CombineTransform

BOOL CombineTransform(lpxformResult, lpxform1, lpxform2)
LPXFORM  lpxformResult;   /* address of combined transformation */
LPXFORM  lpxform1;   /* address of first transformation */
LPXFORM  lpxform2;   /* address of second transformation */

The CombineTransform function concatenates two world-space to page-space transformations.

Parameters

lpxformResult

Points to an XFORM structure that receives the combined transformation.

lpxform1

Points to an XFORM structure that identifies the first transformation.

lpxform2

Points to an XFORM structure that identifies the second transformation. The XFORM structure has the following form:

typedef struct  tagXFORM {  /* xfrm */

    FLOAT eM11;

    FLOAT eM12;

    FLOAT eM21;

    FLOAT eM22;

    FLOAT eDx;

    FLOAT eDy;

} XFORM;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

Applying the combined transformation has the same effect as applying the first transformation and then applying the second transformation.

The three transformations need not be distinct. For example, lpxform1 can point to the same XFORM structure as lpxformResult.

See Also

»GetWorldTransform«, »ModifyWorldTransform«, »SetWorldTransform«


  CommDlgExtendedError

DWORD CommDlgExtendedError(VOID)

The CommDlgExtendedError function identifies the cause of the most recent error to have occurred during the execution of one of the following common dialog box functions:

ChooseColor  ChooseFont FindText  GetFileTitle	GetOpenFileName GetSaveFileName  PrintDlg  ReplaceText
Parameters

This function has no parameters.

Return Value

If the previous call to a common dialog box procedure succeeds, the return value is zero. The return value is CDERR_DIALOGFAILURE if the dialog box could not be created. Otherwise, the return value is a nonzero integer that identifies an error condition.

Comments

Following are the possible CommDlgExtendedError return values and the meaning of each:

Value	Meaning
CDERR_FINDRESFAILURE	The common dialog box procedure failed to find a specified resource.
CDERR_INITIALIZATION	The common dialog box procedure failed during initialization. This error often occurs when insufficient memory is available.
CDERR_LOADRESFAILURE	The common dialog box procedure failed to load a specified resource.
CDERR_LOCKRESFAILURE	The common dialog box procedure failed to lock a specified resource.
CDERR_LOADSTRFAILURE	The common dialog box procedure failed to load a specified string.
CDERR_MEMALLOCFAILURE	The common dialog box procedure was unable to allocate memory for internal structures.
CDERR_MEMLOCKFAILURE	The common dialog box procedure was unable to lock the memory associated with a handle.
CDERR_NOHINSTANCE	The ENABLETEMPLATE flag was set in the Flags member of a structure for the corresponding common dialog box, but the application failed to provide a corresponding instance handle.
CDERR_NOHOOK	The ENABLEHOOK flag was set in the Flags member of a structure for the corresponding common dialog box, but the application failed to provide a pointer to a corresponding hook function.
CDERR_NOTEMPLATE	The ENABLETEMPLATE flag was set in the Flags member of a structure for the corresponding common dialog box, but the application failed to provide a corresponding template.
CDERR_REGISTERMSGFAIL	The RegisterWindowMessage function returned an error value when it was called by the common dialog box procedure.
CDERR_STRUCTSIZE	The lStructSize member of a structure for the corresponding common dialog box is invalid.
CFERR_NOFONTS	No fonts exist.
CFERR_MAXLESSTHANMIN	The size specified in the nSizeMax member of the CHOOSEFONT structure is less than the size specified in the nSizeMin member.
FNERR_BUFFERTOOSMALL	The buffer for a filename is too small. (This buffer is pointed to by the lpstrFile member of the structure for a common dialog box.)
FNERR_INVALIDFILENAME	A filename is invalid.
FNERR_SUBCLASSFAILURE	An attempt to subclass a list box failed because insufficient memory was available.
FRERR_BUFFERLENGTHZERO	A member in a structure for the corresponding common dialog box points to an invalid buffer.
PDERR_CREATEICFAILURE	The PrintDlg function failed when it attempted to create an information context.
PDERR_DEFAULTDIFFERENT	An application called the PrintDlg function with the DN_DEFAULTPRN flag set in the wDefault member of the DEVNAMES structure, but the printer described by the other structure members did not match the current default printer. (This happens when an application stores the DEVNAMES structure and the user changes the default printer by using Control Panel.)
	To use the printer described by the DEVNAMES structure, the application should clear the DN_DEFAULTPRN flag and call the PrintDlg function again. To use the default printer, the application should replace the DEVNAMES structure (and the DEVMODE structure, if one exists) with NULL; this sets the default printer automatically.
PDERR_DNDMMISMATCH	The data in the DEVMODE and DEVNAMES structures describes two different printers.
PDERR_GETDEVMODEFAIL	The printer driver failed to initialize a DEVMODE structure. (This error value applies only to printer drivers written for Windows versions 3.0 and later.)
PDERR_INITFAILURE	Indicates that PrintDlg function failed during initialization, and that there is no more specific extended error code to describe the failure. Think of this as the generic default error code for that function.
PDERR_LOADDRVFAILURE	The PrintDlg function failed to load the device driver for the specified printer.
PDERR_NODEFAULTPRN	A default printer does not exist.
PDERR_NODEVICES	No printer drivers were found.
PDERR_PARSEFAILURE	The PrintDlg function failed to parse the strings in the [devices] section of the WIN.INI file.
PDERR_PRINTERNOTFOUND	The [devices] section of the WIN.INI file did not contain an entry for the requested printer.
PDERR_RETDEFFAILURE	The PD_RETURNDEFAULT flag was set in the Flags member of the PRINTDLG structure, but the hDevMode or hDevNames member was nonzero.
PDERR_SETUPFAILURE	The PrintDlg function failed to load the required resources.
See Also

»ChooseColor«, »ChooseFont«, »FindText«, »GetFileTitle«, »GetOpenFileName«, »GetSaveFileName«, »PrintDlg«, »ReplaceText«


  CompareFileTime

LONG CompareFileTime(lpft1, lpft2)
LPFILETIME  lpft1;   /* address of first file time */
LPFILETIME  lpft2;   /* address of second file time */

The CompareFileTime function compares two 64-bit file times.

Parameters

lpft1

Points to a FILETIME structure that specifies the first 64-bit file time. The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpft2

Points to a FILETIME structure that specifies the second 64-bit file time.

Return Value

If the function succeeds, the return value is one of the following values:

Value	Meaning
−1	First file time is less than second file time.
0	First file time is equal to second file time.
+1	First file time is greater than second file time.
See Also

»GetFileTime«


  CompareStringW

int CompareStringW(lcid, fdwStyle, lpString1, cch1, lpString2, cch2)
LCID  lcid;   /* locale identifier */
DWORD  fdwStyle;   /* comparison-style options */
LPCWSTR  lpString1;   /* address of first string */
int  cch1;   /* number of characters in first string */
LPCWSTR  lpString2;   /* address of second string */
int  cch2;   /* number of characters in second string */

The CompareStringW function compares two wide-character strings of the same locale (according to the supplied locale identifier).

Parameters

lcid

Specifies the locale used for the comparison. An application can use the MAKELCID macro to create a locale identifier. For more information about the MAKELCID macro, see the Microsoft Win32 Programmer's Reference, Volume 5.

fdwStyle

Specifies flags indicating the character properties to use when comparing the two strings. These flags are not set by defaults. This parameter can be any combination of the following values:

Value	Meaning
NORM_IGNORECASE	Ignore case.
NORM_IGNORENONSPACE	Ignore nonspacing characters.
NORM_IGNORESYMBOLS	Ignore symbols.
SORT_STRINGSORT	Treat punctuation the same as symbols.
lpString1

Points to the first string to be compared.

cch1

Specifies the number of characters in the string pointed to by the lpString1 parameter. This count does not include the null-terminating character, if any. If this value is −1, the string is assumed to be null terminated and the length is calculated automatically.

lpString2

Points to the second string to be compared.

cch2

Specifies the number of characters in the string pointed to by the lpString2 parameter. This count does not include the null-terminating character, if any. If this value is −1, the string is assumed to be null terminated and the length is calculated automatically.

Return Value

If the function succeeds, the return value is one of the following values:

Value	Meaning
1	The string pointed to by the lpString1 parameter is less in lexical value than the string pointed to by the lpString2 parameter.
2	The string pointed to by lpString1 is equal in lexical value to the string pointed to by lpString2.
3	The string pointed to by lpString1 is greater in lexical value than the string pointed to by lpString2.
If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Comments

Note that if the return value is 2, the two strings are "equal" in the collation sense, though not necessarily identical.

To maintain the C runtime convention of comparing strings, the value 2 can be subtracted from a non-zero return value. The meaning of 0, ==0 and 0 is then consistent with the C runtimes.

If the two strings are of different lengths, they are compared up to the length of the shortest one. If they are equal to that point, then the return value will indicate that the longer string is greater.

For more information about locale identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

Normally, strings are compared using what is called a "word sort" technique. In a word sort, all punctuation marks and other non-alphanumeric characters, except for the hyphen and the apostrophe, come before any alphanumeric character. The hyphen and the apostrophe are treated differently than the other non-alphanumeric symbols, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list.

If the SORT_STRINGSORT flag is specified, strings are compared using what is called a "string sort" technique. In a string sort, the hyphen and apostrophe are treated just like any other non-alphanumeric symbols: they come before

Word Sort	String Sort
&aardvark	&aardvark
aardentvark	aard-vark
aardvark	aardentvark
aard-vark	aardvark
bills	bill's
bill's	bills
con	co-op
coop	con
co-op	coop
t-ant	t-ant
tanya	t-aria
t-aria	tanya
tomatoes	tom's
toms	tomatoes
tom's	toms
The lstrcmp and lstrcmpi functions use a word sort. The CompareStringW and LCMapStringW functions default to using a word sort, but use a string sort if their caller specifies a SORT_STRINGSORT.

See Also

»FoldStringW«, »GetSystemDefaultLCID«, »GetUserDefaultLCID«, »LCMapStringW«, »lstrcmp«, »lstrcmpi«


  ConfigurePort

BOOL ConfigurePort(lpszName, hwnd, lpszPortName)
LPTSTR  lpszName;   /* address of server name */
HWND  hwnd;   /* handle of window that displays dialog box */
LPTSTR  lpszPortName;   /* address of port name */

This function displays the port-configuration dialog box for the given port on the specified server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the given port exists. If this string is NULL, the port is local.

hwnd

Identifies the parent window of the port-configuration dialog.

lpszPortName

Points to a null-terminated string that specifies the name of the port to be configured.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before calling this function, an application should call the EnumPorts function to determine valid port names.

See Also

»EnumPorts«


  ConnectNamedPipe

BOOL ConnectNamedPipe(hNamedPipe, lpo)
HANDLE  hNamedPipe;   /* handle of named pipe to connect */
LPOVERLAPPED  lpo;   /* address of overlapped structure */

The ConnectNamedPipe function enables a named pipe server process to wait for a client process to connect to an instance of a named pipe. A client process connects by calling either CreateFile or CallNamedPipe.

Parameters

hNamedPipe

Identifies the server end of a named pipe instance. This handle is returned by the CreateNamedPipe function.

lpo

Points to an OVERLAPPED structure. This parameter can be NULL if overlapped operation is not desired. For a description of how the wait mode and the overlapped mode of the hNamedPipe handle affect the behavior of this function, see the Comments section.

The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A named pipe server process can use the ConnectNamedPipe function with a newly created pipe instance. It can also be used with an instance that was previously connected to another client process, in which case the server process must first call the DisconnectNamedPipe function to disconnect the handle from the previous client before the handle can be reconnected to a new client. Otherwise, ConnectNamedPipe returns FALSE, and GetLastError returns ERROR_NO_DATA if the previous client has closed its handle or ERROR_PIPE_CONNECTED if it has not closed its handle.

The behavior of ConnectNamedPipe depends on two conditions: whether the pipe handle's wait mode is set to blocking or nonblocking, and whether the function is set to execute synchronously or in overlapped mode. A server initially specifies a pipe handle's wait mode in the CreateNamedPipe function, and it can be changed in the SetNamedPipeHandleState function. The function is executed as an overlapped operation if FILE_FLAG_OVERLAPPED was specified when the pipe handle was created, and if the lpOverlapped parameter is not NULL. Otherwise, the function is executed synchronously. If an overlapped operation is used, the OVERLAPPED structure pointed to by lpOverlapped must contain a handle to a manual reset event object (which the server can create by using the CreateEvent function).

If lpo is NULL, the operation executes synchronously. The function does not return until a client is connected or an error occurs. The function returns TRUE if a client connected after the function was called. If a client connected before the function was called, the function returns FALSE and GetLastError returns ERROR_PIPE_CONNECTED. This can happen if a client connects in the interval between the call to CreateNamedPipe and the call to ConnectNamedPipe, in which case, there is a good connection between client and server, even though the function returned FALSE.

If lpo is not NULL, the operation executes asynchronously. The function returns immediately with a return value of FALSE. If a client process connected before the function was called, GetLastError returns ERROR_PIPE_CONNECTED. Otherwise, GetLastError returns ERROR_IO_PENDING, which indicates that the operation is executing in the background. When this happens, the event object in the OVERLAPPED structure is set to the not-signaled state before ConnectNamedPipe returns, and it is set to the signaled state when a client connects to this instance of the pipe. The server process can use any of the wait functions — WaitForSingleObject, WaitForMultipleObjects, WaitForSingleObjectEx, WaitForMultipleObjectsEx, SleepEx — to determine when the state of the event object is signaled, and it can then use the GetOverlappedResult function to determine the results of the ConnectNamedPipe operation.

If the specified pipe handle is in nonblocking mode, ConnectNamedPipe always returns immediately. In nonblocking mode, ConnectNamedPipe returns TRUE the first time it is called for a pipe instance that is disconnected from a previous client. This indicates that the pipe is now available to be connected to a new client process. In all other situations, ConnectNamedPipe on a nonblocking mode pipe handle returns FALSE. In these cases, GetLastError returns ERROR_PIPE_LISTENING if no client is connected, ERROR_PIPE_CONNECTED if a client is connected, and ERROR_NO_DATA if a previous client has closed its pipe handle but the server has not disconnected. Note that a good connection between client and server exists only after the ERROR_PIPE_CONNECTED error is received.

Note that nonblocking mode is supported for compatibility with Microsoft® LAN Manager version 2.0, and should not be used to achieve asynchronous I/O with named pipes.

See Also

»CreateFile«, »CallNamedPipe«, »CreateEvent«, »CreateNamedPipe«, »DisconnectNamedPipe«, »GetOverlappedResult«, »SetNamedPipeHandleState«, »SleepEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«


  ContinueDebugEvent

BOOL ContinueDebugEvent(idProcess, idThread, fdwContinueStatus)
DWORD  idProcess;   /* process to continue */
DWORD  idThread;   /* thread to continue */
DWORD  fdwContinueStatus;   /* continuation status */

The ContinueDebugEvent function enables a debugger to continue a thread that previously reported a debugging event.

Parameters

idProcess

Identifies the process to continue.

idThread

Identifies the thread to continue. The combination of process identifier and thread identifier must identify a thread that has previously reported a debugging event.

fdwContinueStatus

Specifies how to continue the thread that reported the debugging event.

If the DBG_CONTINUE flag is specified for this parameter and the thread specified by the idThread parameter previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function stops all exception processing and continues the thread. For any other debugging event, this flag simply continues the thread.

If the DBG_EXCEPTION_NOT_HANDLED flag is specified for this parameter and the thread specified by idThread previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function continues exception processing. If this is a first-chance exception event, the search and dispatch logic of the structured exception handler is invoked; otherwise, the process is terminated. For any other debugging event, this flag simply continues the thread.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Only the thread that created idProcess with the CreateProcess function can call ContinueDebugEvent.

After this function succeeds, the specified thread continues. Depending on the debugging event previously reported by the thread, certain side effects occur. If the continued thread previously reported an EXIT_THREAD_DEBUG_EVENT debugging event, ContinueDebugEvent closes the handle the debugger has to the thread. If the continued thread previously reported an EXIT_PROCESS_DEBUG_EVENT debugging event, ContinueDebugEvent closes the handles the debugger has to the process and to the thread.

See Also

»CreateProcess«


  ControlService

BOOL ControlService(schService, fdwControl, lpssServiceStatus)
SC_HANDLE  schService;   /* handle of service */
DWORD  fdwControl;   /* control code */
LPSERVICE_STATUS  lpssServiceStatus;   /* address of service status structure */

The ControlService function sends a control code to a Win32 service.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function. The access required for this handle depends on the fdwControl code requested.

fdwControl

Specifies the requested control code. This value can be one of the standard control codes in the table, or it can be a user-defined control code in the range of 128 to 255, inclusive. For user-defined control codes, the schService handle must have SERVICE_USER_DEFINE_CONTROL access, and the service defines the action associated with the control code.

Value	Meaning
SERVICE_CONTROL_STOP
	Requests the service to stop. The schService handle must have SERVICE_STOP access.
SERVICE_CONTROL_PAUSE
	Requests the service to pause. The schService handle must have SERVICE_PAUSE_CONTINUE access.
SERVICE_CONTROL_CONTINUE
	Requests the paused service to resume. The schService handle must have SERVICE_PAUSE_CONTINUE access.
SERVICE_CONTROL_INTERROGATE
	Requests the service to update immediately its current status information to the service control manager. The schService handle must have SERVICE_INTERROGATE access.
SERVICE_CONTROL_SHUTDOWN
	The ControlService function fails if this control code is specified.
lpssServiceStatus

Points to a SERVICE_STATUS structure where the latest status information of the service is returned. The information returned reflects the most recent status reported by the service to the service control manager. The SERVICE_STATUS structure has the following form:

typedef struct _SERVICE_STATUS { /* ss */

    DWORD dwServiceType;

    DWORD dwCurrentState;

    DWORD dwControlsAccepted;

    DWORD dwWin32ExitCode;

    DWORD dwServiceSpecificExitCode;

    DWORD dwCheckPoint;

    DWORD dwWaitHint;

} SERVICE_STATUS, *LPSERVICE_STATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with the necessary access.
ERROR_DEPENDENT_SERVICES_RUNNING
	The service cannot be stopped because other running services are dependent on it.
ERROR_INVALID_SERVICE_CONTROL
	The requested control code is not valid, or it is unacceptable to the service.
ERROR_SERVICE_CANNOT_ACCEPT_CTRL
	The requested control code cannot be sent to the service because the state of the service is SERVICE_STOPPED, SERVICE_START_PENDING, or SERVICE_STOP_PENDING.
ERROR_SERVICE_NOT_ACTIVE
	The service has not been started.
ERROR_SERVICE_REQUEST_TIMEOUT
	The service did not respond to the start request in a timely fashion.
Comments

The ControlService function asks the service control manager to send the requested control code to the service. The service control manager sends the code if the service accepts the control and if the service is in a controllable state. The QueryServiceStatus or ControlService function returns a SERVICE_STATUS structure whose dwCurrentState and dwControlsAccepted members indicate the current state and controls accepted by a running Win32 service.

All running services accept the SERVICE_CONTROL_INTERROGATE control code by default. Each service specifies the other control codes that it accepts when it calls the SetServiceStatus function to report its status.

The following table shows the action of the service control manager in each of the possible service states:

Service state	Stop	Other controls
STOPPED	(c)	(c)
STOP_PENDING	(b)	(b)
START_PENDING	(a)	(b)
RUNNING	(a)	(a)
CONTINUE_PENDING	(a)	(a)
PAUSE_PENDING	(a)	(a)
PAUSED	(a)	(a)
(a) If the service accepts this control code, send the request to the service;	otherwise, ControlService returns FALSE and GetLastError returns ERROR_INVALID_SERVICE_CONTROL.
(b) The service is not in a controllable state, so ControlService returns	FALSE and GetLastError returns ERROR_SERVICE_CANNOT_ACCEPT_CTRL.
(c) The service is not in a controllable state, so ControlService returns	FALSE and GetLastError returns ERROR_SERVICE_NOT_ACTIVE.
See Also

»CreateService«, »OpenService«, »QueryServiceStatus«, »SetServiceStatus«


  CopyAcceleratorTable

int CopyAcceleratorTable(hacclOriginal, lpacclCopy, cAccel)
HACCEL  hacclOriginal;   /* handle of accelerator table to copy */
LPACCEL  lpacclCopy;   /* address of structure receiving copy */
int  cAccel;   /* number of entries in table being copied */

The CopyAcceleratorTable function copies the given accelerator table. This function is used to obtain the accelerator-table data that corresponds to an accelerator-table handle, or to determine the size of the accelerator-table data.

Parameters

hacclOriginal

Identifies the accelerator table to be copied.

lpacclCopy

Points to an array of ACCEL structures where the accelerator-table information is to be copied. The ACCEL structure has the following format:

typedef struct tagACCEL { /* accl */

    BYTE   fVirt;

    WORD   key;

    WORD   cmd;

} ACCEL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cAccel

Specifies the number of ACCEL structures to copy to the buffer pointed to by the lpacclCopy parameter.

Return Value

If the lpacclCopy parameter is NULL, the return value specifies the number of accelerator-table entries in the original table. Otherwise, it specifies the number of accelerator-table entries that were copied.

See Also

»CreateAcceleratorTable«, »DestroyAcceleratorTable«, »LoadAccelerators«, »TranslateAccelerator«


  CopyCursor

HCURSOR CopyCursor(hcur)
HCURSOR  hcur;   /* handle of cursor to copy */

The CopyCursor function copies a cursor.

Parameters

hcur

Identifies the cursor to be copied.

Return Value

If the function succeeds, the return value is the handle of the duplicate cursor; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

CopyCursor enables an application or dynamic-link library to obtain the handle of a cursor shape owned by another module. Then, if the other module is freed, the application is still able to use the cursor shape.

See Also

»CopyIcon«, »GetCursor«, »SetCursor«, »ShowCursor«


  CopyEnhMetaFile

HENHMETAFILE CopyEnhMetaFile(hemfSrc, lpszFile)
HENHMETAFILE  hemfSrc;   /* handle of an enhanced metafile */
LPTSTR  lpszFile;   /* address of a filename string */

The CopyEnhMetaFile function copies the contents of an enhanced-format metafile to the given file.

Parameters

hemfSrc

Identifies the source enhanced metafile.

lpszFile

Points to the name of the destination file. If this parameter is NULL, the source metafile is copied to memory.

Return Value

If the function succeeds, the return value is a handle of the copy of the enhanced metafile; otherwise, it is NULL. To obtain extended error information, use the GetLastError function.

Comments

Where text arguments must use Unicode™ characters, use this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

Applications can use metafiles stored in memory for temporary operations.

When the application no longer needs the enhanced-metafile handle, it should delete the handle by calling the DeleteEnhMetaFile function.

See Also

»DeleteEnhMetaFile«


  CopyFile

BOOL CopyFile(lpszExistingFile, lpszNewFile, fFailIfExists)
LPTSTR  lpszExistingFile;   /* address of name of an existing file */
LPTSTR  lpszNewFile;   /* address of filename to copy to */
BOOL  fFailIfExists;   /* flag for operation if file exists */

The CopyFile function copies an existing file to a new file.

Parameters

lpszExistingFile

Points to a null-terminated string that specifies the name of an existing file.

lpszNewFile

Points to a null-terminated string that specifies the name of the new file.

fFailIfExists

Specifies how this operation is to proceed if a file of the same name as that specified by lpszNewFile already exists. If this parameter is TRUE and the new file already exists, the function fails. If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CopyFile function does not copy a file onto itself.

Security attributes for the existing file are not copied to the new file.

See Also

»MoveFile«


  CopyIcon

HICON CopyIcon(hicon)
HICON  hicon;   /* handle of icon to copy */

The CopyIcon function copies the given icon from another module to the current module.

Parameters

hicon

Identifies the icon to be copied.

Return Value

If the function succeeds, the return value is the handle of the duplicate icon; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The CopyIcon function enables an application or dynamic-link library to get its own handle of an icon owned by another module. If the other module is freed, the application icon will still be able to use the icon.

See Also

»CopyCursor«, »DrawIcon«


  CopyLZFile

The CopyLZFile function is obsolete. It is provided only for backwards compatibility. Win32 applications should use the LZCopy function.

See Also

»LZCopy«


  CopyMemory

VOID CopyMemory (Destination, Source, Length)
PVOID  Destination;   /* address of copy destination */
CONST VOID *  Source;   /* address of block to copy */
DWORD  Length;   /* size in bytes of block to copy */

The CopyMemory function copies a block of memory from one location to another.

Parameters

Destination

Points to the starting address of the destination of the copy.

Source

Points to the starting address of the block of memory to copy.

Length

Specifies the size in bytes of the block of memory to copy.

Return Value

This function has no return value.

Comments

If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemory function.

See Also

»FillMemory«, »MoveMemory«, »ZeroMemory«


  CopyMetaFile

HMETAFILE CopyMetaFile(hmfSrc, lpszFile)
HMETAFILE  hmfSrc;   /* handle of a Windows format metafile */
LPTSTR  lpszFile;   /* address of a filename string */

The CopyMetaFile function copies the content of a Windows-format metafile to the given file.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the CopyEnhMetaFile function.

Parameters

hmfSrc

Identifies the source Windows-format metafile.

lpszFile

Points to the name of the destination file. If this parameter is NULL, the source metafile is copied to memory.

Return Value

If the function succeeds, the return value is a handle of the copy of the Windows-format metafile; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

This function supports only applications designed for Microsoft Windows version 3.x. It does not record or play back the new graphics device interface (GDI) functions, such as PolyBezier.

Where text arguments must use Unicode™ characters, use this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

When the application no longer needs the Windows-format metafile handle, it should delete the handle by calling the DeleteMetaFile function.

See Also

»DeleteMetaFile«, »GetLastError«


  CopyRect

BOOL CopyRect(lprcDst, lprcSrc)
LPRECT  lprcDst;   /* address of struct. for destination rectangle */
CONST RECT  *lprcSrc;   /* address of struct. with source rectangle */

The CopyRect function copies the coordinates of one rectangle to another.

Parameters

lprcDst

Points to the RECT structure that will receive the logical coordinates of the source rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprcSrc

Points to the RECT structure whose coordinates are to be copied.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetRect«, »SetRectEmpty«


  CopySid

BOOL CopySid(cbDestinationSid, psidDestination, psidSource)
DWORD  cbDestinationSid;   /* size of buffer for copied SID */
PSID  psidDestination;   /* address of buffer for copied SID */
PSID  psidSource;   /* address of source SID */

The CopySid function copies a security identifier (SID) to a buffer.

Parameters

cbDestinationSid

Specifies the length, in bytes, of the buffer receiving the copy of the SID.

psidDestination

Points to a buffer recieving a copy of the source SID structure.

psidSource

Points to an SID structure the function copies to the buffer pointed to by the psidDestination parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can use the CopySid function to make a copy of an SID in an access token (in a TOKEN_GROUPS structure, for instance) to use in an access-control entry (ACE).

See Also

»AllocateAndInitializeSid«, »EqualSid«, »GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidLengthRequired«, »GetSidSubAuthority«, »GetSidSubAuthorityCount«, »InitializeSid«, »IsValidSid«


  CountClipboardFormats

int CountClipboardFormats(VOID)

The CountClipboardFormats function retrieves the number of different data formats currently on the clipboard.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of different data formats currently on the clipboard; otherwise, it is zero. To get extended error information, use the GetLastError function.

See Also

»EnumClipboardFormats«, »RegisterClipboardFormat«


  CountVoiceNotes

The CountVoiceNotes function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  CPlApplet

LONG CALLBACK* CPlApplet(hwndCPl, uMsg, lParam1, lParam2)
HWND  hwndCPl;   /* handle of Control Panel window */
UINT  uMsg;   /* message */
LPARAM  lParam1;   /* first message parameter */
LPARAM  lParam2;   /* second message parameter */

The CPlApplet function is a library-defined callback function that serves as the entry point for a Windows Control Panel dynamic-link library (DLL).

Parameters

hwndCPl

Identifies the main Control Panel window.

uMsg

Specifies the message being sent to the DLL.

lParam1

Specifies additional message-dependent information.

lParam2

Specifies additional message-dependent information.

Return Value

The return value depends on the message. For more information, see the descriptions of the individual Control Panel messages in the Microsoft Win32 Programmer's Reference, Volume 5.

Comments

Use the hwndCPl parameter for dialog boxes or other windows that require a handle of a parent window.


  CreateAcceleratorTable

HACCEL CreateAcceleratorTable(lpaccl, cEntries)
LPACCEL  lpaccl;   /* address of structure array with accelerator data */
int  cEntries;   /* number of structures in the array */

The CreateAcceleratorTable function creates an accelerator table.

Parameters

lpaccl

Points to an array of ACCEL structures that describes the accelerator table. The ACCEL structure has the following form:

typedef struct tagACCEL { /* accl */

    BYTE   fVirt;

    WORD   key;

    WORD   cmd;

} ACCEL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cEntries

Specifies the number of ACCEL structures in the array.

Return Value

If the function succeeds, the return value is the handle of the created accelerator table; otherwise, it is NULL.

Comments

Before an application closes, it must use the DestroyAcceleratorTable function to destroy each accelerator table that it created by using the CreateAcceleratorTable function.

See Also

»CopyAcceleratorTable«, »DestroyAcceleratorTable«, »LoadAccelerators«, »TranslateAccelerator«


  CreateBitmap

HBITMAP CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, lpvBits)
int  nWidth;   /* bitmap width, in pixels */
int  nHeight;   /* bitmap height, in pixels */
UINT  cPlanes;   /* number of color planes used by device */
UINT  cBitsPerPel;   /* number of bits required to identify a color */
CONST VOID  *lpvBits;   /* address of array containing color data */

The CreateBitmap function creates a bitmap with the given width, height, and color format (color planes and bits per pixel).

Parameters

nWidth

Specifies the bitmap width, in pixels.

nHeight

Specifies the bitmap height, in pixels.

cPlanes

Specifies the number of color planes used by the device.

cBitsPerPel

Specifies the number of bits required to identify the color of a single pixel.

lpvBits

Points to an array of color data used to set the colors in a rectangle of pixels. Each scan line in the rectangle must be word aligned (scan lines that are not word aligned must be padded with zeros). If this parameter is NULL, the new bitmap is undefined.

Return Value

If the function succeeds, the return value is a handle of a bitmap; otherwise, it is NULL.

Comments

The CreateBitmap function should be used only to create monochrome bitmaps. The CreateDIBitmap function should be used to create color bitmaps. If the bitmap is monochrome, zeros represent the foreground color and ones represent the background color for the destination device context.

After a bitmap is created, it can be selected into a device context by calling the SelectObject function.

See Also

»CreateDIBitmap«, »DeleteObject«, »GetBitmapBits«, »SelectObject«, »SetBitmapBits«


  CreateBitmapIndirect

HBITMAP CreateBitmapIndirect(lpbm)
LPBITMAP  lpbm;   /* address of the bitmap data */

The CreateBitmapIndirect function creates a bitmap with the given width, height, and color format (color planes and bits per pixel).

Parameters

lpbm

Points to a BITMAP structure that contains information about the bitmap. The BITMAP structure has the following form:

typedef struct tagBITMAP {  /* bm */

   LONG   bmType;

   LONG   bmWidth;

   LONG   bmHeight;

   LONG   bmWidthBytes;

   WORD   bmPlanes;

   WORD   bmBitsPixel;

   LPVOID bmBits;

} BITMAP;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle of the bitmap; otherwise, it is NULL.

Comments

The CreateBitmapIndirect function should be used only to create monochrome bitmaps. The CreateDIBitmap function should be used to create color bitmaps. If the bitmap is monochrome, zeros represent the foreground color and ones represent the background color for the destination device context.

After a bitmap is created, it can be selected into a device context by calling the SelectObject function.

See Also

»BitBlt«, »CreateBitmap«, »CreateDIBitmap«, »SelectObject«


  CreateBrushIndirect

HBRUSH CreateBrushIndirect(lplb)
LPLOGBRUSH  lplb;   /* address of structure describing brush */

The CreateBrushIndirect function creates a logical brush that has the specified style, color, and pattern.

Parameters

lplb

Points to a LOGBRUSH structure that contains information about the brush. The LOGBRUSH structure has the following form:

typedef struct tagLOGBRUSH { /* lb */

   UINT     lbStyle;

   COLORREF lbColor;

   LONG     lbHatch;

} LOGBRUSH;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value identifies a logical brush; otherwise, it is NULL.

Comments

A brush is a bitmap that Windows uses to paint the interiors of filled shapes.

After an application creates a brush by calling CreateBrushIndirect, it can select it into any device context by calling the SelectObject function.

A brush created by using a monochrome bitmap (one color plane, one bit per pixel) is drawn using the current text and background colors. Pixels represented by a bit set to 0 are drawn with the current text color; pixels represented by a bit set to 1 are drawn with the current background color.

See Also

»DeleteObject«, »GetBrushOrgEx«, »SelectObject«, »SetBrushOrgEx«


  CreateCaret

BOOL CreateCaret(hwnd, hbmp, nWidth, nHeight)
HWND  hwnd;   /* handle of owner window */
HBITMAP  hbmp;   /* handle of bitmap for caret shape */
int  nWidth;   /* caret width */
int  nHeight;   /* caret height */

The CreateCaret function creates a new shape for the system caret and assigns ownership of the caret to the given window. The caret shape can be a line, a block, or a bitmap.

Parameters

hwnd

Identifies the window that owns the caret.

hbmp

Identifies the bitmap that defines the caret shape. If this parameter is NULL, the caret is solid. If this parameter is 1, the caret is gray. If this parameter is a bitmap handle, the caret is the specified bitmap. The bitmap handle must have been created by the CreateBitmap, CreateDIBitmap, or LoadBitmap function.

If hbmp is a bitmap handle, CreateCaret ignores the nWidth and nHeight parameters; the bitmap defines its own width and height.

nWidth

Specifies the width of the caret in logical units. If this parameter is NULL, the width is set to the system-defined window border width. If hbmp is a bitmap handle, CreateCaret ignores this parameter.

nHeight

Specifies the height, in logical units, of the caret. If this parameter is NULL, the height is set to the system-defined window border height. If hbmp is a bitmap handle, CreateCaret ignores this parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The nWidth and nHeight parameters specify the caret's width and height, in logical units; the exact width and height, in pixels, depend on the window's mapping mode.

CreateCaret automatically destroys the previous caret shape, if any, regardless of the window that owns the caret. The caret is hidden until the application calls the ShowCaret function to make the caret visible.

The caret is a shared resource; there is only one caret in the system. A window should create a caret only when it has the keyboard focus or is active. The window should destroy the caret before losing the keyboard focus or becoming inactive.

You can retrieve the width or height of the system's window border by using the GetSystemMetrics function, specifying the SM_CXBORDER and SM_CYBORDER indices. Using the window border width or height guarantees that the caret will be visible on a high-resolution screen.

See Also

»CreateBitmap«, »CreateDIBitmap«, »DestroyCaret«, »GetSystemMetrics«, »HideCaret«, »LoadBitmap«, »ShowCaret«


  CreateCompatibleBitmap

HBITMAP CreateCompatibleBitmap(hdc, nWidth, nHeight)
HDC  hdc;   /* handle of device context */
int  nWidth;   /* width of bitmap, in pixels */
int  nHeight;   /* height of bitmap, in pixels */

The CreateCompatibleBitmap function creates a bitmap compatible with the device that is associated with the given device context (DC).

Parameters

hdc

Identifies a device context.

nWidth

Specifies the bitmap width, in pixels.

nHeight

Specifies the bitmap height, in pixels.

Return Value

If the function succeeds, the return value is a handle of the bitmap; otherwise, it is NULL.

Comments

The color format of the bitmap created by this function matches the color format of the device identified by the hdc parameter. This bitmap can be selected into any memory DC that is compatible with the original device.

Because memory DCs allow both color and monochrome bitmaps, the format of the bitmap returned by the CreateCompatibleBitmap function differs when the specified DC is a memory DC. However, a compatible bitmap that was created for a nonmemory DC always possesses the same color format and uses the same color palette as the specified DC.

See Also

»DeleteObject«, »SelectObject«


  CreateCompatibleDC

HDC CreateCompatibleDC(hdc)
HDC  hdc;   /* handle of memory device context */

The CreateCompatibleDC function creates a memory device context (DC) compatible with the given device.

Parameters

hdc

Identifies the device context. If this handle is NULL, the function creates a memory device context compatible with the application's current screen.

Return Value

If the function succeeds, the return value is the handle of a memory device context; otherwise, it is NULL.

Comments

Before an application can use a memory device context for drawing operations, it must select a bitmap of the correct width and height into the DC. Once a bitmap has been selected, the DC can be used to prepare images that will be copied to the screen or printed.

This function can only be used with devices that support raster operations. An application can determine whether a device supports these operations by calling the GetDeviceCaps function.

When a memory DC is no longer needed, an application must delete it by calling the DeleteDC function.

See Also

»CreateCompatibleBitmap«, »DeleteDC«, »GetDeviceCaps«


  CreateConsoleScreenBuffer

HANDLE CreateConsoleScreenBuffer(fdwAccess, fdwShareMode, lpsa, fdwType, pvReserved)
DWORD  fdwAccess;   /* access flag */
DWORD  fdwShareMode;   /* buffer share mode */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security attributes */
DWORD  fdwType;   /* type of buffer to create */
PVOID  pvReserved;   /* reserved */

The CreateConsoleScreenBuffer function creates a console screen buffer and returns a handle of it.

Parameters

fdwAccess

Specifies the desired access to the console screen buffer. This parameter can be one or both of the following values:

Value	Meaning
GENERIC_READ	Requests read access to the console screen buffer, enabling the process to read data from the buffer.
GENERIC_WRITE	Requests write access to the console screen buffer, enabling the process to write data to the buffer.
fdwShareMode

Specifies how this console screen buffer can be shared. This parameter can be zero, indicating that the buffer cannot be shared, or one or both of the following two values:

Value	Meaning
FILE_SHARE_READ	Other open operations can be performed on the console screen buffer for read access.
FILE_SHARE_WRITE	Other open operations can be performed on the console screen buffer for write access.
lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the console screen buffer. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fdwType

Specifies the type of console screen buffer to create. The only currently supported screen buffer type is CONSOLE_TEXTMODE_BUFFER.

pvReserved

Reserved for possible future use; should be NULL.

Return Value

If the function succeeds, the return value is a handle of the new console screen buffer; otherwise, it is INVALID_HANDLE_VALUE. To get extended error information, use the GetLastError function.

Comments

A console can have multiple screen buffers but only one active screen buffer. Inactive screen buffers can be accessed for reading and writing, but only the active screen buffer is displayed. To make the new screen buffer the active screen buffer, use SetConsoleActiveScreenBuffer.

The calling process can use the returned handle in any function that requires a handle of a console screen buffer, subject to the limitations of access specified by the fdwAccess parameter.

The calling process can use the DuplicateHandle function to create a duplicate screen buffer handle that has different access or inheritability from the original handle. However, DuplicateHandle cannot be used to create a duplicate that is valid for a different process (except through inheritance).

To close the screen buffer handle, use the CloseHandle function.

See Also

»GetConsoleScreenBufferInfo«, »SetConsoleActiveScreenBuffer«, »SetConsoleScreenBufferSize«


  CreateCursor

HCURSOR CreateCursor(hinst, xHotSpot, yHotSpot, nWidth, nHeight, pvANDplane,
pvXORplane)
HINSTANCE  hinst;   /* handle of application instance */
int  xHotSpot;   /* horizontal position of hot spot */
int  yHotSpot;   /* vertical position of hot spot */
int  nWidth;   /* cursor width */
int  nHeight;   /* cursor height */
CONST VOID  *pvANDplane;   /* address of AND bitmask array */
CONST VOID  *pvXORplane;   /* address of XOR bitmask array */

The CreateCursor function creates a cursor having the specified size, bit patterns, and hot spot.

Parameters

hinst

Identifies the current instance of the application creating the cursor.

xHotSpot

Specifies the horizontal position of the cursor's hot spot.

yHotSpot

Specifies the vertical position of the cursor's hot spot.

nWidth

Specifies the width, in pixels, of the cursor.

nHeight

Specifies the height, in pixels, of the cursor.

pvANDplane

Points to an array of bytes that contains the bit values for the AND bitmask of the cursor, as in a device-dependent monochrome bitmap.

pvXORplane

Points to an array of bytes that contains the bit values for the XOR bitmask of the cursor, as in a device-dependent monochrome bitmap.

Return Value

If the function succeeds, the return value identifies the cursor; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The nWidth and nHeight parameters must specify a width and height that are supported by the current display driver, because the system cannot create cursors of other sizes. To determine the width and height supported by the display driver, use the GetSystemMetrics function, specifying the SM_CXCURSOR or SM_CYCURSOR value.

Before closing, an application must call the DestroyCursor function to free any system resources associated with the cursor.

See Also

»CreateIcon«, »DestroyCursor«, »GetModuleHandle«, »GetSystemMetrics«, »SetCursor«


  CreateDC

HDC CreateDC(lpszDriver, lpszDevice, lpszOutput, lpInitData)
LPCTSTR  lpszDriver;   /* address of string specifying driver name */
LPCTSTR  lpszDevice;   /* address of string specifying device name */
LPCTSTR  lpszOutput;   /* address of string specifying port or file */
CONST DEVMODE  *lpInitData;   /* address of optional printer data */

The CreateDC function creates a device context (DC) for the specified device by using the given name.

Parameters

lpszDriver

Points to a null-terminated character string that specifies either "DISPLAY" for a display driver, or the name of a printer driver, which is usually "WINSPOOL". This parameter is ignored; it is present only to keep the function prototype identical with Windows 3.1.

lpszDevice

Points to a null-terminated character string that specifies the name of the specific output device being used, as shown by the Print Manager (for example, "Epson FX-80"). It is not the printer model name. The lpszDevice parameter must be used.

lpszOutput

Points to a null-terminated character string. This parameter is ignored; it is present only to keep the function prototype identical with Windows 3.1.

lpInitData

Points to a DEVMODE structure containing device-specific initialization data for the device driver. The DocumentProperties function retrieves this structure filled in for a given device. The lpInitData parameter must be NULL if the device driver is to use the default initialization (if any) specified by the user through Windows Print Manager.

Return Value

If the function succeeds, the return value is the handle of a device context for the specified device; otherwise, it is NULL.

See Also

»DocumentProperties«


  CreateDialog

HWND CreateDialog(hinst, lpszTemplate, hwndOwner, dlgprc)
HANDLE  hinst;   /* handle of application instance */
LPCTSTR  lpszTemplate;   /* identifies dialog box template name */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */

The CreateDialog function creates a modeless dialog box from a dialog box template resource.

Parameters

hinst

Identifies an instance of the module whose executable file contains the dialog box template.

lpszTemplate

Identifies the dialog box template. This parameter is either the address of a null-terminated character string that specifies the name of the dialog box template or an integer value that specifies the resource identifier of the dialog box template. If the parameter specifies a resource identifier, its high-order word must be zero and its low-order word must contain the identifier. You can use the MAKEINTRESOURCE macro to create this value.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

Return Value

If the function succeeds, the return value is the handle of the dialog box; otherwise, it is NULL.

Comments

The CreateDialog function uses the CreateWindowEx function to create the dialog box. CreateDialog then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box if the template specifies the WS_VISIBLE style. Finally, CreateDialog returns the window handle of the dialog box.

After CreateDialog returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function.

See Also

»CreateDialogIndirect«, »CreateDialogIndirectParam«, »CreateDialogParam«, »CreateWindowEx«, »DestroyWindow«, »DialogBox«, »DialogProc«, »ShowWindow«


  CreateDialogIndirect

HWND CreateDialogIndirect(hinst, lpTemplate, hwndOwner, dlgprc)
HANDLE  hinst;   /* handle of application instance */
LPCDLGTEMPLATE  lpTemplate;   /* address of dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */

The CreateDialogIndirect function creates a modeless dialog box from a dialog box template in memory.

Parameters

hinst

Identifies the instance of the module that creates the dialog box.

lpTemplate

Points to a global memory object that contains a dialog box template used to create the dialog box. This template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures.

The DLGTEMPLATE structure has the following form:

typedef struct { /* dltt */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  cdit;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

} DLGTEMPLATE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The DLGITEMTEMPLATE structure has the following form:

typedef struct { /* dlit */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

    WORD  id;

} DLGITEMTEMPLATE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

Return Value

If the function succeeds, the return value is the window handle of the dialog box; otherwise, it is NULL.

Comments

The CreateDialogIndirect function uses the CreateWindowEx function to create the dialog box. CreateDialogIndirect then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box if the template specifies the WS_VISIBLE style. Finally, CreateDialogIndirect returns the window handle of the dialog box.

After CreateDialogIndirect returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function.

See Also

»CreateDialog«, »CreateDialogIndirectParam«, »CreateDialogParam«, »CreateWindowEx«, »DestroyWindow«, »DialogProc«, »ShowWindow«


  CreateDialogIndirectParam

HWND CreateDialogIndirectParam(hinst, lpTemplate, hwndOwner, dlgprc, lParamInit)
HANDLE  hinst;   /* handle of application instance */
LPCDLGTEMPLATE  lpTemplate;   /* address of dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */
LPARAM  lParamInit;   /* initialization value */

The CreateDialogIndirectParam function creates a modeless dialog box from a dialog box template in memory. Before displaying the dialog box, the function passes an application-defined value to the dialog box procedure as the lParam parameter of the WM_INITDIALOG message. An application can use this value to initialize dialog box controls.

Parameters

hinst

Identifies the instance of the module that will create the dialog box.

lpTemplate

Points to a global memory object that contains a dialog box template used to create the dialog box. This template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures.

The DLGTEMPLATE structure has the following form:

typedef struct { /* dltt */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  cdit;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

} DLGTEMPLATE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The DLGITEMTEMPLATE structure has the following form:

typedef struct { /* dlit */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

    WORD  id;

} DLGITEMTEMPLATE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

lParamInit

Specifies the value to pass to the dialog box in the lParam parameter of the WM_INITDIALOG message.

Return Value

If the function succeeds, the return value is the window handle of the dialog box; otherwise, it is NULL.

Comments

The CreateDialogIndirectParam function uses the CreateWindowEx function to create the dialog box. CreateDialogIndirectParam then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box if the template specifies the WS_VISIBLE style. Finally, CreateDialogIndirectParam returns the window handle of the dialog box.

After CreateDialogIndirectParam returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function.

See Also

»CreateDialog«, »CreateDialogIndirect«, »CreateDialogParam«, »CreateWindowEx«, »DestroyWindow«, »DialogProc«, »ShowWindow«


  CreateDialogParam

HWND CreateDialogParam(hinst, lpszTemplate, hwndOwner, dlgprc, lParamInit)
HANDLE  hinst;   /* handle of application instance */
LPCTSTR  lpszTemplate;   /* identifies dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */
LPARAM  lParamInit;   /* initialization value */

The CreateDialogParam function creates a modeless dialog box from a dialog box template resource. Before displaying the dialog box, the function passes an application-defined value to the dialog box procedure as the lParam parameter of the WM_INITDIALOG message. An application can use this value to initialize dialog box controls.

Parameters

hinst

Identifies an instance of the module whose executable file contains the dialog box template.

lpszTemplate

Identifies the dialog box template. This parameter is either the address of a null-terminated character string that specifies the name of the dialog box template or an integer value that specifies the resource identifier of the dialog box template. If the parameter specifies a resource identifier, its high-order word must be zero and low-order word must contain the identifier. You can use the MAKEINTRESOURCE macro to create this value.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

lParamInit

Specifies the value to pass to the dialog box procedure in the lParam parameter in the WM_INITDIALOG message.

Return Value

If the function succeeds, the return value is the window handle of the dialog box; otherwise, it is NULL.

Comments

The CreateDialogParam function uses the CreateWindowEx function to create the dialog box. CreateDialogParam then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box if the template specifies the WS_VISIBLE style. Finally, CreateDialogParam returns the window handle of the dialog box.

After CreateDialogParam returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function.

See Also

»CreateDialog«, »CreateDialogIndirect«, »CreateDialogIndirectParam«, »CreateWindowEx«, »DestroyWindow«, »DialogProc«, »ShowWindow«


  CreateDIBitmap

HBITMAP CreateDIBitmap(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage)
HDC  hdc;   /* handle of device context */
LPBITMAPINFOHEADER  lpbmih;   /* address of bitmap size and format data */
DWORD  fdwInit;   /* initialization flag */
CONST BYTE  *lpbInit;   /* address of initialization data */
LPBITMAPINFO  lpbmi;   /* address of bitmap color-format data */
UINT  fuUsage;   /* color-data usage */

The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a device-independent bitmap (DIB) and, optionally, sets the bitmap bits.

Parameters

hdc

Identifies a device context.

lpbmih

Points to a BITMAPINFOHEADER structure. The BITMAPINFOHEADER structure has the following form:

typedef struct tagBITMAPINFOHEADER{ /* bmih */

   DWORD  biSize;

   LONG   biWidth;

   LONG   biHeight;

   WORD   biPlanes;

   WORD   biBitCount

   DWORD  biCompression;

   DWORD  biSizeImage;

   LONG   biXPelsPerMeter;

   LONG   biYPelsPerMeter;

   DWORD  biClrUsed;

   DWORD  biClrImportant;

} BITMAPINFOHEADER;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If fdwInit has the value CBM_INIT, the function uses the BITMAPINFOHEADER structure to obtain, among other information, the desired width and height of the bitmap. This scenario is compatible with the Windows 3.1 CreateDIBitmap function.

If fdwInit has the value CBM_CREATEDIB, the function ignores the lpbmih parameter. The parameter may be NULL. This scenario is new for the Win32 API set.

fdwInit

Specifies how the bitmap is to be created. This parameter must be one of the following values:

Value	Meaning
CBM_CREATEDIB	The color format of the bitmap being created matches the color format specified in the structure pointed to by the lpbmi parameter. If this flag is not specified, the bitmap is assumed to be compatible with the device associated with the device context identified by the hdc parameter.
CBM_INIT	The data pointed to by the lpbInit and lpbmi parameters is to be used to initialize the bitmap. If this flag is not specified, the data is not used.
lpbInit

Points to an array of bytes containing the initial bitmap data. The format of the data depends on the biBitCount member of the BITMAPINFO structure to which the lpbmi parameter points.

lpbmi

Points to a BITMAPINFO structure that describes the dimensions and color format of the array pointed to by the lpbInit parameter. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuUsage

Specifies whether the bmiColors member of the BITMAPINFO data structure was initialized and, if so, whether bmiColors contains explicit red, green, blue (RGB) values or palette indices. The fuUsage parameter must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	The color table consists of an array of 16-bit indices into the logical palette of the DC into which the bitmap is to be selected.
DIB_PAL_INDICES	There is no color table for the bitmap. The bitmap bits are indices into the device's physical palette, not the currently selected logical palette.
DIB_RGB_COLORS	The color table contains literal RGB values.
Return Value

If the function succeeds, the return value is a handle of the bitmap; otherwise, it is NULL.

Comments

In order for a device to reach optimal bitmap drawing speed, the bitmap bits must be indices into the device's physical palette (and DIB_PAL_INDICES must be specified as the usage argument). Applications that create bitmaps in this format must use the colors from the device's physical palette. These colors are obtained by calling the GetSystemPaletteEntries function and are valid only when the application window is the active window. For more information about color and palettes, see Chapter 36, "Colors," in Microsoft Win32 Programmer's Reference, Volume 1.

See Also

»DeleteObject«, »GetDeviceCaps«, »GetSystemPaletteEntries«, »SelectObject«


  CreateDIBPatternBrush

HBRUSH CreateDIBPatternBrush(hglbDIBPacked, fuColorSpec)
HGLOBAL  hglbDIBPacked;   /* handle of device-independent bitmap */
UINT  fuColorSpec;   /* color table data */

The CreateDIBPatternBrush function creates a logical brush that has the pattern specified by the given device-independent bitmap (DIB). The brush can subsequently be selected into any device context (DC) that is associated with a device that supports raster operations.

This function is provided only for compatibility with applications written for versions of Windows earlier than 3.0. For applications written with the Win32 API, use the CreateDIBPatternBrushPt.

Parameters

hglbDIBPacked

Identifies a global memory object containing a packed DIB, which consists of a BITMAPINFO structure immediately followed by an array of bytes defining the pixels of the bitmap. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuColorSpec

Specifies whether the bmiColors member of the BITMAPINFO structure is initialized and, if so, whether this member contains explicit red, green, blue (RGB) values or indices into a logical palette. The fuColorSpec parameter must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	A color table is provided and consists of an array of 16-bit indices into the logical palette of the DC that the brush is to be selected into.
DIB_RGB_COLORS	A color table is provided and contains literal RGB values.
DIB_PAL_INDICES	No color table is provided. The bitmap itself contains indices into the logical palette of the DC that the brush is to be selected into.
Return Value

If the function succeeds, the return value identifies a logical brush; otherwise, it is NULL.

Comments

When an application selects a two-color DIB pattern brush into a monochrome DC, Windows does not acknowledge the colors specified in the DIB; instead, it displays the pattern brush using the current background and foreground colors of the DC. Pixels mapped to the first color of the DIB (offset 0 in the DIB color table) are displayed using the foreground color; pixels mapped to the second color (offset 1 in the color table) are displayed using the background color.

See Also

»CreateDIBPatternBrushPt«, »CreateHatchBrush«, »CreatePatternBrush«, »CreateSolidBrush«, »SetBkColor«, »SetTextColor«


  CreateDIBPatternBrushPt

HBRUSH CreateDIBPatternBrushPt(lpPackedDIB, iUsage)
LPVOID  lpPackedDIB;   /* address of structure and bitmap bits */
UINT  iUsage;   /* usage flags */

The CreateDIBPatternBrushPt function creates a logical brush that has the pattern specified by the device-independent bitmap (DIB).

Parameters

lpPackedDIB

Points to a packed DIB consisting of a BITMAPINFO structure immediately followed by an array of bytes defining the pixels of the bitmap. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

iUsage

Specifies whether the bmiColors member of the BITMAPINFO structure contains a valid color table and, if so, whether the entries in this color table contain explicit red, green, blue (RGB) values or palette indices. The iUsage parameter must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	A color table is provided and consists of an array of 16-bit indices into the logical palette of the DC into which the brush is to be selected.
DIB_RGB_COLORS	A color table is provided and contains literal RGB values.
DIB_PAL_INDICES	No color table is provided. The bitmap itself contains indices into the logical palette of the DC into which the brush is to be selected.
Return Value

If the function succeeds, the return value identifies a logical brush; otherwise, it is NULL.

Comments

A brush is a bitmap that Windows uses to paint the interiors of filled shapes.

After an application creates a brush by calling CreateDIBPatternBrushPt, it can select that brush into any DC by calling the SelectObject function.

See Also

»CreateDIBPatternBrush«, »CreateHatchBrush«, »CreatePatternBrush«, »CreateSolidBrush«, »DeleteObject«, »GetBrushOrgEx«, »SelectObject«, »SetBrushOrgEx«


  CreateDIBSection

HBITMAP CreateDIBSection(hdc, lpInfo, fInit, iUsage)
HDC  hdc;   /* handle of device context */
LPBITMAPINFO  lpInfo;   /* address of bitmap data */
DWORD  fInit;   /* scan line order */
DWORD  iUsage;   /* color format */

The CreateDIBSection function copies color data for a number of scan lines into the given buffer.

Parameters

hdc

Identifies a device context that contains the logical palette used to initialize the bitmap's colors.

lpInfo

Points to a BITMAPINFO structure that describes the desired size and format of the bitmap. In addition, this structure contains a logical palette. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fInit

Specifies the order of scan lines in the bitmap. This parameter can be one of the following values:

Constant	Meaning
BMF_TOPDOWN	The first scanline in the buffer to which the lppBits parameter points is the top scan line.
BMF_DIB	The first scan line in the buffer to which lppBits points is the bottom scan line.
iUsage

Specifies whether the bmiColors member of BITMAPINFO structure contains explicit red, green, blue (RGB) values or indices into the currently realized logical palette. This parameter can be one of the following values:

Constant	Meaning
DIB_PAL_COLORS	The BITMAPINFO structure contains an array of 16-bit indices into a logical palette.
DIB_RGB_COLORS	The BITMAPINFO structure contains an array of literal RGB values.
Return Value

If the function succeeds, the return value is a handle of the bitmap; otherwise, it is NULL.

Comments

The bitmap bits stored in the buffer pointed to by the lppBits parameter are aligned on doubleword boundaries.

See Also

»DeleteObject«, »SelectObject«


  CreateDirectory

BOOL CreateDirectory(lpszPath, lpsa)
LPTSTR  lpszPath;   /* address of path of directory to create */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security descriptor */

The CreateDirectory function creates a new directory.

Parameters

lpszPath

Points to a null-terminated string that specifies the path of the directory to be created.

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the directory. The file system must support this parameter for it to have an effect.

The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»RemoveDirectory«


  CreateDiscardableBitmap

HBITMAP CreateDiscardableBitmap(hDC, nWidth, nHeight)
HDC  hDC;   /* handle of device context */
int  nWidth;   /* bitmap width */
int  nHeight;   /* bitmap height */

The CreateDiscardableBitmap function creates a discardable bitmap that is compatible with the given device. The bitmap has the same bits-per-pixel format and the same color palette as the device. An application can select this bitmap as the current bitmap for a memory device that is compatible with the given device.

The CreateDiscardableBitmap function is included only for compatibility with earlier versions of Windows. For Win32 applications, use the CreateCompatibleBitmap function.

Parameters

hDC

Identifies a device context.

nWidth

Specifies the width, in bits, of the bitmap.

nHeight

Specifies the height, in bits, of the bitmap.

Return Value

If the function succeeds, the return value is a handle of the bitmap; otherwise, it is NULL.

See Also

»CreateCompatibleBitmap«


  CreateEllipticRgn

HRGN CreateEllipticRgn(nLeftRect, nTopRect, nRightRect, nBottomRect)
int  nLeftRect;   /* x-coordinate upper left corner bounding rectangle */
int  nTopRect;   /* y-coordinate upper left corner bounding rectangle */
int  nRightRect;   /* x-coordinate lower right corner bounding rectangle */
int  nBottomRect;   /* y-coordinate lower right corner bounding rectangle */

The CreateEllipticRgn function creates an elliptical region.

Parameters

nLeftRect

Specifies the x-coordinate of the upper left corner of the bounding rectangle of the ellipse.

nTopRect

Specifies the y-coordinate of the upper left corner of the bounding rectangle of the ellipse.

nRightRect

Specifies the x-coordinate of the lower right corner of the bounding rectangle of the ellipse.

nBottomRect

Specifies the y-coordinate of the lower right corner of the bounding rectangle of the ellipse.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is NULL.

Comments

A bounding rectangle defines the size, shape, and orientation of the region: The long sides of the rectangle define the length of the ellipse's major axis; the short sides define the length of the ellipse's minor axis; and the center of the rectangle defines the intersection of the major and minor axes.

The coordinates of the bounding rectangle are specified in logical units.

See Also

»CreateEllipticRgnIndirect«, »DeleteObject«, »SelectObject«


  CreateEllipticRgnIndirect

HRGN CreateEllipticRgnIndirect(lprc)
CONST RECT  *lprc;   /* address of structure defining bounding rectangle */

The CreateEllipticRgnIndirect function creates an elliptical region.

Parameters

lprc

Points to a RECT structure that contains the coordinates of the upper left and lower right corners of the bounding rectangle of the ellipse. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is NULL.

Comments

A bounding rectangle defines the size, shape, and orientation of the region: The long sides of the rectangle define the length of the ellipse's major axis; the short sides define the length of the ellipse's minor axis; and the center of the rectangle defines the intersection of the major and minor axes.

The coordinates of the bounding rectangle are specified in logical units.

See Also

»CreateEllipticRgn«, »DeleteObject«, »SelectObject«


  CreateEnhMetaFile

HDC CreateEnhMetaFile(hdcRef, lpFilename, lpRect, lpDescription)
HDC  hdcRef;   /* handle of a reference device context */
LPTSTR  lpFilename;   /* address of a filename string */
LPRECT  lpRect;   /* address of a bounding rectangle */
LPTSTR  lpDescription;   /* address of an optional description string */

The CreateEnhMetaFile function creates a device context (DC) for an enhanced-format metafile. This DC can be used to store a device-independent picture.

Parameters

hdcRef

Identifies a reference device for the enhanced metafile.

lpFilename

Points to the filename for the enhanced metafile to be created. If this parameter is NULL, the enhanced metafile is memory based and its contents are lost when it is deleted by using the DeleteEnhMetaFile function.

lpRect

Points to a RECT structure that specifies the dimensions (in .01-millimeter units) of the picture to be stored in the enhanced metafile. The RECT structure has the following format:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpDescription

Points to a string that specifies the name of the application that created the picture, as well as the picture's title.

Return Value

If the function succeeds, the return value is a handle of the device context for the enhanced metafile; otherwise, it is NULL.

Comments

Where text arguments must use Unicode™ characters, use this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

Windows uses the reference device identified by the hdcRef parameter to record the resolution and units of the device on which a picture originally appeared. If the hdcRef parameter is NULL, it uses the current display device for reference.

The left and top members of the RECT structure pointed to by the lpRect parameter must be less than the right and bottom members, respectively. Points along the edges of the rectangle are included in the picture. If lpRect is NULL, the graphics device interface (GDI) computes the dimensions of the smallest rectangle that surrounds the picture drawn by the application. The lpRect parameter should be provided where possible.

The string pointed to by the lpDescription parameter must contain a null character between the application name and the picture name and must terminate with two null characters — for example, "XYZ Graphics Editor\0Bald Eagle\0\0", where \0 represents the null character. If lpDescription is NULL, there is no corresponding entry in the enhanced-metafile header.

Applications use the DC created by this function to store a graphics picture in an enhanced metafile. The handle identifying this DC can be passed to any GDI function.

After an application stores a picture in an enhanced metafile, it can display the picture on any output device by calling the PlayEnhMetaFile function. When displaying the picture, Windows uses the rectangle pointed to by the lpRect parameter and the resolution data from the reference device to position and scale the picture.

The device context returned by this function contains the same default attributes associated with any new DC.

Applications must use the GetWinMetaFileBits function to convert an enhanced metafile to the older Windows metafile format.

The filename for the enhanced metafile should use the .EMF extension.

See Also

»CloseEnhMetaFile«, »DeleteEnhMetaFile«, »GetEnhMetaFileDescription«, »GetEnhMetaFileHeader«, »GetWinMetaFileBits«, »PlayEnhMetaFile«


  CreateEvent

HANDLE CreateEvent(lpsa, fManualReset, fInitialState, lpszEventName)
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security attributes */
BOOL  fManualReset;   /* flag for manual-reset event */
BOOL  fInitialState;   /* flag for initial state */
LPTSTR  lpszEventName;   /* address of event-object name */

The CreateEvent function creates a named or unnamed event object.

Parameters

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the event object. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpsa is NULL, the event object is created with a default security descriptor and the resulting handle is not inheritable.

fManualReset

Specifies whether a manual-reset or auto-reset event object is created. If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled. If FALSE, Windows automatically resets the state to nonsignaled after a single waiting thread has been released.

fInitialState

Specifies the initial state of the event object. If TRUE, the initial state is signaled; otherwise, it is nonsignaled.

lpszEventName

Points to a null-terminated string specifying the name of the event object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpszEventName matches the name of an existing named event object, this function requests EVENT_ALL_ACCESS access to the existing object. In this case, the fManualReset and fInitialState parameters are ignored because they have already been set by the creating process. If the lpsa parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpszEventName is NULL, the event object is created without a name.

If lpszEventName matches the name of an existing semaphore, mutex, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because event, mutex, semaphore, and file-mapping objects share the same name space.

Return Value

If the function succeeds, the return value is a handle of the event object. If the named event object existed before the function call, the GetLastError function returns ERROR_ALREADY_EXISTS. Otherwise, GetLastError returns zero.

If the function fails, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

The handle returned by CreateEvent has EVENT_ALL_ACCESS access to the new event object and can be used in any function that requires a handle of an event object.

Any thread of the calling process can specify the event-object handle in a call to one of the wait functions (MsgWaitForMultipleObjects, WaitForSingleObject, WaitForMultipleObjects, WaitForSingleObjectEx, or WaitForMultipleObjectsEx). The single-object wait functions return when the state of the specified object is signaled. The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.

The initial state of the event object is specified by the fInitialState parameter. Use the SetEvent function to set the state of an event object to signaled. Use the ResetEvent function to reset the state of an event object to nonsignaled.

When the state of a manual-reset event object is signaled, it remains signaled until it is explicitly reset to nonsignaled by the ResetEvent function. Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object, can be released while the object's state is signaled.

When the state of an auto-reset event object is signaled, it remains signaled until a single waiting thread is released; the system then automatically resets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.

Multiple processes can have handles of the same event object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available:

•	A child process created by the CreateProcess function can inherit a handle of an event object if the lpsa parameter of CreateEvent enabled inheritance.

•	A process can specify the event-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.

•	A process can specify the name of an event object in a call to the OpenEvent or CreateEvent function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The event object is destroyed when its last handle has been closed.

See Also

»CloseHandle«, »OpenEvent«, »ResetEvent«, »SetEvent«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  CreateFile

HANDLE CreateFile(lpszName, fdwAccess, fdwShareMode, lpsa, fdwCreate,
fdwAttrsAndFlags, hTemplateFile)
LPCTSTR  lpszName;   /* address of name of the file */
DWORD  fdwAccess;   /* access (read-write) mode */
DWORD  fdwShareMode;   /* share mode */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security descriptor */
DWORD  fdwCreate;   /* how to create */
DWORD  fdwAttrsAndFlags;   /* file attributes */
HANDLE  hTemplateFile;   /* handle of file with attrs. to copy */

The CreateFile function creates, opens, or truncates a file, pipe, communications resource, disk device, or console. It returns a handle that can be used to access the object.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the file, pipe, communications resource, disk device, or console to create, open, or truncate.

fdwAccess

Specifies the type of access to the file. This parameter can be one or both of the following values:

Value	Meaning
GENERIC_READ	Specifies read access to the file. Data can be read from the file and the file pointer can be moved.
GENERIC_WRITE	Specifies write access to the file. Data can be read from and written to the file and the file pointer can be moved.
fdwShareMode

Specifies how this file can be shared. This parameter must be some combination of the following values:

Value	Meaning
0	Prevents the file from being shared.
FILE_SHARE_READ	Other open operations can be performed on the file for read access. Specify this flag if the CreateFile function is opening the client end of a mailslot.
FILE_SHARE_WRITE	Other open operations can be performed on the file for write access.
lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the file. The file system must support this parameter for it to have an effect.

The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fdwCreate

Specifies the action to take when the file exists or does not exist. For more information about this parameter, see Comments. This parameter must be one of the following values:

Value	Meaning
CREATE_NEW	Creates a new file. Fails if the specified file already exists.
CREATE_ALWAYS	Creates a new file. Overwrites the file if it exists.
OPEN_EXISTING	Opens the file. Fails if the file does not exist.
	Please see the Comments section below for a discussion of why you should use the OPEN_EXISTING flag if you are using the CreateFile function on a device, including the console.
OPEN_ALWAYS	Opens the file, if it exists. If the file does not exist, the function creates the file as if fdwCreate were CREATE_NEW.
TRUNCATE_EXISTING	Opens the file. Once opened, the file is truncated so that its size is zero bytes. The calling process must open the file with at least GENERIC_WRITE access. Fails if the file does not exist.
fdwAttrsAndFlags

Specifies the file attributes and flags for the file. Any combination of the following flags and attributes is acceptable, except that all other file attributes override FILE_ATTRIBUTE_NORMAL.

Attribute	Meaning
FILE_ATTRIBUTE_ARCHIVE
	The file is an archive file. Applications use this flag to mark files for backup or removal.
FILE_ATTRIBUTE_NORMAL
	The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_HIDDEN
	The file is hidden. It is not to be included in an ordinary directory listing.
FILE_ATTRIBUTE_READONLY
	The file is read only. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM
	The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY
	The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access, rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.
FILE_ATTRIBUTE_ATOMIC_WRITE
	The file is an atomic write file. Applications write to the file using atomic write semantics. If any write operation flushes data to the medium, all write operations up to that point are also flushed, as well as any file system structures. This ensures that the data is retrievable at a later time.
FILE_ATTRIBUTE_XACTION_WRITE
	Reserved for future use. Do not specify.
Flag	Meaning
FILE_FLAG_WRITE_THROUGH
	Instructs the operating system to write through any intermediate cache and go directly to the file. The operating system can still cache writes, but cannot lazily flush the writes.
FILE_FLAG_OVERLAPPED
	Instructs the operating system to initialize the file so ReadFile, WriteFile, ConnectNamedPipe, and TransactNamedPipe operations that take a significant amount of time to process return ERROR_IO_PENDING. When the operation is finished, an event is set to the signaled state.
	When FILE_FLAG_OVERLAPPED is specified, the operating system does not maintain the file pointer. The file position must be passed as part of the OVERLAPPED structure argument to the ReadFile and WriteFile functions. If this flag is specified, the ReadFile and WriteFile functions must specify an OVERLAPPED structure.
	This flag also enables more than one operation to be performed simultaneously with the handle (a simultaneous read and write, for example).
FILE_FLAG_NO_BUFFERING
	Indicates that the file is to be opened with no intermediate buffering or caching done by the system. Reads and writes to the file must be done on sector boundaries. Buffer addresses for reads and writes must be aligned on disk sector boundaries in memory. You can determine sector size with the GetDiskFreeSpace function.
FILE_FLAG_RANDOM_ACCESS
	Indicates that the file is accessed randomly. Windows uses this flag to optimize file caching.
FILE_FLAG_SEQUENTIAL_SCAN
	Indicates that the file is to be accessed sequentially from beginning to end; the file pointer is not moved. Windows uses this flag to optimize file caching. If an application moves the file pointer, optimum caching cannot occur.
FILE_FLAG_DELETE_ON_CLOSE
	Indicates that the operating system is to delete the file immediately after all its handles have been closed.
FILE_FLAG_BACKUP_SEMANTICS
	Indicates that the file is being opened or created for a backup or restore operation. The operating system ensures that the calling process overrides file security checks, provided it has the necessary permission to do so. The relevant permissions are SE_BACKUP_NAME and SE_RESTORE_NAME.
FILE_FLAG_POSIX_SEMANTICS
	Indicates to access the file according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file systems that support such naming. Use care when using this option because files created with this flag may not be accessible by applications written for MS-DOS, Windows 3.x, or Windows NT.
If the CreateFile function opens the client side of a named pipe, the fdwAttrsAndFlags parameter can also contain Security Quality of Service information. When the calling application specifies the SECURITY_SQOS_PRESENT flag, the fdwAttrsAndFlags parameter can contain one or more of the following values:

Value	Meaning
SECURITY_ANONYMOUS
	Specifies to impersonate the client at the Anonymous impersonation level.
SECURITY_IDENTIFICATION
	Specifies to impersonate the client at the Identification impersonation level.
SECURITY_IMPERSONATION
	Specifies to impersonate the client at the Impersonation impersonation level.
SECURITY_DELEGATION
	Specifies to impersonate the client at the Delegation impersonation level.
Value	Meaning
SECURITY_CONTEXT_TRACKING
	Specifies that the security tracking mode is dynamic. If this flag is not specified, Security Tracking Mode is static.
SECURITY_EFFECTIVE_ONLY
	Specifies that only the enabled aspects of the client's security context are available to the server. If this flag is not specified, all aspects of the client's security context are available.
	This flag allows the client to limit the groups and privileges a server can use while impersonating the client.
For more information about security, see Chapter 49, "Security" in Microsoft Win32 Programmer's Reference, Volume 2.

hTemplateFile

Specifies a handle with GENERIC_READ access to a template file. The template file supplies extended attributes for the file being created.

Return Value

If the function succeeds, the return value is an open handle of the specified file; otherwise, it is INVALID_HANDLE_VALUE. To get extended error information, use the GetLastError function.

Comments

When creating a new file, the CreateFile function performs the following actions:

•	Combines the file attributes and flags specified by fdwAttrsAndFlags with FILE_ATTRIBUTE_ARCHIVE.

•	Sets the file length to zero.

•	If the hTemplateFile parameter is specified, CreateFile copies the extended attributes supplied by the template file to the new file.

When opening an existing file, CreateFile performs the following actions:

•	Combines the file flags specified by fdwAttrsAndFlags with existing file attributes. CreateFile ignores the file attributes specified by fdwAttrsAndFlags.

•	Sets the file length according to the value of fdwCreate.

•	Ignores the hTemplateFile parameter.

•	If the lpsa parameter isn't NULL, CreateFile ignores the lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure. The other structure members are valid. The bInheritHandle member is the only way to indicate whether the file handle can be inherited.

If CreateFile opens the client end of a named pipe, the function uses any instance of the named pipe that is in the listening state. The opening process can duplicate the handle as many times as required but, once opened, the named pipe instance cannot be opened by another client. The access specified when a pipe is opened must be compatible with the access specified in the CreateNamedPipe dwOpenMode parameter.

For more information about pipes, see Chapter 54, "Pipes" in Microsoft Win32 Programmer's Reference, Volume 2.

If CreateFile opens the client end of a mailslot, the function always returns a valid handle, even if the mailslot does not exist. In other words, there is no relationship between opening the client end and opening the server end of the mailslot.

For more information about mailslots, see Chapter 55, "Mailslots," in Microsoft Win32 Programmer's Reference, Volume 2.

CreateFile can create a handle to a communications resource, such as the serial port COM1. For communications resources, the fdwShareMode parameter must be 0 (exclusive access), the fdwCreate parameter must be OPEN_EXISTING, and the hTemplate parameter must be NULL. Read, write, or read-write access can be specified, and the handle can be opened for overlapped input and output (I/O).

For more information about communications, see Chapter 68, "Communications," Microsoft Win32 Programmer's Reference, Volume 2.

CreateFile can create a handle to console input (CONIN$). If the process has an open handle to it as a result of inheritance or duplication, it can also create a handle to the active screen buffer (CONOUT$).

The calling process must be attached to an inherited console or one allocated by the AllocConsole function. For console handles, set the CreateFile parameters as follows:

Parameter	Value
lpszName	Use the values CONIN$ to specify console input, CONOUT$ to specify console output.
	CONIN$ gets a handle of the console's input buffer, even if the SetStdHandle function redirected the standard input handle. Use the GetStdHandle function to get the standard input handle.
	CONOUT$ gets a handle of the active screen buffer, even if SetStdHandle redirected the standard output handle. Use GetStdHandle to get the standard output handle.
fdwAccess	"GENERIC_READ | GENERIC_WRITE" is preferred, but either one can limit access.
fdwShareMode	If the calling process inherited the console, or a child process should be able to access the console, this parameter must be "FILE_SHARE_READ | FILE_SHARE_WRITE".
lpsa	If the calling process wants the console to be inherited, the bInheritHandle member of the SECURITY_ATTRIBUTES structure must be TRUE.
fdwCreate	The user should specify OPEN_EXISTING when using CreateFile to open the console.
fdwAttrsAndFlags	Ignored.
hTemplateFile	Ignored.
A call to CreateFile with lpszName set to "CON" and fwdAccess set to GENERIC_READ opens a console for input. A call to CreateFile with lpszName set to "CON" and fwdAccess set to GENERIC_WRITE opens a console for output. A call to CreateFile with lpszName set to "CON" and fwdAccess set to GENERIC_READ | GENERIC_WRITE will cause CreateFile to fail, returning an ERROR_PATH_NOT_FOUND error.

The CreateFile function may be used to open a disk drive or a partition on a disk drive. The function returns a handle to the disk device; that handle may be used with the DeviceIOControl function. The following requirements must be met in order for such a call to succeed:

•	The caller must have administrative privileges for the operation to succeed on a hard disk drive.

•	The lpszName string should be of the form \\.\PhysicalDriveN to open the Nth hard disk. Hard disk numbers start at 0. For example:

String	Meaning
\\.\PHYSICALDRIVE2	Obtains a handle to the user's computer's third physical drive
•	The lpszName string should be \\.\x: to open a floppy drive x or a partition x on a hard disk. For example:

String	Meaning
\\.\A:	Obtains a handle to the user's computer's A: drive.
\\.\C:	Obtains a handle to the user's computer's C: drive.
•	The  fdwCreate parameter must have the value OPEN_EXISTING.

•	When opening a floppy disk or a partition on a hard disk, the fdwShareMode flag must at least specify FILE_SHARE_WRITE.

Use the CloseHandle function to close a handle returned by CreateFile.

See Also

»AllocConsole«, »CloseHandle«, »ConnectNamedPipe«, »CreateNamedPipe«, »GetDiskFreeSpace«, »GetOverlappedResult«, »GetStdHandle«, »OpenFile«, »SetStdHandle«


  CreateFileMapping

HANDLE CreateFileMapping(hFile, lpsa, fdwProtect, dwMaximumSizeHigh,
dwMaximumSizeLow, lpszMapName)
HANDLE  hFile;   /* handle of file to map */
LPSECURITY_ATTRIBUTES  lpsa;   /* optional security attributes */
DWORD  fdwProtect;   /* protection for mapping object */
DWORD  dwMaximumSizeHigh;   /* high-order 32 bits of object size */
DWORD  dwMaximumSizeLow;   /* low-order 32 bits of object size */
LPTSTR  lpszMapName;   /* name of file-mapping object */

The CreateFileMapping function creates a named or unnamed file-mapping object for the specified file.

Parameters

hFile

Identifies the file from which to create a mapping object. The file must be opened with an access mode compatible with the protection flags specified by the fdwProtect parameter. It is recommended, though not required, that files you intend to map be opened for exclusive access.

If hFile is (HANDLE)0xFFFFFFFF, the calling process must also specify a mapping object size in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. The function creates a file-mapping object of the specified size backed by the operating-system paging file rather than by a named file in the file system. The file-mapping object can be shared through duplication, through inheritance, or by name.

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the mapping object.

The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

If lpsa is NULL, the file-mapping object is created with a default security descriptor and the resulting handle is not inherited.

fdwProtect

Specifies the protection desired for the file view, when the file is mapped. This parameter can be one of the following values:

Value	Description
PAGE_READONLY	Gives read-only access to the committed region of pages. An attempt to write to or execute the committed region results in an access violation. The file specified by the hFile parameter must have been created with GENERIC_READ access.
PAGE_READWRITE	Gives read-and-write access to the committed region of pages. The file specified by hFile must have been created with GENERIC_READ and GENERIC_WRITE access.
PAGE_WRITECOPY	Gives copy on write access to the committed region of pages. The files specified by the hFile parameter must have been created with GENERIC_READ and GENERIC_WRITE access.
dwMaximumSizeHigh

Specifies the high-order 32 bits of the maximum size of the file-mapping object.

dwMaximumSizeLow

Specifies the low-order 32 bits of the maximum size of the file-mapping object. If the dwMaximumSizeLow and dwMaximumSizeHigh parameters are zero, the maximum size of the file-mapping object is equal to the current size of the file identified by hFile.

lpszMapName

Points to a null-terminated string specifying the name of the mapping object. The name can contain any character except the backslash path-separator character (\).

If lpszMapName matches the name of an existing named mapping object, this function requests access to the mapping object with the protection specified by the fdwProtect parameter.

If lpszMapName is NULL, the mapping object is created without a name.

Return Value

If the function succeeds, the return value is a handle of the file-mapping object. If the object existed before the function call, the GetLastError function returns ERROR_ALREADY_EXISTS. If the mapping object did not exist, GetLastError returns zero.

If the function fails, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

After a file-mapping object has been created, the size of the file must not exceed the size of the file-mapping object; if it does, not all of the file's contents will be available for sharing.

The handle that CreateFileMapping returns has full access to the new file-mapping object. It can be used with any function that requires a handle to a file-mapping object. File-mapping objects can be shared either through process creation, through handle duplication, or by name. For information on duplicating handles, see the »DuplicateHandle« function reference page. For information on opening a file-mapping object by name, see the »OpenFileMapping« function reference page.

Creating a file-mapping object creates the potential for mapping a view of the file but does not map the view. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process's address space.

With one important exception, file views derived from a single file-mapping object are coherent, or identical, at a given time. If multiple processes have handles of the same file-mapping object, they see a coherent view of the data when they map a view of the file.

The exception has to do with remote files. Although CreateFileMapping works with remote files, it does not keep them coherent. For example, if two machines both map a file as writable, and both change the same page, each machine will only see its own writes to the page. When the data gets updated on the disk, it is not merged.

A mapped file and a file accessed by means of the input and output (I/O) functions (ReadFile and WriteFile) are not necessarily coherent.

Example

To implement a mapping-object creation function that fails if the object already exists, an application can use the following code.

    hMap = CreateFileMapping(...);

    if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {

        CloseHandle(hMap);

        hMap = NULL;

    }

    return hMap;

See Also

»DuplicateHandle«, »MapViewOfFile«, »MapViewOfFileEx«, »OpenFileMapping«


  CreateFont

HFONT CreateFont(nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic,
fdwUnderline, fdwStrikeOut, fdwCharSet, fdwOutputPrecision, fdwClipPrecision, fdwQuality,
fdwPitchAndFamily, lpszFace)
int  nHeight;   /* logical height of font */
int  nWidth;   /* logical average character width */
int  nEscapement;   /* angle of escapement */
int  nOrientation;   /* base-line orientation angle */
int  fnWeight;   /* font weight */
DWORD  fdwItalic;   /* italic attribute flag */
DWORD  fdwUnderline;   /* underline attribute flag */
DWORD  fdwStrikeOut;   /* strikeout attribute flag */
DWORD  fdwCharSet;   /* character set identifier */
DWORD  fdwOutputPrecision;   /* output precision */
DWORD  fdwClipPrecision;   /* clipping precision */
DWORD  fdwQuality;   /* output quality */
DWORD  fdwPitchAndFamily;   /* pitch and family */
LPCTSTR  lpszFace;   /* address of typeface name string */

The CreateFont function creates a logical font that has specific characteristics. The logical font can subsequently be selected as the font for any device.

Parameters

nHeight

Specifies the desired height, in logical units, of the requested font's character cell or character. (The character height value is the character cell height value minus the the internal-leading value.) If this value is greater than zero, the font mapper matches it against available character cell height values; if this value is zero, the font mapper uses a default height value when it searches for a match; if this value is less than zero, the font mapper matches it against available character height values.

nWidth

Specifies the average width, in logical units, of characters in the requested font. If this value is zero, the font mapper chooses a "closest match" value. The "closest match" value is determined by comparing the absolute values of the difference between the current device's aspect-ratio and the digitized aspect-ratio of available fonts.

nEscapement

Specifies the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line of a row of text.

nOrientation

Specifies the angle, in tenths of degrees, between each character's base line and the x-axis of the device.

fnWeight

Specifies the desired weight of the font. (If this value is zero, a default weight is used.) This parameter can be one of the following values:

Value	Weight
FW_DONTCARE	0
FW_THIN	100
FW_EXTRALIGHT	200
FW_LIGHT	300
FW_NORMAL	400
FW_MEDIUM	500
FW_SEMIBOLD	600
FW_BOLD	700
FW_EXTRABOLD	800
FW_HEAVY	900
fdwItalic

Specifies an italic font if set to TRUE.

fdwUnderline

Specifies an underlined font if set to TRUE.

fdwStrikeOut

Specifies a strikeout font if set to TRUE.

fdwCharSet

Specifies the desired character set. The following values are predefined:

ANSI_CHARSET
UNICODE_CHARSET
SYMBOL_CHARSET
SHIFTJIS_CHARSET
HANGEUL_CHARSET
CHINESEBIG5_CHARSET
OEM_CHARSET

The OEM character set is operating-system dependent.

Fonts with other character sets may exist in the operating system. If an application uses a font with an unknown character set, it should not attempt to translate or interpret strings that are rendered with that font.

fdwOutputPrecision

Specifies the desired output precision. The output precision defines how closely the output must match the requested font's height, width, character orientation, escapement, and pitch. It can be one of the following values:

OUT_DEFAULT_PRECIS
OUT_STRING_PRECIS
OUT_CHARACTER_PRECIS
OUT_STROKE_PRECIS
OUT_TT_PRECIS
OUT_DEVICE_PRECIS
OUT_RASTER_PRECIS
OUT_TT_ONLY_PRECIS
OUT_OUTLINE_PRECIS

Applications can use the OUT_DEVICE_PRECIS, OUT_RASTER_PRECIS, and OUT_TT_PRECIS values to control how the font mapper chooses a font when the operating system contains more than one font with a given name. For example, if a operating system contains a font named Symbol in raster and TrueType® form, specifying OUT_TT_PRECIS forces the font mapper to choose the TrueType version. (Specifying OUT_TT_PRECIS forces the font mapper to choose a TrueType font for a specified a device or raster font, even if there is no TrueType font of the same name.)

fdwClipPrecision

Specifies the desired clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region. It can be one or more of the following values:

CLIP_DEFAULT_PRECIS
CLIP_CHARACTER_PRECIS
CLIP_STROKE_PRECIS
CLIP_MASK
CLIP_LH_ANGLES
CLIP_TT_ALWAYS
CLIP_EMBEDDED

To use an embedded read-only font, applications must specify CLIP_ENCAPSULATE.

To achieve consistent rotation of device, TrueType, and vector fonts, an application can use the OR operator to combine the CLIP_LH_ANGLES value with any of the other fdwClipPrecision values. If the CLIP_LH_ANGLES bit is set, the rotation for all fonts depends on whether the orientation of the coordinate system is left-handed or right-handed. If CLIP_LH_ANGLES is not set, device fonts always rotate counterclockwise, but the rotation of other fonts is dependent on the orientation of the coordinate system. (For more information about the orientation of coordinate systems, see the description of the nOrientation parameter.)

fdwQuality

Specifies the desired output quality. The output quality defines how carefully GDI must attempt to match the logical-font attributes to those of an actual physical font. It can be one of the following values:

Value	Meaning
DEFAULT_QUALITY	Appearance of the font does not matter.
DRAFT_QUALITY	Appearance of the font is less important than when the PROOF_QUALITY value is used. For GDI raster fonts, scaling is enabled. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
PROOF_QUALITY	Character quality of the font is more important than exact matching of the logical-font attributes. For GDI raster fonts, scaling is disabled and the font closest in size is chosen. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
fdwPitchAndFamily

Specifies the pitch and family of the font. The two low-order bits specify the pitch of the font and can be one of the following values:

DEFAULT_PITCH
FIXED_PITCH
VARIABLE_PITCH

Applications can set bit 2 (0x04) of the fdwPitchAndFamily parameter to choose a TrueType font.

The four high-order bits specify the font family and can be one of the following values:

Value	Description
FF_DECORATIVE	Novelty fonts. Old English is an example.
FF_DONTCARE	Don't care or don't know.
FF_MODERN	Fonts with constant stroke width, with or without serifs. Pica, Elite, and Courier New® are examples.
FF_ROMAN	Fonts with variable stroke width and with serifs. MS® Serif is an example.
FF_SCRIPT	Fonts designed to look like handwriting. Script and Cursive are examples.
FF_SWISS	Fonts with variable stroke width and without serifs. MS® Sans Serif is an example.
An application can specify a value for the fdwPitchAndFamily parameter by using the Boolean OR operator to join a pitch constant with a family constant.

Font families describe the look of a font in a general way. They are intended for specifying fonts when the exact typeface requested is not available.

lpszFace

Points to a null-terminated string that specifies the typeface name of the font. The length of this string must not exceed 32 characters. The EnumFonts function can be used to enumerate the typeface names of all currently available fonts.

Return Value

If the function succeeds, the return value is a handle of a logical font; otherwise, it is NULL. To get extended error information, use the GetLastError function.

See Also

»DeleteObject«, »SelectObject«


  CreateFontIndirect

HFONT CreateFontIndirect(lplf)
CONST LOGFONT  *lplf;   /* address of logical font structure */

The CreateFontIndirect function creates a logical font that has the characteristics specified in the given structure. The font can subsequently be selected as the current font for any device context.

Parameters

lplf

Points to a LOGFONT structure that defines the characteristics of the logical font. The LOGFONT structure has the following form:

typedef struct tagLOGFONT { /* lf */

   LONG lfHeight;

   LONG lfWidth;

   LONG lfEscapement;

   LONG lfOrientation;

   LONG lfWeight;

   BYTE lfItalic;

   BYTE lfUnderline;

   BYTE lfStrikeOut;

   BYTE lfCharSet;

   BYTE lfOutPrecision;

   BYTE lfClipPrecision;

   BYTE lfQuality;

   BYTE lfPitchAndFamily;

   CHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle of a logical font; otherwise, it is NULL.

Comments

The CreateFontIndirect function creates a logical font with the characteristics specified in the LOGFONT structure. When this font is selected by using the SelectObject function, GDI's font mapper attempts to match the logical font with an existing physical font. If it fails to find an exact match, it provides an alternative whose characteristics match as many of the requested characteristics as possible.

See Also

»DeleteObject«, »SelectObject«


  CreateHalftonePalette

HPALETTE CreateHalftonePalette(hdc)
HDC  hdc;   /* handle of device context */

The CreateHalftonePalette function creates a halftone palette for the specified device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value identifies a logical halftone palette; otherwise, it is 0. To get extended error information, use the GetLastError function.

Comments

An application should create a halftone palette when the stretching mode of a device context is set to HALFTONE. The logical halftone palette returned by CreateHalftonePalette should then be selected and realized into the device context before the StretchBlt or StretchDIBits function is called.

See Also

»RealizePalette«, »SelectPalette«, »SetStretchBltMode«


  CreateHatchBrush

HBRUSH CreateHatchBrush(fnStyle, clrref)
int  fnStyle;   /* hatch style */
COLORREF  clrref;   /* color value */

The CreateHatchBrush function creates a logical brush that has the specified hatch pattern and color.

Parameters

fnStyle

Specifies the hatch style of the brush. This parameter can be any one of the following values:

Value	Meaning
HS_BDIAGONAL	45-degree downward left-to-right hatch
HS_CROSS	Horizontal and vertical crosshatch
HS_DIAGCROSS	45-degree crosshatch
HS_FDIAGONAL	45-degree upward left-to-right hatch
HS_HORIZONTAL	Horizontal hatch
HS_VERTICAL	Vertical hatch
clrref

Specifies the foreground color of the brush that is used for the hatches.

Return Value

If the function succeeds, the return value identifies a logical brush; otherwise, it is NULL.

Comments

A brush is a bitmap that Windows uses to paint the interiors of filled shapes.

After an application creates a brush by calling CreateHatchBrush, it can select that brush into any device context (DC) by calling the SelectObject function.

If an application uses a hatch brush to fill the backgrounds of both a parent and a child window with matching color, it may be necessary to set the brush origin before painting the background of the child window. You can do this by having your application call the SetBrushOrgEx function. Your application can retrieve the current brush origin by calling the GetBrushOrgEx function.

See Also

»CreateDIBPatternBrush«, »CreateDIBPatternBrushPt«, »CreatePatternBrush«, »CreateSolidBrush«, »DeleteObject«, »GetBrushOrgEx«, »SelectObject«, »SetBrushOrgEx«


  CreateIC

HDC CreateIC(lpszDriver, lpszDevice, lpszOutput, lpdvmInit)
LPCTSTR  lpszDriver;   /* address of string specifying driver name */
LPCTSTR  lpszDevice;   /* address of string specifying device name */
LPCTSTR  lpszOutput;   /* address of string specifying port or file name */
LPDEVMODE  lpdvmInit;   /* address of optional initialization data */

The CreateIC function creates an information context for the specified device. The information context provides a fast way to get information about the device without creating a device context.

Parameters

lpszDriver

Points to a null-terminated character string that specifies the name of the device driver (for example, "Epson"). This parameter is ignored; it is present only to keep the function prototype identical with Windows 3.1.

lpszDevice

Points to a null-terminated character string that specifies the name of the specific output device being used, as shown by the Print Manager (for example, "Epson FX-80"). It is not the printer model name. The lpszDevice parameter must be used.

lpszOutput

Points to a null-terminated character string that specifies the file or device name for the physical output medium (file or output port). This parameter is ignored; it is present only to keep the function prototype identical with Windows 3.1

lpdvmInit

Points to a DEVMODE structure containing device-specific initialization data for the device driver. The DocumentProperties function retrieves this structure filled in for a given device. The lpdvmInit parameter must be NULL if the device driver is to use the default initialization (if any) specified by the user through Windows Print Manager.

Return Value

If the function succeeds, the return value is the handle of an information context; otherwise, it is NULL.

Comments

An error occurs if an application calls a GDI drawing function and supplies a handle identifying an information context.

See Also

»DocumentProperties«, »GetDeviceCaps«


  CreateIcon

HICON CreateIcon(hinst, nWidth, nHeight, cPlanes, cBitsPixel, lpbANDbits, lpbXORbits)
HINSTANCE  hinst;   /* handle of application instance */
int  nWidth;   /* icon width */
int  nHeight;   /* icon height */
BYTE  cPlanes;   /* number of planes in XOR bitmask */
BYTE  cBitsPixel;   /* number of bits per pixel in XOR bitmask */
CONST BYTE  *lpbANDbits;   /* address of AND bitmask array */
CONST BYTE  *lpbXORbits;   /* address of XOR bitmask array */

The CreateIcon function creates an icon that has the specified size, colors, and bit patterns.

Parameters

hinst

Identifies the instance of the module creating the icon.

nWidth

Specifies the width, in pixels, of the icon.

nHeight

Specifies the height, in pixels, of the icon.

cPlanes

Specifies the number of planes in the XOR bitmask of the icon.

cBitsPixel

Specifies the number of bits per pixel in the XOR bitmask of the icon.

lpbANDbits

Points to an array of bytes that contains the bit values for the AND bitmask of the icon. This bitmask describes a monochrome bitmap.

lpbXORbits

Points to an array of bytes that contains the bit values for the XOR bitmask of the icon. This bitmask describes a monochrome or device-dependent color bitmap.

Return Value

If the function succeeds, the return value is the handle of an icon; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The nWidth and nHeight parameters must specify a width and height supported by the current display driver, because the system cannot create icons of other sizes. To determine the width and height supported by the display driver, use the GetSystemMetrics function, specifying the SM_CXICON or SM_CYICON value.

CreateIcon applies the following truth table to the AND and XOR bitmasks:

AND bitmask	XOR bitmask	Display
0	0	Black
0	1	White
1	0	Screen
1	1	Reverse screen
Before closing, an application must call the DestroyIcon function to free system resources associated with the icon.

See Also

»DestroyIcon«, »GetSystemMetrics«


  CreateIconFromResource

HICON CreateIconFromResource(pbIconBits, cbIconBits, fIcon, dwVersion)
PBYTE  pbIconBits;   /* address of icon or cursor bits */
DWORD  cbIconBits;   /* number of bytes in bit buffer */
BOOL  fIcon;   /* icon or cursor flag */
DWORD  dwVersion;   /* Windows format version */

The CreateIconFromResource function creates an icon or cursor from resource bits describing the icon.

Parameters

pbIconBits

Points to a buffer containing the icon or cursor resource bits. These bits are typically loaded by calls to the LookupIconIdFromDirectory and LoadResource functions.

cbIconBits

Specifies the size, in bytes, of the set of bits pointed to by the pbIconBits parameter.

fIcon

Specifies whether an icon or a cursor is to be created. If this parameter is TRUE, an icon is to be created. If it is FALSE, a cursor is to be created.

dwVersion

Specifies the version number of the icon or cursor format for the resource bits pointed to by the pbIconBits parameter. This parameter can be one of the following values:

Format	dwVersion
Windows 2.x	0x00020000
Windows 3.x	0x00030000
All Win32 applications use the Windows 3.x format for icons and cursors.

Return Value

If the function succeeds, the return value is the handle of the icon or cursor; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The CreateIconFromResource, CreateIconIndirect, GetIconInfo, and LookupIconIdFromDirectory functions allow shell applications and icon browsers to examine and use resources from throughout the system.

See Also

»CreateIconIndirect«, »GetIconInfo«, »LookupIconIdFromDirectory«


  CreateIconIndirect

HICON CreateIconIndirect(pici)
PICONINFO  pici;   /* address of icon information structure */

The CreateIconIndirect function creates an icon or cursor from an ICONINFO structure.

Parameters

pici

Points to an ICONINFO structure the function uses to create the icon or cursor. The ICONINFO structure has the following format:

typedef struct _ICONINFO { /* ii */

   BOOL    fIcon;

   DWORD   xHotspot;

   DWORD   yHotspot;

   HBITMAP hbmMask;

   HBITMAP hbmColor;

} ICONINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the icon or cursor that is created; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The system copies the bitmaps in the ICONINFO structure before creating the icon or cursor. The application must continue to manage the original bitmaps and delete them when they are no longer necessary.

See Also

»CreateIcon«, »CreateIconFromResource«, »DestroyIcon«, »DrawIcon«, »GetIconInfo«, »LoadIcon«, »LookupIconIdFromDirectory«


  CreateMailslot

HANDLE CreateMailslot(lpszName, cbMaxMsg, dwReadTimeout, lpsa)
LPTSTR  lpszName;   /* address of string for mailslot name */
DWORD  cbMaxMsg;   /* maximum message size */
DWORD  dwReadTimeout;   /* milliseconds before read time-out */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security structure */

The CreateMailslot function creates a mailslot with the specified name and returns a handle that a mailslot server can use to perform operations on the mailslot. The mailslot is local to the computer that creates it. An error occurs if a mailslot with the specified name already exists.

Parameters

lpszName

Points to a null-terminated string specifying the name of the mailslot. This name must have the following form:

\\.\mailslot\[path]name

The name field must be unique. The name may include multiple levels of pseudodirectories separated by backslashes. For example, both \\.\mailslot\example_mailslot_name and \\.\mailslot\abc\def\ghi are valid names.

cbMaxMsg

Specifies the maximum size, in bytes, of a single message that can be written to the mailslots. To specify that the message can be of any size, set this value to zero.

dwReadTimeout

Specifies the amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. The following values have special meanings:

Value	Meaning
0	Returns immediately if no message is present. (The system does not treat an immediate return as an error.)
MAILSLOT_WAIT_FOREVER	Waits forever for a message.
This time-out value applies to all subsequent read operations and all inherited mailslot handles.

lpsa

Points to a SECURITY_ATTRIBUTES structure specifying the security attributes for the mailslot.

If lpsa is NULL, the mailslot is created with a default security descriptor, and the resulting handle is not inherited.

The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

Return Value

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

If the function succeeds, the return value is a handle to the mailslot, for use in server mailslot operations. If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, use the GetLastError function.

Comments

The mailslot exists until one of the following conditions is true:

•	The last (possibly inherited or duplicated) handle to it is closed using the CloseHandle function.

•	The process owning the last (possibly inherited or duplicated) handle exits.

Windows NT™ ( )  Advanced Server uses the second method to destroy mailslots.

To write a message to a mailslot, a process uses the CreateFile function, specifying the mailslot name by using one of the following formats:

Format	Usage
\\.\mailslot\name	Retrieves a client handle to a local mailslot.
\\computername\mailslot\name	Retrieves a client handle to a remote mailslot.
\\domainname\mailslot\name	Retrieves a client handle to all mailslots with the given name in the specified domain.
\\*\mailslot\name	Retrieves a client handle to all mailslots with the given name in the system's primary domain.
If CreateFile specifies a domain or uses the asterisk (*) format to specify the system's primary domain, the application cannot write more than 400 bytes at a time to the mailslot. When an application attempts to write more than 400 bytes, the WriteFile function fails and the GetLastError functions returns ERROR_BAD_NETPATH.

An application must specify the FILE_SHARE_READ flag when using CreateFile to retrieve a client handle to a mailslot.

See Also

»CloseHandle«, »CreateFile«, »GetMailslotInfo«, »SetMailslotInfo«


  CreateMDIWindow

HWND CreateMDIWindow(lpszClassName, lpszWindowName, dwStyle, x, y, nWidth,
nHeight, hwndParent, hinst, lParam)
LPTSTR  lpszClassName;   /* address of registered child class name */
LPTSTR  lpszWindowName;   /* address of window name */
DWORD  dwStyle;   /* window style */
int  x;   /* horizontal position of window */
int  y;   /* vertical position of window */
int  nWidth;   /* width of window */
int  nHeight;   /* height of window */
HWND  hwndParent;   /* handle of parent window (MDI client) */
HINSTANCE  hinst;   /* handle of application instance */
LPARAM  lParam;   /* application-defined value */

The CreateMDIWindow function creates a multiple document interface (MDI) child window.

Parameters

lpszClassName

Points to a null-terminated string specifying the window class of the MDI child window. The class name must have been registered by a call to the RegisterClass function.

lpszWindowName

Points to a null-terminated string that represents the window name. Windows displays the name in the title bar of the child window.

dwStyle

Specifies the style of the MDI child window. If the MDI client window is created with the MDIS_ALLCHILDSTYLES window style, this parameter can be any combination of the window styles listed in the description of the CreateWindow function. Otherwise, this parameter can be one or more of the following values:

Value	Description
WS_MINIMIZE	Creates an MDI child window that is initially minimized.
WS_MAXIMIZE	Creates an MDI child window that is initially maximized.
WS_HSCROLL	Creates an MDI child window that has a horizontal scroll bar.
WS_VSCROLL	Creates an MDI child window that has a vertical scroll bar.
x

Specifies the initial horizontal position, in client coordinates, of the MDI child window. If this parameter is CW_USEDEFAULT, the MDI child window is assigned the default horizontal position.

y

Specifies the initial vertical position, in client coordinates, of the MDI child window. If this parameter is CW_USEDEFAULT, the MDI child window is assigned the default vertical position.

nWidth

Specifies the initial width, in device units, of the MDI child window. If this parameter is CW_USEDEFAULT, the MDI child window is assigned the default width.

nHeight

Specifies the initial height, in device units, of the MDI child window. If this parameter is set to CW_USEDEFAULT, the MDI child window is assigned the default height.

hwndParent

Identifies the MDI client window that will be the parent of the new MDI child window.

hinst

Identifies the instance of the application creating the MDI child window.

lParam

Specifies an application-defined value.

Return Value

If the function succeeds, the return value is the handle of the created window; otherwise, it is NULL.

Comments

Using the CreateMDIWindow function is similar to sending the WM_MDICREATE message to an MDI client window, except that the function can create an MDI child window in a different thread, while the message cannot.

See Also

»WM_MDICREATE«


  CreateMenu

HMENU CreateMenu(VOID)

The CreateMenu function creates a menu. The menu is initially empty, but it can be filled with menu items by using the AppendMenu and InsertMenu functions.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the newly created menu; otherwise, it is NULL.

Comments

Resources associated with a menu that is assigned to a window are freed automatically. If the menu is not assigned to a window, an application must free system resources associated with the menu before closing. An application frees menu resources by calling the DestroyMenu function.

See Also

»AppendMenu«, »DestroyMenu«, »InsertMenu«, »SetMenu«


  CreateMetaFile

HDC CreateMetaFile(lpszFile)
LPCTSTR  lpszFile;   /* address of filename string */

The CreateMetaFile function creates a device context (DC) for a Windows-format metafile.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the CreateEnhMetaFile function.

Parameters

lpszFile

Points to the filename for the Windows-format metafile to be created. If this parameter is NULL, the Windows-format metafile is memory based and its contents are lost when it is deleted by using the DeleteMetaFile function.

Return Value

If the function succeeds, the return value is a handle of the device context for the Windows-format metafile; otherwise, it is NULL.

Comments

Where text arguments must use Unicode™ characters, use this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

CreateMetaFile is a Windows-format metafile function. This function supports only applications designed for Microsoft Windows version 3.x. It does not record or play back the new Win32 graphics device interface (GDI) functions such as PolyBezier.

The device context created by this function can be used to record GDI output functions in a Windows-format metafile. It cannot be used with GDI query functions such as GetTextColor. When the DC is used with a GDI output function, the return value of that function becomes TRUE if the function is recorded and FALSE otherwise. When an object is selected by using the SelectObject function, only a copy of the object is recorded. The object still belongs to the application.

To create a scalable Windows-format metafile, record the graphics output in the MM_ANISOTROPIC mapping mode. The file cannot contain functions that modify the viewport origin and extents, nor can it contain device-dependent functions such as the SelectClipRgn function. Once created, the Windows metafile can be scaled and rendered to any output device-format by defining the viewport origin and extents of the picture before playing it.

See Also

»CloseMetaFile«, »DeleteMetaFile«, »GetTextColor«, »PolyBezier«, »SelectClipRgn«


  CreateMutex

HANDLE CreateMutex(lpsa, fInitialOwner, lpszMutexName)
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security attributes */
BOOL  fInitialOwner;   /* flag for initial ownership */
LPTSTR  lpszMutexName;   /* address of mutex-object name */

The CreateMutex function creates a named or unnamed mutex object.

Parameters

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the mutex object. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpsa is NULL, the mutex object is created with a default security descriptor and the resulting handle is not inheritable.

fInitialOwner

Specifies the initial owner of the mutex object. If TRUE, the calling thread requests immediate ownership of the mutex object. Otherwise, the mutex is not owned.

lpszMutexName

Points to a null-terminated string specifying the name of the mutex object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpszMutexName matches the name of an existing named mutex object, this function requests MUTEX_ALL_ACCESS access to the existing object. In this case, the fInitialOwner parameter is ignored because it has already been set by the creating process. If the lpsa parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpszMutexName is NULL, the mutex object is created without a name.

If lpszMutexName matches the name of an existing event, semaphore, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because event, mutex, semaphore, and file-mapping objects share the same name space.

Return Value

If the function succeeds, the return value is a handle of the mutex object. If the named mutex object existed before the function call, the GetLastError function returns ERROR_ALREADY_EXISTS. Otherwise, GetLastError returns zero.

If the function fails, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

The handle returned by CreateMutex has MUTEX_ALL_ACCESS access to the new mutex object and can be used in any function that requires a handle of a mutex object.

Any thread of the calling process can specify the mutex-object handle in a call to one of the wait functions (MsgWaitForMultipleObjects, WaitForSingleObject, WaitForMultipleObjects, WaitForSingleObjectEx, or WaitForMultipleObjectsEx). The single-object wait functions return when the state of the specified object is signaled. The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.

The state of a mutex object is signaled when it is not owned by any thread. The creating thread can use the fInitialOwner flag to request immediate ownership of the mutex. Otherwise, a thread must use one of the wait functions to request ownership. When the mutex's state is signaled, one waiting thread is granted ownership, the mutex's state changes to nonsignaled, and the wait function returns. Only one thread can own a mutex at any given time. The owning thread uses the ReleaseMutex function to release its ownership.

The thread that owns a mutex can specify the same mutex in repeated wait function calls without blocking its execution. Typically, you would not wait repeatedly for the same mutex, but this mechanism prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait.

Two or more processes can call CreateMutex to create the same named mutex. The first process actually creates the mutex, and subsequent processes open a handle of the existing mutex. This enables multiple processes to get handles of the same mutex, while relieving the user of the responsibility of ensuring that the creating process is started first. When using this technique, you should set the fInitialOwner flag to FALSE; otherwise, it can be difficult to be certain which process has initial ownership.

Multiple processes can have handles of the same mutex object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available:

•	A child process created by the CreateProcess function can inherit a handle of a mutex object if the lpsa parameter of CreateMutex enabled inheritance.

•	A process can specify the mutex-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.

•	A process can specify the name of a mutex object in a call to the OpenMutex or CreateMutex function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.

See Also

»CloseHandle«, »MsgWaitForMultipleObjects«, »OpenMutex«, »ReleaseMutex«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  CreateNamedPipe

HANDLE CreateNamedPipe(lpszPipeName, fdwOpenMode, fdwPipeMode,
nMaxInstances, cbOutBuf, cbInBuf, dwTimeout, lpsa)
LPTSTR  lpszPipeName;   /* address of pipe name */
DWORD  fdwOpenMode;   /* pipe open mode */
DWORD  fdwPipeMode;   /* pipe-specific modes */
DWORD  nMaxInstances;   /* maximum number of instances */
DWORD  cbOutBuf;   /* out buffer size in bytes */
DWORD  cbInBuf;   /* in buffer size in bytes */
DWORD  dwTimeout;   /* time-out time in milliseconds */
LPSECURITY_ATTRIBUTES  lpsa;   /* security attributes */

The CreateNamedPipe function creates an instance of a named pipe and returns a handle for subsequent pipe operations. A named pipe server process uses this function either to create the first instance of a specific named pipe and establish its basic attributes, or to create a new instance of an existing named pipe.

Parameters

lpszPipeName

Points to the null-terminated string that uniquely identifies the pipe. The string must have the following form:

\\.\pipe\pipename

The pipename part of the name can include any character, including numbers and special characters. The entire pipe name string can be up to 256 characters long. Pipe names are not case sensitive.

fdwOpenMode

Specifies the access mode, the overlapped mode, and the write-through mode of the pipe handle. It must specify one of the following access-mode flags, and the same one must be specified for each instance of the pipe:

Value	Meaning
PIPE_ACCESS_DUPLEX
	The pipe is bidirectional; both server and client processes can read from and write to the pipe. This gives the server the equivalent of GENERIC_READ | GENERIC_WRITE access to the pipe. The client can specify GENERIC_READ or GENERIC_WRITE, or both, when it connects to the pipe using the CreateFile function.
PIPE_ACCESS_INBOUND
	The flow of data in the pipe goes from client to server only. This gives the server the equivalent of GENERIC_READ access to the pipe. The client must specify GENERIC_WRITE access when connecting to the pipe.
PIPE_ACCESS_OUTBOUND
	The flow of data in the pipe goes from server to client only. This gives the server the equivalent of GENERIC_WRITE access to the pipe. The client must specify GENERIC_READ access when connecting to the pipe.
The fdwOpenMode parameter can also include either or both of the following flags, to enable write-through mode or overlapped mode. These flags can be different for different instances of the same pipe.

Value	Meaning
FILE_FLAG_WRITE_THROUGH
	Write-through mode is enabled. This mode affects only write operations on byte-type pipes, and then only when the client and server processes are on different computers. If enabled, the functions that write to a named pipe do not return until the data written is transmitted across the network and is in the pipe's buffer on the remote computer. If not enabled, the system enhances the efficiency of network operations by buffering data until a minimum number of bytes accumulate or until a maximum time elapses.
FILE_FLAG_OVERLAPPED
	Overlapped mode is enabled. If enabled, the functions that perform read, write, and connect operations that may take a significant time to be completed can return immediately. This enables the thread that started the operation to perform other operations while the time-consuming operation executes in the background. For example, in overlapped mode, a thread can handle simultaneous I/O operations on multiple instances of a pipe or perform simultaneous read and write operations on the same pipe handle. If overlapped mode is not enabled, the functions that perform read, write, and connect operations on the pipe handle do not return until the operation is finished. The ReadFileEx and WriteFileEx functions can only be used with a pipe handle in overlapped mode. The ReadFile, WriteFile, ConnectNamedPipe, and TransactNamedPipe functions can execute either synchronously or as overlapped operations.
fdwPipeMode

Specifies the type, read mode, and wait mode of the pipe handle.

One of the following type flags can be specified. The same one must be specified for each instance of the pipe. If you specify zero, the parameter defaults to byte-type mode.

Value	Meaning
PIPE_TYPE_BYTE
	Data is written to the pipe as a stream of bytes. This flag cannot be used with the PIPE_READMODE_MESSAGE flag.
PIPE_TYPE_MESSAGE
	Data is written to the pipe as a stream of messages. This flag can be used with either PIPE_READMODE_MESSAGE or PIPE_READMODE_BYTE.
One of the following read mode flags can be specified. Different instances of the same pipe can specify different read modes. If you specify zero, the parameter defaults to byte-read mode.

Value	Meaning
PIPE_READMODE_BYTE
	Data is read from the pipe as a stream of bytes. This flag can be used with either PIPE_TYPE_MESSAGE or PIPE_TYPE_BYTE.
PIPE_READMODE_MESSAGE
	Data is read from the pipe as a stream of messages. This flag can be only used if PIPE_TYPE_MESSAGE is also specified.
One of the following wait mode flags can be specified. Different instances of the same pipe can specify different wait modes. If you specify zero, the parameter defaults to blocking mode.

Value	Meaning
PIPE_WAIT
	Blocking mode is enabled. When the pipe handle is specified in the ReadFile, WriteFile, or ConnectNamedPipe function, the operations are not completed until there is data to read, all data is written, or a client is connected. This can mean waiting indefinitely in some situations for a client process to perform an action.
PIPE_NOWAIT
	Nonblocking mode is enabled. In this mode, ReadFile, WriteFile, and ConnectNamedPipe always return immediately. Note that nonblocking mode is supported for compatibility with Microsoft® LAN Manager version 2.0, and should not be used to achieve asynchronous I/O with named pipes.
nMaxInstances

Specifies the maximum number of instances that can be created for this pipe. The same number must be specified for all instances. Acceptable values are in the range 1 through PIPE_UNLIMITED_INSTANCES. If this parameter is PIPE_UNLIMITED_INSTANCES, the number of pipe instances that can be created is limited only by the availability of system resources.

cbOutBuf

Specifies the number of bytes to reserve for the output buffer. See the Comments section below for a discussion on sizing named pipe buffers.

cbInBuf

Specifies the number of bytes to reserve for the input buffer. See the Comments section below for a discussion on sizing named pipe buffers.

dwTimeout

Specifies the default time-out value, in milliseconds, if the WaitNamedPipe function specifies NMPWAIT_USE_DEFAULT_WAIT. Each instance of a named pipe must specify the same value.

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the pipe. Since named pipes are implemented as a file system, and that file system supports the lpsa parameter, lpsa will always have an effect when specified.

The SECURITY_ATTRIBUTES structure has the following format:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

If lpsa is NULL, the pipe is created with a default security descriptor, and the resulting handle is not inherited. For a full description of the SECURITY ATTRIBUTES structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle to the server end of a named pipe instance . Otherwise, it is INVALID_HANDLE_VALUE. To get extended error information, use the GetLastError function. The return value is ERROR_INVALID_PARAMETER if nMaxInstances is greater than PIPE_UNLIMITED_INSTANCES.

Comments

To create an instance of a named pipe by using the CreateNamedPipe function the user must have FILE_CREATE_PIPE_INSTANCE access to the named pipe object. If a new named pipe is being created, then the access control list (ACL) from the security attributes parameter defines the discretionary access control for the named pipe.

All instances of a named pipe must specify the same pipe type (byte- or message-type), pipe access (duplex, inbound, or outbound), instance count, and time-out value. If different values are used, this function fails and the GetLastError function returns ERROR_ACCESS_DENIED.

The input and output buffer sizes are advisory. The actual buffer size reserved for each end of the named pipe is either the system default, the system minimum or maximum, or the specified size rounded up to the next allocation boundary.

An instance of a named pipe is always deleted when the last handle to the instance of the named pipe is closed.

See Also

»ConnectNamedPipe«, »ReadFile«, »ReadFileEx«, »TransactNamedPipe«, »WaitNamedPipe«, »WriteFile«, »WriteFileEx«


  CreatePalette

HPALETTE CreatePalette(lplgpl)
CONST LOGPALETTE  *lplgpl;   /* address of logical color palette */

The CreatePalette function creates a logical color palette.

Parameters

lplgpl

Points to a LOGPALETTE structure that contains information about the colors in the logical palette. The LOGPALETTE structure has the following form:

typedef struct tagLOGPALETTE { /* lgpl */

    WORD         palVersion;

    WORD         palNumEntries;

    PALETTEENTRY palPalEntry[1];

} LOGPALETTE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle that identifies a logical palette; otherwise it is NULL. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

Once an application creates a logical palette, it can select that palette into a device context by calling the SelectPalette function. A palette selected into a device context can be realized by calling the RealizePalette function.

See Also

»GetDeviceCaps«, »RealizePalette«, »SelectPalette«


  CreatePatternBrush

HBRUSH CreatePatternBrush(hbmp)
HBITMAP  hbmp;   /* handle of bitmap */

The CreatePatternBrush function creates a logical brush with the specified bitmap pattern.

Parameters

hbmp

Identifies the bitmap to be used to create the logical brush.

Return Value

If the function succeeds, the return value identifies a logical brush; otherwise, it is NULL.

Comments

A pattern brush is a bitmap that Windows uses to paint the interiors of filled shapes.

After an application creates a brush by calling CreatePatternBrush, it can select that brush into any device context (DC) by calling the SelectObject function.

You can delete a pattern brush without affecting the associated bitmap by using the DeleteObject function. Therefore, you can then use this bitmap to create any number of pattern brushes.

A brush created by using a monochrome (1 bit per pixel) bitmap has the text and background colors of the DC to which it is drawn. Pixels represented by a 0 bit are drawn with the current text color; pixels represented by a 1 bit are drawn with the current background color.

See Also

»CreateBitmap«, »CreateBitmapIndirect«, »CreateCompatibleBitmap«, »CreateDIBPatternBrush«, »CreateDIBPatternBrushPt«, »CreateHatchBrush«, »DeleteObject«, »GetBrushOrgEx«, »LoadBitmap«, »SelectObject«, »SetBrushOrgEx«


  CreatePen

HPEN CreatePen(fnPenStyle, nWidth, crColor)
int  fnPenStyle;   /* pen style */
int  nWidth;   /* pen width */
COLORREF  crColor;   /* pen color */

The CreatePen function creates a logical cosmetic pen that has the specified style, width, and color. The pen can subsequently be selected into a device context and used to draw lines and curves.

Parameters

fnPenStyle

Specifies the pen style. It can be any one of the following values:

Value	Meaning
PS_SOLID	Pen is solid.
PS_DASH	Pen is dashed. This style is valid only when the pen width is one or less in device units.
PS_DOT	Pen is dotted. This style is valid only when the pen width is one or less in device units.
PS_DASHDOT	Pen has alternating dashes and dots. This style is valid only when the pen width is one or less in device untis.
PS_DASHDOTDOT	Pen has alternating dashes and double dots. This style is valid only when the pen width is one or less in device units.
PS_NULL	Pen is invisible.
PS_INSIDEFRAME	Pen is solid. When this pen is used in any graphics device interface (GDI) drawing function that takes a bounding rectangle, the dimensions of the figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to geometric pens.
nWidth

Specifies the width of the pen, in logical units. If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation.

crColor

Specifies a color reference for the pen color.

Return Value

If the function succeeds, the return value is a handle that identifies a logical cosmetic pen; otherwise, it is NULL.

Comments

After an application creates a logical pen, it can select that pen into a device context by calling the SelectObject function. After a pen is selected into a device context, it can be used to draw lines and curves.

If the value specified by the nWidth parameter is zero, a line drawn with the created pen will always be a single pixel wide — regardless of the current transformation.

If the value specified by nWidth is greater than 1, the fnPenStyle parameter must be PS_NULL, PS_SOLID, or PS_INSIDEFRAME.

If the value specified by nWidth is greater than 1 and fnPenStyle is PS_INSIDEFRAME, the line associated with the pen is drawn inside the frame of all primitives except polygons and polylines.

If the value specified by nWidth is greater than 1, fnPenStyle is PS_INSIDEFRAME, and the color specified by the crColor parameter does not match one of the entries in the logical palette, Windows draws lines by using a dithered color. Dithered colors are not available with solid pens.

When an application no longer requires a given pen, it should call the DeleteObject function to delete the pen from the device context.

See Also

»CreatePenIndirect«, »DeleteObject«, »ExtCreatePen«, »GetObject«, »RGB«, »SelectObject«


  CreatePenIndirect

HPEN CreatePenIndirect(lplgpn)
LPLOGPEN  lplgpn;   /* address of LOGPEN structure */

The CreatePenIndirect function creates a logical cosmetic pen that has the style, width, and color specified in the given structure.

Parameters

lplgpn

Points to the LOGPEN structure that specifies the pen's style, width, and color. The LOGPEN structure has the following form:

typedef struct tagLOGPEN { /* lgpn */

    UINT     lopnStyle;

    POINT    lopnWidth;

    COLORREF lopnColor;

} LOGPEN;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle that identifies a logical cosmetic pen; otherwise, it is NULL.

Comments

After an application creates a logical pen, it can select that pen into a device context by calling the SelectObject function. After a pen is selected into a device context, it can be used to draw lines and curves.

When an application no longer requires a given pen, it should call the DeleteObject function to delete the pen from the device context.

See Also

»CreatePen«, »DeleteObject«, »ExtCreatePen«, »GetObject«, »RGB«, »SelectObject«, »LOGPEN«


  CreatePipe

BOOL CreatePipe(phRead, phWrite, lpsa, cbPipe)
PHANDLE  phRead;   /* address of variable for read handle */
PHANDLE  phWrite;   /* address of variable for write handle */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security attributes */
DWORD  cbPipe;   /* number of bytes reserved for pipe */

The CreatePipe function creates an anonymous pipe and returns handles to the read and write ends of the pipe.

Parameters

phRead

Points to the variable that receives the read handle for the pipe.

phWrite

Points to the variable that receives the write handle for the pipe.

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the pipe. The file system must support this parameter for it to have an effect. The SECURITY_ATTRIBUTES structure has the following format:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

If lpsa is NULL, the pipe is created with a default security descriptor, and the resulting handle is not inherited. For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

cbPipe

Specifies the buffer size for the pipe. This is only a suggestion; the system uses this value to calculate an appropriate buffering mechanism. If this parameter is zero, the system uses the default buffer size.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CreatePipe function creates the pipe, assigning the specified pipe size to the storage buffer. CreatePipe also creates handles that the process uses to read from and write to the buffer in subsequent calls to ReadFile and WriteFile.

When a process uses WriteFile to write to an anonymous pipe, the write operation is not completed until all bytes are written. If the pipe buffer is full before all bytes are written, WriteFile does not return until another process or thread uses ReadFile to make more buffer space available.

See Also

»ReadFile«, »WriteFile«


  CreatePolygonRgn

HRGN CreatePolygonRgn(lppt, cPoints, fnPolyFillMode)
CONST POINT  *lppt;   /* address of array of points */
int  cPoints;   /* number of points in array */
int  fnPolyFillMode;   /* polygon-filling mode */

The CreatePolygonRgn function creates a polygonal region.

Parameters

lppt

Points to an array of POINT structures that define the vertices of the polygon. The polygon is presumed closed. Each vertex can be specified only once. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cPoints

Specifies the number of points in the array.

fnPolyFillMode

Specifies the fill mode used to determine which pixels are in the region. This parameter can be one of the following values:

Value	Meaning
ALTERNATE	Selects alternate mode (fills area between odd-numbered and even-numbered polygon sides on each scan line).
WINDING	Selects winding mode (fills any region with a nonzero winding value).
For more information about these modes, see the »SetPolyFillMode« function.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is NULL.

See Also

»CreatePolyPolygonRgn«, »DeleteObject«, »SelectObject«, »SetPolyFillMode«


  CreatePolyPolygonRgn

HRGN CreatePolyPolygonRgn(lppt, lpPolyCounts, nCount, fnPolyFillMode)
CONST POINT  *lppt;   /* address of array of points */
CONST INT  *lpPolyCounts;   /* address of array that contains vertex counts */
int  nCount;   /* number of integers in array of vertex counts */
int  fnPolyFillMode;   /* polygon fill mode */

The CreatePolyPolygonRgn function creates a region consisting of a series of polygons. The polygons can overlap.

Parameters

lppt

Points to an array of POINT structures that define the vertices of the polygons. The polygons are specified consecutively. Each polygon is presumed closed and each vertex is specified only once. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpPolyCounts

Points to an array of integers, each of which specifies the number of points in one of the polygons in the lppt array.

nCount

Specifies the total number of integers in the lpPolyCounts array.

fnPolyFillMode

Specifies the fill mode used to determine which pixels are in the region. This parameter can be one of the following values:

Value	Meaning
ALTERNATE	Selects alternate mode (fills area between odd-numbered and even-numbered polygon sides on each scan line).
WINDING	Selects winding mode (fills any region with a nonzero winding value).
For more information about these modes, see the »SetPolyFillMode« function.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is 0.

See Also

»CreatePolygonRgn«, »DeleteObject«, »SelectObject«, »SetPolyFillMode«


  CreatePopupMenu

HMENU CreatePopupMenu(VOID)

The CreatePopupMenu function creates a pop-up menu. The menu is initially empty, but it can be filled with menu items by using the AppendMenu and InsertMenu functions.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the newly created pop-up menu; otherwise, it is NULL.

Comments

The application can add the pop-up menu to an existing menu or pop-up menu, or it can display and track selections on the pop-up menu by calling the TrackPopupMenu function.

Resources associated with a pop-up menu that is assigned to a window are freed automatically. If the pop-up menu is not assigned to a window, an application must free system resources associated with the menu before closing. An application frees menu resources by calling the DestroyMenu function.

See Also

»AppendMenu«, »CreateMenu«, »InsertMenu«, »SetMenu«, »TrackPopupMenu«


  CreatePrivateObjectSecurity

BOOL CreatePrivateObjectSecurity(psdParent, psdCreator, lppsdNew, fContainer,
hClientToken, pgm)
PSECURITY_DESCRIPTOR  psdParent;   /* address of parent directory SD */
PSECURITY_DESCRIPTOR  psdCreator;   /* address of creator SD */
PSECURITY_DESCRIPTOR *  lppsdNew;   /* address of pointer to new SD */
BOOL  fContainer;   /* container flag for new SD */
HANDLE  hClientToken;   /* handle of client's access token */
PGENERIC_MAPPING  pgm;   /* address of access-rights structure */

The CreatePrivateObjectSecurity function allocates and initializes a self-relative security descriptor for a new protected server's object. This function is called when a new protected server object is being created.

Parameters

psdParent

Points to the security descriptor for the parent directory in which a new object is being created. If there is no parent directory, this parameter can be NULL.

psdCreator

Points to a security descriptor provided by the creator of the object. If the object's creator does not explicitly pass security information for the new object, this parameter is intended to be NULL.

lppsdNew

Points to a pointer to the newly allocated security descriptor created when the function returns.

fContainer

Specifies whether the new object is a container. A value of TRUE indicates the object contains other objects, such as a directory.

hClientToken

Identifies the access token for the client process on whose behalf the object is being created. If this is an impersonation token, it must be at SecurityIdentification level or higher. For a full description of the SecurityIdentification impersonation level, see the »SECURITY_IMPERSONATION_LEVEL« enumerated type in the Microsoft Win32 Programmer's Reference, Volume 5.

A client token is used to retrieve default security information for the new object, such as its default owner, primary group, and discretionary access-control list. The token must be open for TOKEN_QUERY access.

pgm

Points to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

The GENERIC_MAPPING structure has the following form:

typedef struct _GENERIC_MAPPING { /* gm */

    ACCESS_MASK GenericRead;

    ACCESS_MASK GenericWrite;

    ACCESS_MASK GenericExecute;

    ACCESS_MASK GenericAll;

} GENERIC_MAPPING;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If a system access-control list, or SACL, is specified in the SECURITY_DESCRIPTOR specified by psdCreator, hClientToken must have SeSecurityPrivilege enabled, and the caller's token must have SeAuditPrivilege enabled. The CreatePrivateObjectSecurity function performs access/privilege checks to ensure this, and may generate audits during the process.

The CreatePrivateObjectSecurity function may send many messages to port objects. This can result in a significant delay before the function returns. Be sure to take this potential delay into account when designing an application that calls CreatePrivateObjectSecurity. An application that uses mutexes to lock structures, for example, usually seeks to avoid such potentially-long lockups.

See Also

»DestroyPrivateObjectSecurity«, »GetPrivateObjectSecurity«, »GetTokenInformation«, »OpenProcessToken«, »SetPrivateObjectSecurity«


  CreateProcess

BOOL CreateProcess(lpszImageName, lpszCommandLine, lpsaProcess, lpsaThread,
fInheritHandles, fdwCreate, lpvEnvironment, lpszCurDir, lpsiStartInfo, lppiProcInfo)
LPCTSTR  lpszImageName;   /* address of module name */
LPCTSTR  lpszCommandLine;   /* address of command line */
LPSECURITY_ATTRIBUTES  lpsaProcess;   /* address of process security attrs */
LPSECURITY_ATTRIBUTES  lpsaThread;   /* address of thread security attrs */
BOOL  fInheritHandles;   /* new process inherits handles? */
DWORD  fdwCreate;   /* creation flags */
LPVOID  lpvEnvironment;   /* address of new environment block */
LPTSTR  lpszCurDir;   /* address of current directory name */
LPSTARTUPINFO  lpsiStartInfo;   /* address of STARTUPINFO */
LPPROCESS_INFORMATION  lppiProcInfo;   /* address of PROCESS_INFORMATION */

The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.

Parameters

lpszImageName

Points to a null-terminated string specifying the full path and filename of the module to execute. If a partial name is specified, the current drive and current directory are used by default. If this parameter is NULL, the module name must be the first white space−delimited token in the lpszCommandLine string. The specified module can be a Win32 application, or it can be some other type of module (for example,MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.

lpszCommandLine

Points to a null-terminated string specifying the command line for the application to be executed. If this parameter is NULL, the lpszImageName string is used as the command line. If both lpszImageName and lpszCommandLine are non-NULL, lpszImageName specifies the module to execute and lpszCommandLine is used as the command line. The new process can use GetCommandLine to retrieve the entire command line; or C runtime processes can use the argc/argv mechanism.

If lpszImageName is NULL, the first white space−delimited token of the command line specifies the module name. If the filename does not contain an extension, .EXE is assumed. If the filename ends in a "." with no extension, or the filename contains a path, .EXE is not appended. If the filename does not contain a directory path, Windows searches for the executable file in the following sequence:

1.	The directory from which the application loaded.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

lpsaProcess

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the created process. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpsaProcess is NULL, the process is created with a default security descriptor, and the resulting handle is not inherited.

lpsaThread

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the primary thread of the new process. If lpsaThread is NULL, the process is created with a default security descriptor, and the resulting handle is not inherited.

fInheritHandles

Indicates whether the new process inherits handles from the calling process. If TRUE, each inheritable open handle in the calling process is inherited by the new process. Inherited handles have the same value and access privileges as the original handles.

fdwCreate

Specifies additional flags that control the priority class and the creation of the process. The following creation flags can be specified in any combination, except as noted:

Value	Meaning
DEBUG_PROCESS
	If set, the calling process is treated as a debugger, and the new process is a process being debugged. The system notifies the debugger of all debug events that occur in the process being debugged.
	If not set and the calling process is being debugged, the new process becomes another process being debugged by the calling process's debugger. If the calling process is not a process being debugged, no debugging-related actions occur.
DEBUG_ONLY_THIS_PROCESS
	If set, the calling process is treated as a debugger, and the new process is a process being debugged. If the new process creates additional processes, the system does not notify the debugger of any debug events that occur in the additional processes.
CREATE_SUSPENDED
	The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
DETACHED_PROCESS
	For console processes, the new process does not have access to the console of the parent process. The new process can call AllocConsole if it later wants to create a new console. This flag cannot be used with the CREATE_NEW_CONSOLE flag.
CREATE_NEW_CONSOLE
	The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag.
CREATE_NO_WINDOW
	The created process has a console, but no window. This flag should not be used by applications. It is intended only for internal use to implement VDM code.
CREATE_NEW_PROCESS_GROUP
	The new process is the root process of a new process group. The process group includes all processes that are descendants of this root process. The process group ID of the new process group is the same as the process ID, which is returned in the lppiProcInfo structure. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or CTRL+BREAK signal to a group of console processes.
The fdwCreate parameter also controls the new process's priority class, which is used in determining the scheduling priorities of the process's threads. If none of the following priority class flags is specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS. In this case the default priority class of the child process is IDLE_PRIORITY_CLASS. One of the following flags can be specified:

Priority	Meaning
IDLE_PRIORITY_CLASS	Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS	Indicates a normal process with no special scheduling needs.
HIGH_PRIORITY_CLASS	Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
REALTIME_PRIORITY_CLASS	Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.
lpvEnvironment

Points to an environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process. The environment block consists of a null-terminated block of null-terminated strings (that is, two null bytes at the end of the block). Each string is in the form:

name=value

Because the equal sign is used as a separator, it must not be used in the name of an environment variable.

If an application provides an environment block, rather than passing NULL for this parameter, the system's drives' current directory information is not automatically propagated to the new process. See the Comments section below for a discussion of this situation and how to handle it.

lpszCurDir

Points to a null-terminated string that specifies the current drive and directory for the new process. The string must be a full path and filename that includes a drive letter. If this parameter is NULL, the new process is created with the same current drive and directory as the calling process. This option is provided primarily for shells that need to start an application and specify its initial drive and working directory.

lpsiStartInfo

Points to a STARTUPINFO structure that specifies how the main window for the new process should appear. The STARTUPINFO structure has the following form:

typedef struct _STARTUPINFO { /* si */

    DWORD   cb;

    LPTSTR  lpReserved;

    LPTSTR  lpDesktop;

    LPTSTR  lpTitle;

    DWORD   dwX;

    DWORD   dwY;

    DWORD   dwXSize;

    DWORD   dwYSize;

    DWORD   dwXCountChars;

    DWORD   dwYCountChars;

    DWORD   dwFillAttribute;

    DWORD   dwFlags;

    WORD    wShowWindow;

    WORD    cbReserved2;

    LPBYTE  lpReserved2;

    HANDLE  hStdInput;

    HANDLE  hStdOutput;

    HANDLE  hStdError;

} STARTUPINFO, *LPSTARTUPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lppiProcInfo

Points to a PROCESS_INFORMATION structure that receives identification information about the new process. The PROCESS_INFORMATION structure has the following form:

typedef struct _PROCESS_INFORMATION { /* pi */

    HANDLE hProcess;

    HANDLE hThread;

    DWORD dwProcessId;

    DWORD dwThreadId;

} PROCESS_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CreateProcess function is used to run a new program. The WinExec and LoadModule functions are still available, but they are implemented as calls to the CreateProcess function.

In addition to creating a process, CreateProcess also creates a thread object. The thread is created with an initial stack whose size is described in the image header of the specified program's executable file. The thread begins execution at the image's entrypoint.

The the new process and the new thread handles are created with full access rights. For either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle of that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process is not be able to use the handle to gain access to the thread.

The process is assigned a 32-bit process identifier. The ID is valid until the process terminates. It can be used to identify the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also assigned a 32-bit thread identifier. The ID is valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are returned in the PROCESS_INFORMATION structure.

The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.

The preferred way to shut down a process is by using the ExitProcess command, because this function notifies all DLLs attached to the process of the approaching termination. Other means of shutting down a process do not notify the attached DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs).

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

1.	During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

2.	Only one thread in a process can be in a DLL initialization or detach routine at a time.

3.	The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created.

When the last thread in a process terminates, the following events occur:

•	All objects opened by the process are implicitly closed.

•	The process's termination status (which is returned by GetExitCodeProcess) changes from its initial value of STILL_ACTIVE to the termination status of the last thread to terminate.

•	The thread object of the main thread is set to the signaled state, satisfying any threads that were waiting on the object.

•	The process object is set to the signaled state, satisfying any threads that were waiting on the object.

If the current directory on drive c: is \msvc\mfc, there is an environment variable called =C: whose value is C:\MSVC\MFC. As noted above in the description of lpvEnvironment, such current directory information for a system's drives does not automatically propagate to a new process when  the CreateProcess function's lpvEnvironment parameter is non-NULL. An application must manually pass the current directory  information to the new process. To do so, the application  must explicitly create the =X environment variable strings, get  them into alphabetical order (since Windows NT uses a sorted environment), and then put  them into  the environment block specified by lpvEnvironment. Typically they will go at the front  of the environment block, due to the aforementioned Windows NT environment block sorting.

One way to obtain a drive X:'s current directory variable is to call GetFullPathName("X:",...). That avoids an application having to scan the environment block. If the full path returned is X:\,  there is no need to pass that value on as environment data, since the root directory is the default current directory for a new process' X: drive.

The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object.

See Also

»AllocConsole«, »CloseHandle«, »CreateRemoteThread«, »CreateThread«, »ExitProcess«, »ExitThread«, »GetCommandLine«, »GetEnvironmentStrings«, »GetExitCodeProcess«, »GetStartupInfo«, »GetSystemDirectory«, »GetWindowsDirectory«, »OpenProcess«, »ResumeThread«, »TerminateProcess«


  CreateRectRgn

HRGN CreateRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect)
int  nLeftRect;   /* x-coordinate of upper left corner */
int  nTopRect;   /* y-coordinate of upper left corner */
int  nRightRect;   /* x-coordinate of lower right corner */
int  nBottomRect;   /* y-coordinate of lower right corner */

The CreateRectRgn function creates a rectangular region.

Parameters

nLeftRect

Specifies the x-coordinate of the upper left corner of the region.

nTopRect

Specifies the y-coordinate of the upper left corner of the region.

nRightRect

Specifies the x-coordinate of the lower right corner of the region.

nBottomRect

Specifies the y-coordinate of the lower right corner of the region.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is NULL.

Comments

The region will be exclusive of the bottom and right edges.

See Also

»CreateRectRgnIndirect«, »CreateRoundRectRgn«, »DeleteObject«, »SelectObject«


  CreateRectRgnIndirect

HRGN CreateRectRgnIndirect(lprc)
CONST RECT  *lprc;   /* address of the rectangle */

The CreateRectRgnIndirect function creates a rectangular region.

Parameters

lprc

Points to a RECT structure that contains the coordinates of the upper left and lower right corners of the rectangle that defines the region. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is NULL.

Comments

The region will be exclusive of the bottom and right edges.

See Also

»CreateRectRgn«, »CreateRoundRectRgn«, »DeleteObject«, »SelectObject«


  CreateRemoteThread

HANDLE CreateRemoteThread(hProcess, lpsa, cbStack, lpStartAddr, lpvThreadParm,
fdwCreate, lpIDThread)
HANDLE  hProcess;   /* handle to process to create thread in */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of thread security attrs */
DWORD  cbStack;   /* initial thread stack size */
LPTHREAD_START_ROUTINE  lpStartAddr;   /* address of thread function */
LPVOID  lpvThreadParm;   /* address of argument for new thread */
DWORD  fdwCreate;   /* creation flags */
LPDWORD  lpIDThread;   /* address of returned thread identifier */

The CreateRemoteThread function creates a thread that runs in the address space of the another process.

Parameters

hProcess

Identifies the process in which the thread is to be created. The handle must have PROCESS_CREATE_THREAD access.

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the thread. The SECURITY_ATTRIBUTES structure has the following format:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpsa is NULL, the thread is created with a default security descriptor, and the resulting handle is not inherited.

cbStack

Specifies the size, in bytes, of the stack for the new thread. If this value is zero, the stack size defaults to the same size as that of the primary thread of the process. The stack is allocated automatically in the memory space of the process and is freed when the thread terminates. Note that the stack size grows as necessary.

lpStartAddr

Points to the starting address of the new thread. The address is logically a procedure that never returns and that accepts as an argument a single 32-bit pointer argument.

lpvThreadParm

Points to a single 32-bit value passed to the thread.

fdwCreate

Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation.

lpIDThread

Points to a 32-bit variable that receives the thread identifier.

Return Value

If the function succeeds, the return value is a handle to the new thread; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The CreateRemoteThread function causes a new thread of execution to begin in the address space of the specified process. The thread has access to all objects opened by the process.

The new thread handle is created with full access to the new thread. If a security descriptor is not provided, the handle may be used in any function that requires a thread object handle. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread.

The thread execution begins at the function specified by the lpStartAddr parameter. If this function returns, the results are unspecified.

The CreateRemoteThread function may succeed even if lpStartAddr points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a bad start address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to bad or missing DLLs.

The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread.

When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting on the object.

The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

1.	During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

2.	Only one thread in a process can be in a DLL initialization or detach routine at a time.

3.	The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

See Also

»CloseHandle«, »CreateProcess«, »CreateThread«, »ExitProcess«, »ExitThread«, »ResumeThread«


  CreateRoundRectRgn

HRGN CreateRoundRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect,
nWidthEllipse, nHeightEllipse)
int  nLeftRect;   /* x-coordinate upper left corner of region */
int  nTopRect;   /* y-coordinate upper left corner of region */
int  nRightRect;   /* x-coordinate lower right corner of region */
int  nBottomRect;   /* y-coordinate lower right corner of region */
int  nWidthEllipse;   /* height of ellipse for rounded corners */
int  nHeightEllipse;   /* width of ellipse for rounded corners */

The CreateRoundRectRgn function creates a rectangular region with rounded corners.

Parameters

nLeftRect

Specifies the x-coordinate of the upper left corner of the region.

nTopRect

Specifies the y-coordinate of the upper left corner of the region.

nRightRect

Specifies the x-coordinate of the lower right corner of the region.

nBottomRect

Specifies the y-coordinate of the lower right corner of the region.

nWidthEllipse

Specifies the width of the ellipse used to create the rounded corners.

nHeightEllipse

Specifies the height of the ellipse used to create the rounded corners.

Return Value

If the function succeeds, the return value is the handle of the region; otherwise, it is NULL.

See Also

»CreateRectRgn«, »CreateRectRgnIndirect«, »DeleteObject«, »SelectObject«


  CreateScalableFontResource

BOOL CreateScalableFontResource(fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath)
DWORD  fdwHidden;   /* flag for read-only embedded font */
LPCTSTR  lpszFontRes;   /* address of filename for font resource */
LPCTSTR  lpszFontFile;   /* address of filename for scalable font */
LPTSTR  lpszCurrentPath;   /* address of path to font file */

The CreateScalableFontResource function creates a font resource file for a scalable font.

Parameters

fdwHidden

Specifies whether the font is a read-only embedded font. This parameter can be one of the following values:

Value	Meaning
0	The font has read-write permission.
1	The font has read-only permission and should be hidden from other applications in the system. When this flag is set, the font is not enumerated by the EnumFonts or EnumFontFamilies function.
lpszFontRes

Points to a null-terminated string specifying the name of the font resource file that this function creates.

lpszFontFile

Points to a null-terminated string specifying the name of the scalable font file that this function uses to create the font resource file.

lpszCurrentPath

Points to a null-terminated string specifying the path to the scalable font file.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The CreateScalableFontResource function is used by applications that install TrueType fonts. An application uses the CreateScalableFontResource function to create a font resource file (typically with a .FOT filename extension) and then uses the AddFontResource function to install the font. The TrueType® font file (typically with a .TTF filename extension) must be in the SYSTEM subdirectory of the WINDOWS directory to be used by the AddFontResource function.

The CreateScalableFontResource function currently supports only TrueType-technology scalable fonts.

When the lpszFontFile parameter specifies only a filename and extension, the lpszCurrentPath parameter must specify a path. When the lpszFontFile parameter specifies a full path, the lpszCurrentPath parameter must be NULL or a pointer to NULL.

When only a filename and extension are specified in the lpszFontFile parameter and a path is specified in the lpszCurrentPath parameter, the string in lpszFontFile is copied into the .FOT file as the .TTF file that belongs to this resource. When the AddFontResource function is called, the operating system assumes that the .TTF file has been copied into the SYSTEM directory (or into the main Windows directory in the case of a network installation). The .TTF file need not be in this directory when the CreateScalableFontResource function is called, because the lpszCurrentPath parameter contains the directory information. A resource created in this manner does not contain absolute path information and can be used in any Windows installation.

When a path is specified in the lpszFontFile parameter and NULL is specified in the lpszCurrentPath parameter, the string in lpszFontFile is copied into the .FOT file. In this case, when the AddFontResource function is called, the .TTF file must be at the location specified in the lpszFontFile parameter when the CreateScalableFontResource function was called; the lpszCurrentPath parameter is not needed. A resource created in this manner contains absolute references to paths and drives and does not work if the .TTF file is moved to a different location.

See Also

»AddFontResource«


  CreateSemaphore

HANDLE CreateSemaphore(lpsa, cSemInitial, cSemMax, lpszSemName)
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security attributes */
LONG  cSemInitial;   /* initial count */
LONG  cSemMax;   /* maximum count */
LPTSTR  lpszSemName;   /* address of semaphore-object name */

The CreateSemaphore function creates a named or unnamed semaphore object.

Parameters

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the semaphore object. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpsa is NULL, the semaphore object is created with a default security descriptor and the resulting handle is not inheritable.

cSemInitial

Specifies an initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to cSemMax. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased by a specified amount by calling the ReleaseSemaphore function.

cSemMax

Specifies the maximum count for the semaphore object. This value must be greater than zero.

lpszSemName

Points to a null-terminated string specifying the name of the semaphore object. The name is limited to MAX_PATH characters, and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpszSemName matches the name of an existing named semaphore object, this function requests SEMAPHORE_ALL_ACCESS access to the existing object. In this case, the cSemInitial and cSemMax parameters are ignored because they have already been set by the creating process. If the lpsa parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpszSemName is NULL, the semaphore object is created without a name.

If lpszSemName matches the name of an existing event, mutex, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because event, mutex, semaphore, and file-mapping objects share the same name space.

Return Value

If the function succeeds, the return value is a handle of the semaphore object. If the named semaphore object existed before the function call, the GetLastError function returns ERROR_ALREADY_EXISTS. Otherwise, GetLastError returns zero.

If the function fails, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

The handle returned by CreateSemaphore has SEMAPHORE_ALL_ACCESS access to the new semaphore object and can be used in any function that requires a handle of a semaphore object.

Any thread of the calling process can specify the semaphore-object handle in a call to one of the wait functions (MsgWaitForMultipleObjects, WaitForSingleObject, WaitForMultipleObjects, WaitForSingleObjectEx, or WaitForMultipleObjectsEx). The single-object wait functions return when the state of the specified object is signaled. The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.

The state of a semaphore object is signaled when its count is greater than zero, and nonsignaled when its count is equal to zero. The cSemInitial parameter specifies the initial count. Each time a waiting thread is released because of the semaphore's signaled state, the count of the semaphore is decreased by one. Use the ReleaseSemaphore function to increment a semaphore's count by a specified amount. The count can never be less than zero or greater than the value specified in the cSemMax parameter.

Multiple processes can have handles of the same semaphore object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available:

•	A child process created by the CreateProcess function can inherit a handle of a semaphore object if the lpsa parameter of CreateSemaphore enabled inheritance.

•	A process can specify the semaphore-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.

•	A process can specify the name of a semaphore object in a call to the OpenSemaphore or CreateSemaphore function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The semaphore object is destroyed when its last handle has been closed.

See Also

»CloseHandle«, »OpenSemaphore«, »ReleaseSemaphore«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  CreateService

SC_HANDLE CreateService(schSCManager, lpszServiceName, fdwDesiredAccess,
fdwServiceType, fdwStartType, fdwErrorControl, lpszBinaryPathName, lpszLoadOrderGroup,
lpdwTagID, lpszDependencies, lpszServiceStartName, lpszPassword)
SC_HANDLE  schSCManager;   /* handle of service control manager database */
LPCTSTR  lpszServiceName;   /* address of name of service to start */
LPCTSTR  lpszDisplayName;   /* address of display name */
DWORD  fdwDesiredAccess;   /* type of access to service */
DWORD  fdwServiceType;   /* type of service */
DWORD  fdwStartType;   /* when to start service */
DWORD  fdwErrorControl;   /* severity if service fails to start */
LPCTSTR  lpszBinaryPathName;   /* address of name of binary file */
LPCTSTR  lpszLoadOrderGroup;   /* address of name of load ordering group */
LPDWORD  lpdwTagID;   /* address of variable to get tag identifier */
LPCTSTR  lpszDependencies;   /* address of array of dependency names */
LPCTSTR  lpszServiceStartName;   /* address of account name of service */
LPCTSTR  lpszPassword;   /* address of password for service account */

The CreateService function creates a service object and adds it to the specified service control manager database.

Parameters

schSCManager

Identifies the service control manager database. The OpenSCManager function returns this handle which must have SC_MANAGER_CREATE_SERVICE access.

lpszServiceName

Points to a null-terminated string that names the service to install. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. Forward-slash (/) and back-slash (\) are invalid service name characters.

lpszDisplayName

Points to a null-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the Service Control Manager. Display name comparisons are always case-insensitive.

fdwDesiredAccess

Specifies the access to the service. Before granting the requested access, the system checks the access token of the calling process against the discretionary access-control list of the security descriptor associated with the service object. Any or all of the following service object access types can be specified:

Access	Description
SERVICE_ALL_ACCESS
	Includes STANDARD_RIGHTS_REQUIRED in addition to all of the access types listed in this table.
SERVICE_CHANGE_CONFIG
	Enables calling of the ChangeServiceConfig function to change the service configuration.
SERVICE_ENUMERATE_DEPENDENTS
	Enables calling of the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_INTERROGATE
	Enables calling of the ControlService function to ask the service to report its status immediately.
SERVICE_PAUSE_CONTINUE
	Enables calling of the ControlService function to pause or continue the service.
SERVICE_QUERY_CONFIG
	Enables calling of the QueryServiceConfig function to query the service configuration.
SERVICE_QUERY_STATUS
	Enables calling of the QueryServiceStatus function to ask the service control manager about the status of the service.
SERVICE_START
	Enables calling of the StartService function to start the service.
SERVICE_STOP
	Enables calling of the ControlService function to stop the service.
SERVICE_USER_DEFINE_CONTROL
	Enables calling of the ControlService function to specify a user-defined control code.
The STANDARD_RIGHTS_REQUIRED constant (defined in the WINNT.H file) enables the following service object access types:

Standard rights	Description
DELETE	Enables calling of the DeleteService function to delete the service.
READ_CONTROL	Enables calling of the QueryServiceObjectSecurity function to query the security descriptor of the service object.
WRITE_DAC|WRITE_OWNER	Enables calling of the SetServiceObjectSecurity function to modify the security descriptor of the service object.
The fdwDesiredAccess parameter can specify any or all of the following generic access types:

Generic access	Service access
GENERIC_READ	Combines the following access: STANDARD_RIGHTS_READ, SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, and SERVICE_ENUMERATE_DEPENDENTS.
GENERIC_WRITE	Combines the following access: STANDARD_RIGHTS_WRITE and SERVICE_CHANGE_CONFIG.
GENERIC_EXECUTE	Combines the following access: STANDARD_RIGHTS_EXECUTE, SERVICE_START, SERVICE_STOP, SERVICE_PAUSE_CONTINUE, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL.
fdwServiceType

Specifies the type of service. One of the following values is specified.

Type	Meaning
SERVICE_WIN32_OWN_PROCESS	Specifies a service that runs in its own Win32 process.
SERVICE_WIN32_SHARE_PROCESS	Specifies a service that shares a Win32 process with other services.
SERVICE_KERNEL_DRIVER	Specifies a Windows NT device driver.
SERVICE_FILE_SYSTEM_DRIVER	Specifies a Windows NT file system driver.
fdwStartType

Specifies when to start the service. This member can be one of the following values.

Value	Meaning
SERVICE_BOOT_START	Specifies a device driver started by the operating system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_SYSTEM_START	Specifies a device driver started by the IoInitSystem function. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_AUTO_START	Specifies a device driver or Win32 service started by the service control manager automatically during system startup.
SERVICE_DEMAND_START	Specifies a device driver or Win32 service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED	Specifies a device driver or Win32 service that can no longer be started.
fdwErrorControl

Specifies the severity of the error if this service fails to start during startup, and determines the action taken by the startup program if failure occurs. One of the following values can be specified:

Value	Meaning
SERVICE_ERROR_IGNORE
	The startup (boot) program logs the error but continues the startup operation.
SERVICE_ERROR_NORMAL
	The startup program logs the error and puts up a message box pop-up but continues the startup operation.
SERVICE_ERROR_SEVERE
	The startup program logs the error. If the last-known-good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration.
SERVICE_ERROR_CRITICAL
	The startup program logs the error, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known-good configuration.
lpszBinaryPathName

Points to a null-terminated string that contains the fully qualified path to the service binary file.

lpszLoadOrderGroup

Points to a null-terminated string that names the load ordering group of which this service is a member. If the pointer is NULL or if it points to an empty string, the service does not belong to a group. The registry has a list of load ordering groups at HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ServiceGroupOrder. The startup program uses this list to load groups of services in a specified order with respect to the other groups in the list. You can place a service in a group so that another service can depend on the group.

The order in which a service starts is determined by these criteria:

1.	The order of groups in the registry's load-ordering group list. Services in groups in the load-ordering group list are started first, followed by services in groups not in the load-ordering group list and then services that do not belong to a group.

2.	The service's dependencies listed in the lpszDependencies parameter and the dependencies of other services dependent on the service.

lpdwTagID

Points to a 32-bit variable that receives a unique tag value for this service in the group specified in the lpszLoadOrderGroup parameter. If no tag is requested, this parameter can be NULL.

You can use a tag for ordering service startup in a load ordering group by specifying a tag order vector in the registry at HKEY_LOCAL_MACHINE\System\ CurrentControlSet\Control\GroupOrderList. Tags are only evaluated for SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER type services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.

lpszDependencies

Points to an array of null-separated names of services or load ordering groups that must start before this service. The array is double null-terminated. If the pointer is NULL or if it points to an empty string, the service has no dependencies. If a group name is specified, it must be prefixed by the SC_GROUP_IDENTIFIER character (defined in the WINSVC.H file) to differentiate it from a service name, because services and service groups share the same name space. Dependency on a service means that this service can only run if the service it depends on is running. Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.

lpszServiceStartName

Points to a null-terminated string. If the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, this name is the account name in the form of "DomainName\Username", which the service process will be logged on as when it runs. If the account belongs to the built-in domain, ".\Username" can be specified. If NULL is specified, the service will be logged on as the "LocalSystem" account, in which case, the lpszPassword parameter must be NULL.

If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this name is the Windows NT driver object name (that is, \FileSystem\Rdr or \Driver\Xns), which the input and output (I/O) system uses to load the device driver. If NULL is specified, the driver is run with a default object name created by the I/O system, based on the service name.

lpszPassword

Points to a null-terminated string that contains the password to the account name specified by the lpszServiceStartName parameter, if the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS. If the pointer is NULL or if it points to an empty string, the service has no password. If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this parameter is ignored.

Return Value

If the function succeeds, the return value is a handle to the service; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The handle to the specified service control manager database does not have SC_MANAGER_CREATE_SERVICE access.
ERROR_CIRCULAR_DEPENDENCY
	A circular service dependency was specified.
ERROR_DUP_NAME
	The display name already exists in the service control manager database either as a service name or as another display name.
ERROR_INVALID_HANDLE
	The handle to the specified service control manager database is invalid.
ERROR_INVALID_NAME
	The specified service name is invalid.
ERROR_INVALID_PARAMETER
	A parameter that was specified is invalid.
ERROR_INVALID_SERVICE_ACCOUNT
	The user account name specified in the lpszServiceStartName parameter does not exist.
ERROR_SERVICE_EXISTS
	The specified service already exist in this database.
Comments

The CreateService function creates a service object and installs it in the service control manager database by creating a service name key in the registry with the following form: HKEY_LOCAL_MACHINE\System\CurrentControlSet\ Services\<lpszServiceName> where lpszServiceName is the service name specified for this function. Information specified for this function is saved as values under this key. Setup programs and the service itself can create any subkey under this service name key for any service specific information.

If the appropriate access rights are enabled, the calling process can use the returned handle to identify the newly created service in the following functions:

ChangeServiceConfig
ControlService
DeleteService
EnumDependentServices
QueryServiceConfig
QueryServiceObjectSecurity
QueryServiceStatus
SetServiceObjectSecurity
StartService

The returned handle is only valid for the process that called CreateService. It can be closed by calling the CloseServiceHandle function.

See Also

»CloseServiceHandle«, »OpenSCManager«, »StartService«


  CreateSolidBrush

HBRUSH CreateSolidBrush(crColor)
COLORREF  crColor;   /* brush color value */

The CreateSolidBrush function creates a logical brush that has the specified solid color.

Parameters

crColor

Specifies the color of the brush.

Return Value

If the function succeeds, the return value identifies a logical brush; otherwise the return value is NULL.

Comments

A solid brush is a bitmap that Windows uses to paint the interiors of filled shapes.

After an application creates a brush by calling CreateSolidBrush, it can select that brush into any device context (DC) by calling the SelectObject function.

See Also

»CreateDIBPatternBrush«, »CreateDIBPatternBrushPt«, »CreateHatchBrush«, »CreatePatternBrush«, »DeleteObject«, »SelectObject«


  CreateTapePartition

DWORD CreateTapePartition(hDevice, dwPartitionMethod, dwCount, dwSize)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwPartitionMethod;   /* type of new partition */
DWORD  dwCount;   /* number of new partitions to create */
DWORD  dwSize;   /* size of new partition, in megabytes */

The CreateTapePartition function reformats a tape.

Parameters

hDevice

Identifies the device where the new partition is to be created. This handle is created by using the CreateFile function.

dwPartitionMethod

Specifies the type of partition to create. Refer to the hardware documentation to determine what type of partitions your device supports. This parameter can have one of the following values:

Value	Description
TAPE_FIXED_PARTITIONS	Partitions the tape based on the device's default definition of partitions. The dwCount and dwSize parameters are ignored.
TAPE_INITIATOR_PARTITIONS	Partitions the tape into the number and size of partitions specified by dwCount and dwSize, respectively, except for the last partition. The size of the last partition is the remainder of the tape.
TAPE_SELECT_PARTITIONS	Partitions the tape into the number of partitions specified by dwCount. The dwSize parameter is ignored. The size of the partitions is determined by the device's default partition size. Refer to your tape device's documentation for more specific information.
dwCount

Specifies the number of partitions to create. The GetTapeParameters function provides the maximum number of partitions a tape can support.

dwSize

Specifies the size, in megabytes, of each partition. This value is ignored if the dwPartitionMethod parameter is TAPE_SELECT_PARTITIONS.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

Creating partitions reformats the tape. All previous information recorded on the tape is destroyed.


  CreateThread

HANDLE CreateThread(lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread)
LPSECURITY_ATTRIBUTES  lpsa;   /* address of thread security attrs */
DWORD  cbStack;   /* initial thread stack size */
LPTHREAD_START_ROUTINE  lpStartAddr;   /* address of thread function */
LPVOID  lpvThreadParm;   /* argument for new thread */
DWORD  fdwCreate;   /* creation flags */
LPDWORD  lpIDThread;   /* address of returned thread ID */

The CreateThread function creates a thread to execute within the address space of the calling process.

Parameters

lpsa

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the thread. The SECURITY_ATTRIBUTES structure has the following format:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpsa is NULL, the thread is created with a default security descriptor, and the resulting handle is not inherited.

cbStack

Specifies the size in bytes of the stack for the new thread. If 0 is specified, the stack size defaults to the same size as that of the primary thread of the process. The stack is allocated automatically in the memory space of the process, and it is freed when the thread terminates. Note that the stack size grows if necessary.

lpStartAddr

Points to the application-supplied function to be executed by the thread and represents the starting address of the thread. The function accepts a single 32-bit argument and returns a 32-bit exit code.

lpvThreadParm

Specifies a single 32-bit parameter value passed to the thread.

fdwCreate

Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state, and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation.

lpIDThread

Points to a 32-bit variable that receives the thread identifier.

Return Value

If the function succeeds, the return value is a handle to the new thread. Otherwise, the return value is NULL. Use the GetLastError function to obtain extended error information.

Comments

The new thread handle is created with full access to the new thread. If a security descriptor is not provided, the handle can be used in any function that requires a thread object handle . When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread.

The thread execution begins at the function specified by the lpStartAddr parameter. If this function returns, the DWORD return value is used to terminate the thread in an implicit call to the ExitThread function. Use the GetExitCodeThread function to get the thread's return value.

The CreateThread function may succeed even if lpStartAddr points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a bad start address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to bad or missing DLLs.

The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread.

When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting on the object.

The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

1.	During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

2.	Only one thread in a process can be in a DLL initialization or detach routine at a time.

3.	The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

See Also

»CloseHandle«, »CreateProcess«, »CreateRemoteThread«, »ExitProcess«, »ExitThread«, »ResumeThread«


  CreateWindow

HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight,
hwndParent, hmenu, hinst, lpvParam)
LPCTSTR  lpszClassName;   /* address of registered class name */
LPCTSTR  lpszWindowName;   /* address of window name */
DWORD  dwStyle;   /* window style */
int  x;   /* horizontal position of window */
int  y;   /* vertical position of window */
int  nWidth;   /* window width */
int  nHeight;   /* window height */
HWND  hwndParent;   /* handle of parent or owner window */
HMENU  hmenu;   /* handle of menu, or child-window identifier */
HANDLE  hinst;   /* handle of application instance */
LPVOID  lpvParam;   /* address of window-creation data */

The CreateWindow function creates an overlapped, pop-up, or child window. It specifies the window class, window title, window style, and (optionally) the initial position and size of the window. The function also specifies the window's parent or owner, if any, and the window's menu.

Parameters

lpszClassName

Points to a null-terminated string, or is an integer atom. If this parameter is an atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value less than 0xC000, must be in the low-order word of lpszClassName; the high-order word must be zero.

If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with the RegisterClass function or any of the predefined control-class names. For a complete list, see the Comments section.

lpszWindowName

Points to a null-terminated string that specifies the window name.

dwStyle

Specifies the style of the window being created. This parameter can be a combination of the window styles and control styles listed in the Comments section.

x

Specifies the initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area.

If this parameter is set to CW_USEDEFAULT, Windows selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.

y

Specifies the initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box, y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area.

If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, Windows ignores the y parameter.

nWidth

Specifies the width, in device units, of the window. For overlapped windows, nWidth is either the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, Windows selects a default width and height for the window; the default width extends from the initial x-coordinate to the right edge of the screen, and the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, the nWidth and nHeight parameters are set to zero.

nHeight

Specifies the height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, Windows ignores nHeight.

hwndParent

Identifies the parent or owner window of the window being created. A valid window handle must be supplied when a child window or an owned window is created. A child window is confined to the client area of its parent window. An owned window is an overlapped window that is destroyed when its owner window is destroyed or hidden when its owner is minimized; it is always displayed on top of its owner window. Although this parameter must specify a valid handle if the dwStyle parameter includes the WS_CHILD style, it is optional if dwStyle includes the WS_POPUP style.

hmenu

Identifies a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window, hmenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hmenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.

hinst

Identifies the instance of the module to be associated with the window.

lpvParam

Points to a value passed to the window through the CREATESTRUCT structure referenced by the lParam parameter of the WM_CREATE message. If an application calls CreateWindow to create a multiple document interface (MDI) client window, lpvParam must point to a CLIENTCREATESTRUCT structure. The CREATESTRUCT structure has the following form:

typedef struct tagCREATESTRUCT { /* cs */

    LPVOID lpCreateParams;

    HANDLE hInstance;

    HMENU  hMenu;

    HWND   hwndParent;

    int    cy;

    int    cx;

    int    y;

    int    x;

    LONG   style;

    LPCSTR lpszName;

    LPCSTR lpszClass;

    DWORD  dwExStyle;

} CREATESTRUCT;

The CLIENTCREATESTRUCT structure has the following form:

typedef struct tagCLIENTCREATESTRUCT { /* ccs */

    HANDLE hWindowMenu;

    UINT   idFirstChild;

} CLIENTCREATESTRUCT;

For a full description of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the new window; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

Before returning, the CreateWindow function sends a WM_CREATE message to the window procedure.

For overlapped, pop-up, and child windows, the CreateWindow function sends WM_CREATE, WM_GETMINMAXINFO, and WM_NCCREATE messages to the window. The lParam parameter of the WM_CREATE message contains a pointer to a CREATESTRUCT structure. If the WS_VISIBLE style is specified, CreateWindow sends the window all the messages required to activate and show the window.

If the window style specifies a title bar, the window title pointed to by the lpszWindowName parameter is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use the lpszWindowName parameter to specify the text of the control.

The following predefined control classes can be specified in the lpszClassName parameter:

Class	Meaning
BUTTON	Designates a small rectangular child window that represents a button the user can turn on or off by clicking. Button controls can be used alone or in groups, and they can either be labeled or appear without text. Button controls typically change appearance when the user clicks them.
COMBOBOX	Designates a control consisting of a list box and a selection field similar to an edit control. When using this style, an application should either display the list box at all times or enable a drop-down list box.
	Depending on the style of the combo box, the user can or cannot edit the contents of the selection field. If the list box is visible, typing characters into the selection field highlights the first list box entry that matches the characters typed. Conversely, selecting an item in the list box displays the selected text in the selection field.
EDIT	Designates a rectangular child window into which the user can type text from the keyboard. The user selects the control and gives it the keyboard focus by clicking it or moving to it by pressing the TAB key. The user can type text when the edit control displays a flashing caret; can use the mouse to move the cursor, select characters to be replaced, or position the cursor for inserting characters; or can use the BACKSPACE key to delete characters.
	Edit controls use the variable-pitch system font and display characters from the ANSI character set. The WM_SETFONT message can also be sent to the edit control to change the default font.
	Edit controls expand tab characters into as many space characters as are required to move the caret to the next tab stop. Tab stops are assumed to be at every eighth character position.
LISTBOX	Designates a list of character strings. This control is used whenever an application must present a list of names, such as filenames, from which the user can choose. The user can select a string by clicking it. A selected string is highlighted, and a notification message is passed to the parent window. A vertical or horizontal scroll bar with a list box is used to scroll lists that are too long for the control window. The list box automatically hides or shows the scroll bar, as needed.
MDICLIENT	Designates an MDI client window. This window receives messages that control the MDI application's child windows. The recommended style bits are WS_CLIPCHILDREN and WS_CHILD. The WS_HSCROLL and WS_VSCROLL styles are used to create an MDI client window that allows the user to scroll MDI child windows into view.
SCROLLBAR	Designates a rectangle that contains a scroll box and has direction arrows at both ends. The scroll bar sends a notification message to its parent window whenever the user clicks the control. The parent window is responsible for updating the position of the scroll box, if necessary. Scroll bar controls have the same appearance and function as scroll bars used in ordinary windows. Unlike scroll bars, however, scroll bar controls can be positioned anywhere in a window and can be used whenever scrolling input is needed for a window.
	The scroll bar class also includes size box controls. A size box is a small rectangle the user can expand to change the size of the window.
STATIC	Designates a simple text field, box, or rectangle used to label, box, or separate other controls. Static controls take no input and provide no output.
The following window styles can be specified in the dwStyle parameter:

Style	Meaning
WS_BORDER	Creates a window that has a thin-line border.
WS_CAPTION	Creates a window that has a title bar (includes the WS_BORDER style).
WS_CHILD	Creates a child window. This style cannot be used with the WS_POPUP style.
WS_CHILDWINDOW	Same as the WS_CHILD style.
WS_CLIPCHILDREN	Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.
WS_CLIPSIBLINGS	Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window. This style is used with the WS_CHILD style only.
WS_DISABLED	Creates a window that is initially disabled. A disabled window cannot receive input from the user.
WS_DLGFRAME	Creates a window that has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar.
WS_GROUP	Specifies the first control of a group of controls. The user can change the keyboard focus from one control in the group to the next by using the direction keys. All controls defined with the WS_GROUP style after the first control belong to the same group. The next control with the WS_GROUP style ends the group and starts the next group.
WS_HSCROLL	Creates a window that has a horizontal scroll bar.
WS_MAXIMIZE	Creates a window that is initially maximized.
WS_MAXIMIZEBOX	Creates a window that has a Maximize button.
WS_MINIMIZE	Creates a window that is initially minimized.
WS_MINIMIZEBOX	Creates a window that has a Minimize button.
WS_OVERLAPPED	Creates an overlapped window. An overlapped window has a title bar and a border.
WS_OVERLAPPEDWINDOW	Creates an overlapped window with the WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles.
WS_POPUP	Creates a pop-up window. This style cannot be used with the WS_CHILD style.
WS_POPUPWINDOW	Creates a pop-up window with WS_BORDER, WS_POPUP, and WS_SYSMENU styles. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the System menu (also known as Control menu) visible.
WS_SYSMENU	Creates a window that has a System-menu box in its title bar. The WS_CAPTION style must also be specified.
WS_TABSTOP	Specifies a control that can receive the keyboard focus when the user presses the TAB key. Pressing the TAB key changes the keyboard focus to the next control with the WS_TABSTOP style.
WS_THICKFRAME	Creates a window that has a sizing border.
WS_VISIBLE	Creates a window that is initially visible.
WS_VSCROLL	Creates a window that has a vertical scroll bar.
The following button styles (in the BUTTON class) can be specified in the dwStyle parameter:

Style	Meaning
BS_3STATE	Creates a button that is the same as a check box, except that the box can be grayed as well as checked. Use the grayed state to show that the state of the check box is not determined.
BS_AUTO3STATE	Creates a button that is the same as a three-state check box, except that the box changes its state when the user selects it. The state cycles through checked, grayed, and normal.
BS_AUTOCHECKBOX	Creates a button that is the same as a check box, except that an X appears in the check box when the user selects the box; the X disappears the next time the user selects the box.
BS_AUTORADIOBUTTON	Creates a button that is the same as a radio button, except that when the user selects it, the button automatically highlights itself and removes the selection from any other buttons in the same group.
BS_CHECKBOX	Creates a small empty square, with text displayed to its right, unless this style is combined with the BS_LEFTTEXT style.
BS_DEFPUSHBUTTON	Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style is useful for enabling the user to quickly select the most likely (default) option.
BS_GROUPBOX	Creates a rectangle in which other controls can be grouped. Any text associated with this style is displayed in the rectangle's upper left corner.
BS_LEFTTEXT	Places text on the left side of the radio button or check box when combined with a radio button or check box style.
BS_OWNERDRAW	Creates an owner-drawn button. The owner window receives a WM_MEASUREITEM message when the button is created and a WM_DRAWITEM message when a visual aspect of the button has changed. Do not combine the BS_OWNERDRAW style with any other button styles.
BS_PUSHBOX	Unsupported. Applications should use BS_PUSHBUTTON instead.
BS_PUSHBUTTON	Creates a push button that posts a WM_COMMAND message to the owner window when the user selects the button.
BS_RADIOBUTTON	Creates a small circle that has text displayed to its right, unless this style is combined with the BS_LEFTTEXT style. Use radio buttons for groups of related but mutually exclusive choices.
BS_USERBUTTON	Obsolete. Applications should use BS_OWNERDRAW instead.
The following combo box styles (in the COMBOBOX class) can be specified in the dwStyle parameter:

Style	Meaning
CBS_AUTOHSCROLL	Automatically scrolls the text in an edit control to the right when the user types a character at the end of the line. If this style is not set, only text that fits within the rectangular boundary is allowed.
CBS_DISABLENOSCROLL	Shows a disabled vertical scroll bar in the list box when the box does not contain enough items to scroll. Without this style, the scroll bar is hidden when the list box does not contain enough items.
CBS_DROPDOWN	Similar to CBS_SIMPLE, except that the list box is not displayed unless the user selects an icon next to the edit control.
CBS_DROPDOWNLIST	Similar to CBS_DROPDOWN, except that the edit control is replaced by a static text item that displays the current selection in the list box.
CBS_HASSTRINGS	Specifies that an owner-drawn combo box contains items consisting of strings. The combo box maintains the memory and address for the strings so the application can use the CB_GETLBTEXT message to retrieve the text for a particular item.
CBS_NOINTEGRALHEIGHT	Specifies that the size of the combo box is exactly the size specified by the application when it created the combo box. Normally, Windows sizes a combo box so that it does not display partial items.
CBS_OEMCONVERT	Converts text entered in the combo box edit control from the Windows character set to the OEM character set and then back to the Windows set. This ensures proper character conversion when the application calls the AnsiToOem function to convert a Windows string in the combo box to OEM characters. This style is most useful for combo boxes that contain filenames and applies only to combo boxes created with the CBS_SIMPLE or CBS_DROPDOWN style.
CBS_OWNERDRAWFIXED	Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are all the same height. The owner window receives a WM_MEASUREITEM message when the combo box is created and a WM_DRAWITEM message when a visual aspect of the combo box has changed.
CBS_OWNERDRAWVARIABLE	Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are variable in height. The owner window receives a WM_MEASUREITEM message for each item in the combo box when you create the combo box and a WM_DRAWITEM message when a visual aspect of the combo box has changed.
CBS_SIMPLE	Displays the list box at all times. The current selection in the list box is displayed in the edit control.
CBS_SORT	Automatically sorts strings entered into the list box.
The following edit control styles (in the EDIT class) can be specified in the dwStyle parameter:

Style	Meaning
ES_AUTOHSCROLL	Automatically scrolls text to the right by 10 characters when the user types a character at the end of the line. When the user presses the ENTER key, the control scrolls all text back to position zero.
ES_AUTOVSCROLL	Automatically scrolls text up one page when the user presses the ENTER key on the last line.
ES_CENTER	Centers text in a multiline edit control.
ES_LEFT	Left-aligns text.
ES_LOWERCASE	Converts all characters to lowercase as they are typed into the edit control.
ES_MULTILINE	Designates a multiline edit control. The default is single-line edit control.
	When the multiline edit control is in a dialog box, the default response to pressing the ENTER key is to activate the default button. To use the ENTER key as a carriage return, use the ES_WANTRETURN style.
	When the multiline edit control is not in a dialog box and the ES_AUTOVSCROLL style is specified, the edit control shows as many lines as possible and scrolls vertically when the user presses the ENTER key. If you do not specify ES_AUTOVSCROLL, the edit control shows as many lines as possible and beeps if the user presses the ENTER key when no more lines can be displayed.
	If you specify the ES_AUTOHSCROLL style, the multiline edit control automatically scrolls horizontally when the caret goes past the right edge of the control. To start a new line, the user must press the ENTER key. If you do not specify ES_AUTOHSCROLL, the control automatically wraps words to the beginning of the next line when necessary. A new line is also started if the user presses the ENTER key. The window size determines the position of the word wrap. If the window size changes, the word wrapping position changes and the text is redisplayed.
	Multiline edit controls can have scroll bars. An edit control with scroll bars processes its own scroll bar messages. Edit controls without scroll bars scroll as described in the previous two paragraphs and process any scroll messages sent by the parent window.
ES_NOHIDESEL	Negates the default behavior for an edit control. The default behavior hides the selection when the control loses the input focus and inverts the selection when the control receives the input focus. If you specify ES_NOHIDESEL, the selected text is inverted, even if the control does not have the focus.
ES_OEMCONVERT	Converts text entered in the edit control from the Windows character set to the OEM character set and then back to the Windows set. This ensures proper character conversion when the application calls the CharToOem function to convert a Windows string in the edit control to OEM characters. This style is most useful for edit controls that contain filenames.
ES_PASSWORD	Displays an asterisk (*) for each character typed into the edit control. You can use the EM_SETPASSWORDCHAR message to change the character that is displayed.
ES_READONLY	Prevents the user from typing or editing text in the edit control.
ES_RIGHT	Right-aligns text in a multiline edit control.
ES_UPPERCASE	Converts all characters to uppercase as they are typed into the edit control.
ES_WANTRETURN	Specifies that a carriage return be inserted when the user presses the ENTER key while entering text into a multiline edit control in a dialog box. If you do not specify this style, pressing the ENTER key has the same effect as pressing the dialog box's default push button. This style has no effect on a single-line edit control.
The following list box control styles (in the LISTBOX class) can be specified in the dwStyle parameter:

Style	Meaning
LBS_DISABLENOSCROLL	Shows a disabled vertical scroll bar for the list box when the box does not contain enough items to scroll. If you do not specify this style, the scroll bar is hidden when the list box does not contain enough items.
LBS_EXTENDEDSEL	Allows multiple items to be selected by using the SHIFT key and the mouse or special key combinations.
LBS_HASSTRINGS	Specifies that a list box contains items consisting of strings. The list box maintains the memory and addresses for the strings so the application can use the LB_GETTEXT message to retrieve the text for a particular item. By default, all list boxes except owner-drawn list boxes have this style. You can create an owner-drawn list box either with or without this style.
LBS_MULTICOLUMN	Specifies a multicolumn list box that is scrolled horizontally. The LB_SETCOLUMNWIDTH message sets the width of the columns.
LBS_MULTIPLESEL	Turns string selection on or off each time the user clicks or double-clicks a string in the list box. The user can select any number of strings.
LBS_NODATA	Specifies a no-data list box. Specify this style when the count of items in the list box will exceed one thousand. A no-data list box must also have the LBS_OWNERDRAWFIXED style, but must not have the LBS_SORT or LBS_HASSTRINGS style.
	A no-data list box resembles an owner-drawn list box except that it contains no string or bitmap data for an item. Commands to add, insert, or delete an item always ignore any given item data; requests to find a string within the list box always fail. Windows sends the WM_DRAWITEM message to the owner window when an item must be drawn. The itemID member of the DRAWITEMSTRUCT structure passed with the WM_DRAWITEM message specifies the line number of the item to be drawn. A no-data list box does not send a WM_DELETEITEM message.
LBS_NOINTEGRALHEIGHT	Specifies that the size of the list box is exactly the size specified by the application when it created the list box. Normally, Windows sizes a list box so that the list box does not display partial items.
LBS_NOREDRAW	Specifies that the list box's appearance is not updated when changes are made. You can change this style at any time by sending a WM_SETREDRAW message.
LBS_NOTIFY	Notifies the parent window with an input message whenever the user clicks or double-clicks a string in the list box.
LBS_OWNERDRAWFIXED	Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are the same height. The owner window receives a WM_MEASUREITEM message when the list box is created and a WM_DRAWITEM message when a visual aspect of the list box has changed.
LBS_OWNERDRAWVARIABLE	Specifies that the owner of the list box is responsible for drawing its contents and that the items in the list box are variable in height. The owner window receives a WM_MEASUREITEM message for each item in the combo box when the combo box is created and a WM_DRAWITEM message when a visual aspect of the combo box has changed.
LBS_SORT	Sorts strings in the list box alphabetically.
LBS_STANDARD	Sorts strings in the list box alphabetically. The parent window receives an input message whenever the user clicks or double-clicks a string. The list box has borders on all sides.
LBS_USETABSTOPS	Enables a list box to recognize and expand tab characters when drawing its strings. The default tab positions are 32 dialog box units. A dialog box unit is a horizontal or vertical distance. One horizontal dialog box unit is equal to one-fourth of the current dialog box base-width unit. Windows calculates these units based on the height and width of the current system font. The GetDialogBaseUnits function returns the current dialog box base units in pixels.
LBS_WANTKEYBOARDINPUT	Specifies that the owner of the list box receives WM_VKEYTOITEM messages whenever the user presses a key and the list box has the input focus. This enables an application to perform special processing on the keyboard input.
The following scroll bar styles (in the SCROLLBAR class) can be specified in the dwStyle parameter:

Style	Meaning
SBS_BOTTOMALIGN
	Aligns the bottom edge of the scroll bar with the bottom edge of the rectangle defined by the CreateWindow parameters x, y, nWidth, and nHeight. The scroll bar has the default height for system scroll bars. Use this style with the SBS_HORZ style.
SBS_HORZ
	Designates a horizontal scroll bar. If neither the SBS_BOTTOMALIGN nor SBS_TOPALIGN style is specified, the scroll bar has the height, width, and position specified by the CreateWindow parameters.
SBS_LEFTALIGN
	Aligns the left edge of the scroll bar with the left edge of the rectangle defined by the CreateWindow parameters. The scroll bar has the default width for system scroll bars. Use this style with the SBS_VERT style.
SBS_RIGHTALIGN
	Aligns the right edge of the scroll bar with the right edge of the rectangle defined by the CreateWindow parameters. The scroll bar has the default width for system scroll bars. Use this style with the SBS_VERT style.
SBS_SIZEBOX
	Designates a size box. If you specify neither the SBS_SIZEBOXBOTTOMRIGHTALIGN nor the SBS_SIZEBOXTOPLEFTALIGN style, the size box has the height, width, and position specified by the CreateWindow parameters.
SBS_SIZEBOXBOTTOMRIGHTALIGN
	Aligns the lower right corner of the size box with the lower right corner of the rectangle specified by the CreateWindow parameters. The size box has the default size for system size boxes. Use this style with the SBS_SIZEBOX style.
SBS_SIZEBOXTOPLEFTALIGN
	Aligns the upper left corner of the size box with the upper left corner of the rectangle specified by the CreateWindow parameters. The size box has the default size for system size boxes. Use this style with the SBS_SIZEBOX style.
SBS_TOPALIGN
	Aligns the top edge of the scroll bar with the top edge of the rectangle defined by the CreateWindow parameters. The scroll bar has the default height for system scroll bars. Use this style with the SBS_HORZ style.
SBS_VERT
	Designates a vertical scroll bar. If you specify neither the SBS_RIGHTALIGN nor the SBS_LEFTALIGN style, the scroll bar has the height, width, and position specified by the CreateWindow parameters.
The following static control styles (in the STATIC class) can be specified in the dwStyle parameter. A static control can have only one of these styles:

Style	Description
SS_BLACKFRAME	Specifies a box with a frame drawn in the same color as the window frames. This color is black in the default Windows color scheme.
SS_BLACKRECT	Specifies a rectangle filled with the current window frame color. This color is black in the default Windows color scheme.
SS_CENTER	Specifies a simple rectangle and centers the given text in the rectangle. The text is formatted before it is displayed. Words that extend past the end of a line are automatically wrapped to the beginning of the next centered line.
SS_GRAYFRAME	Specifies a box with a frame drawn with the same color as the screen background (desktop). This color is gray in the default Windows color scheme.
SS_GRAYRECT	Specifies a rectangle filled with the current screen background color. This color is gray in the default Windows color scheme.
SS_ICON	Specifies an icon displayed in the dialog box. The given text is the name of an icon (not a filename) defined elsewhere in the resource file. The style ignores the nWidth and nHeight parameters; the icon automatically sizes itself.
SS_LEFT	Specifies a simple rectangle and left-aligns the given text in the rectangle. The text is formatted before it is displayed. Words that extend past the end of a line are automatically wrapped to the beginning of the next left-aligned line.
SS_LEFTNOWORDWRAP	Specifies a simple rectangle and left-aligns the given text in the rectangle. Tabs are expanded but words are not wrapped. Text that extends past the end of a line is clipped.
SS_NOPREFIX	Prevents interpretation of any ampersand (&) characters in the control's text as accelerator prefix characters. These are displayed with the ampersand removed and the next character in the string underlined. This static control style may be included with any of the defined static controls.
	An application can combine SS_NOPREFIX with other styles by using the bitwise OR (|) operator. This can be useful when filenames or other strings that may contain an ampersand (&) must be displayed in a static control in a dialog box.
SS_RIGHT	Specifies a simple rectangle and right-aligns the given text in the rectangle. The text is formatted before it is displayed. Words that extend past the end of a line are automatically wrapped to the beginning of the next right-aligned line.
SS_SIMPLE	Specifies a simple rectangle and displays a single line of left-aligned text in the rectangle. The text line cannot be shortened or altered in any way. The control's parent window or dialog box must not process the WM_CTLCOLOR message.
SS_WHITEFRAME	Specifies a box with a frame drawn with the same color as the window backgrounds. This color is white in the default Windows color scheme.
SS_WHITERECT	Specifies a rectangle filled with the current window background color. This color is white in the default Windows color scheme.
The following dialog box styles can be specified in the dwStyle parameter:

Style	Meaning
DS_ABSALIGN	Indicates that the coordinates of the dialog box are screen coordinates; otherwise, Windows assumes they are client coordinates.
DS_LOCALEDIT	Applies to 16-bit applications only. This style directs edit controls in the dialog box to allocate memory from the application's data segment. Otherwise, edit controls allocate storage from a global memory object.
DS_MODALFRAME	Creates a dialog box with a modal dialog-box frame that can be combined with a title bar and System menu by specifying the WS_CAPTION and WS_SYSMENU styles.
DS_NOIDLEMSG	Suppresses WM_ENTERIDLE messages that Windows would otherwise send to the owner of the dialog box while the dialog box is displayed.
DS_SETFONT	Indicates that the dialog box template (the DLGTEMPLATE structure) contains two additional members specifying a font name and point size. The corresponding font is used to display text within the dialog box client area and within the dialog box controls. Windows passes the handle of the font to the dialog box and to each control by sending them the WM_SETFONT message.
DS_SETFOREGROUND	Applies to Windows NT only. This style brings the dialog box to the foreground. Internally, Windows calls the SetForegroundWindow function for the dialog box.
DS_SYSMODAL	Creates a system-modal dialog box.
See Also

»CreateDialog«, »CreateWindowEx«, »DialogBox«, »MessageBox«


  CreateWindowEx

HWND CreateWindowEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, x, y,
nWidth, nHeight, hwndParent, hmenu, hinst, lpvParam)
DWORD  dwExStyle;   /* extended window style */
LPCTSTR  lpszClassName;   /* address of registered class name */
LPCTSTR  lpszWindowName;  /* address of window name */
DWORD  dwStyle;   /* window style */
int  x;   /* horizontal position of window */
int  y;   /* vertical position of window */
int  nWidth;   /* window width */
int  nHeight;   /* window height */
HWND  hwndParent;   /* handle of parent or owner window */
HMENU  hmenu;   /* handle of menu, or child-window identifier */
HANDLE  hinst;   /* handle of application instance */
LPVOID  lpvParam;   /* address of window-creation data */

The CreateWindowEx function creates an overlapped, pop-up, or child window with an extended style; otherwise, this function is identical to the CreateWindow function. For more information about creating a window and for full descriptions of the other parameters of CreateWindowEx, see the description of the »CreateWindow« function.

Parameters

dwExStyle

Specifies the extended style of the window. This parameter can be one of the following values:

Style	Meaning
WS_EX_ACCEPTFILES	Specifies that a window created with this style accepts drag-drop files.
WS_EX_DLGMODALFRAME	Creates a window that has a double border; the window can, optionally, be created with a title bar by specifying the WS_CAPTION style in the dwStyle parameter.
WS_EX_NOPARENTNOTIFY	Specifies that a child window created this style does not send the WM_PARENTNOTIFY message to its parent window when it is created or destroyed.
WS_EX_TOPMOST	Specifies that a window created with this style should be placed above all non-topmost windows and should stay above them, even when the window is deactivated. To add or remove this style, use the SetWindowPos function.
lpszClassName

Points to a null-terminated string, or is an integer atom. If lpszClassName is an atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value less than 0xC000, must be in the low-order word of lpszClassName; the high-order word must be zero.

If lpszClassName is a string, it specifies the window-class name. The class name can be any name registered with the RegisterClass function or any of the predefined control-class names.

lpszWindowName

Points to a null-terminated string that specifies the window name.

dwStyle

Specifies the style of the window being created. For a list of the window styles that can be specified in dwStyle, see the description of the »CreateWindow« function.

x

Specifies the initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area.

If x is set to CW_USEDEFAULT, Windows selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.

y

Specifies the initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box, y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area.

If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, Windows ignores the y parameter.

nWidth

Specifies the width, in device units, of the window. For overlapped windows, nWidth is either the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, Windows selects a default width and height for the window; the default width extends from the initial x-coordinates to the right edge of the screen, and the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, the nWidth and nHeight parameter are set to zero.

nHeight

Specifies the height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, Windows ignores nHeight.

hwndParent

Identifies the parent or owner window of the window being created. A valid window handle must be supplied when a child window or an owned window is created. A child window is confined to the client area of its parent window. An owned window is an overlapped window that is destroyed when its owner window is destroyed or hidden when its owner is minimized; it is always displayed on top of its owner window. Although this parameter must specify a valid handle if the dwStyle parameter includes the WS_CHILD style, it is optional if dwStyle includes the WS_POPUP style.

hmenu

Identifies a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hmenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hmenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.

hinst

Identifies the instance of the module to be associated with the window.

lpvParam

Points to a value passed to the window through the CREATESTRUCT structure referenced by the lParam parameter of the WM_CREATE message. If an application calls CreateWindow to create a multiple document interface (MDI) client window, lpvParam must point to a CLIENTCREATESTRUCT structure. The CREATESTRUCT structure has the following form:

typedef struct tagCREATESTRUCT { /* cs */

    LPVOID lpCreateParams;

    HANDLE hInstance;

    HMENU  hMenu;

    HWND   hwndParent;

    int    cy;

    int    cx;

    int    y;

    int    x;

    LONG   style;

    LPCSTR lpszName;

    LPCSTR lpszClass;

    DWORD  dwExStyle;

} CREATESTRUCT;

The CLIENTCREATESTRUCT structure has the following form:

typedef struct tagCLIENTCREATESTRUCT { /* ccs */

    HANDLE hWindowMenu;

    UINT   idFirstChild;

} CLIENTCREATESTRUCT;

For a full description of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the new window; otherwise, it is NULL.

Comments

The CreateWindowEx function sends WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window being created.

For information about the window control classes, window styles, and control styles used with this function, see the description of the »CreateWindow« function.

See Also

»CreateWindow«, »SetWindowPos«


  DdeAbandonTransaction

BOOL DdeAbandonTransaction(idInst, hconv, idTransaction)
DWORD  idInst;   /* instance identifier */
HCONV  hconv;   /* handle of conversation */
DWORD  idTransaction;   /* transaction identifier */

The DdeAbandonTransaction function abandons the specified asynchronous transaction and releases all resources associated with the transaction.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hconv

Identifies the conversation in which the transaction was initiated. If this parameter is 0L, all transactions are abandoned (the idTransaction parameter is ignored).

idTransaction

Identifies the transaction to abandon. If this parameter is 0L, all active transactions in the specified conversation are abandoned.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_UNFOUND_QUEUE_ID

Comments

Only a dynamic data exchange (DDE) client application should call DdeAbandonTransaction. If the server application responds to the transaction after the client has called DdeAbandonTransaction, the system discards the transaction results. This function has no effect on synchronous transactions.

See Also

»DdeClientTransaction«, »DdeGetLastError«, »DdeInitialize«, »DdeQueryConvInfo«


  DdeAccessData

LPBYTE DdeAccessData(hdata, lpcbData)
HDDEDATA  hdata;   /* handle of DDE object */
LPDWORD  lpcbData;   /* pointer to variable that receives data length */

The DdeAccessData function provides access to the data in the given dynamic data exchange (DDE) object. An application must call the DdeUnaccessData function when it has finished accessing the data in the object.

Parameters

hdata

Identifies the DDE object to access.

lpcbData

Points to a variable that receives the size, in bytes, of the DDE object identified by the hdata parameter. If this parameter is NULL, no size information is returned.

Return Value

If the function succeeds, the return value is a pointer to the first byte of data in the DDE object; otherwise, the return value is NULL.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Comments

If the hdata parameter has not been passed to a Dynamic Data Exchange Management Library (DDEML) function, an application can use the pointer returned by DdeAccessData for read-write access to the DDE object. If hdata has already been passed to a DDEML function, the pointer should be used only for read access to the memory object.

See Also

»DdeAddData«, »DdeCreateDataHandle«, »DdeFreeDataHandle«, »DdeGetLastError«, »DdeUnaccessData«


  DdeAddData

HDDEDATA DdeAddData(hdata, lpbSrcBuf, cbAddData, offObj)
HDDEDATA  hdata;   /* handle of DDE data object */
LPBYTE  lpbSrcBuf;   /* address of source buffer */
DWORD  cbAddData;   /* length of data */
DWORD  offObj;   /* offset within DDE data object */

The DdeAddData function adds data to the given dynamic data exchange (DDE) object. An application can add data starting at any offset from the beginning of the object. If new data overlaps data already in the object, the new data overwrites the old data in the bytes where the overlap occurs. The contents of locations in the object that have not been written to are undefined.

Parameters

hdata

Identifies the DDE object that receives additional data.

lpbSrcBuf

Points to a buffer containing the data to add to the DDE object.

cbAddData

Specifies the length, in bytes, of the data to be added to the DDE object.

offObj

Specifies an offset, in bytes, from the beginning of the DDE object. The additional data is copied to the object beginning at this offset.

Return Value

If the function succeeds, the return value is a new handle of the DDE object. Use the new handle in all references to the object. If an error occurs, the return value is zero.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_MEMORY_ERROR
DMLERR_NO_ERROR

Comments

After a data handle has been used as a parameter in another Dynamic Data Exchange Management Library (DDEML) function or has been returned by a DDE callback function, the handle may be used only for read access to the DDE object identified by the handle.

If the amount of memory originally allocated is less than is needed to hold the added data, the DdeAddData function reallocates a global memory object of the appropriate size.

See Also

»DdeAccessData«, »DdeCreateDataHandle«, »DdeGetLastError«, »DdeUnaccessData«


  DdeCallback

HDDEDATA CALLBACK DdeCallback(uType, uFmt, hconv, hsz1, hsz2, hdata,
dwData1, dwData2)
UINT  uType;   /* transaction type */
UINT  uFmt;   /* clipboard data format */
HCONV  hconv;   /* handle of the conversation */
HSZ  hsz1;   /* handle of a string */
HSZ  hsz2;   /* handle of a string */
HDDEDATA  hdata;   /* handle of a global memory object */
DWORD  dwData1;   /* transaction-specific data */
DWORD  dwData2;   /* transaction-specific data */

The DdeCallback function is an application-defined callback function that processes dynamic data exchange (DDE) transactions sent to the function in response to Dynamic Data Exchange Management Library (DDEML) calls by other applications.

Parameters

uType

Specifies the type of the current transaction. This parameter consists of a combination of transaction-class flags and transaction-type flags. The following table describes each of the transaction classes and provides a list of the transaction types in each class. For information about a specific transaction type, see the individual description of that type.

Value	Meaning
XCLASS_BOOL	A DDE callback function should return TRUE or FALSE when it finishes processing a transaction that belongs to this class. The XCLASS_BOOL transaction types consist of the following:
	XTYP_ADVSTART XTYP_CONNECT
XCLASS_DATA	A DDE callback function should return a DDE handle, CBR_BLOCK, or NULL when it finishes processing a transaction that belongs to this class. The XCLASS_DATA transaction types consist of the following:
	XTYP_ADVREQ XTYP_REQUEST XTYP_WILDCONNECT
XCLASS_FLAGS	A DDE callback function should return DDE_FACK, DDE_FBUSY, or DDE_FNOTPROCESSED when it finishes processing a transaction that belongs to this class. The XCLASS_FLAGS transaction types consist of the following:
	XTYP_ADVDATA XTYP_EXECUTE XTYP_POKE
XCLASS_NOTIFICATION	The transaction types that belong to this class are for notification purposes only. The return value from the callback function is ignored. The XCLASS_NOTIFICATION transaction types consist of the following:
	XTYP_ADVSTOP XTYP_CONNECT_CONFIRM XTYP_DISCONNECT XTYP_ERROR XTYP_MONITOR XTYP_REGISTER XTYP_XACT_COMPLETE XTYP_UNREGISTER
uFmt

Specifies the format in which data is sent or received.

hconv

Identifies the conversation associated with the current transaction.

hsz1

Identifies a string. The meaning of this parameter depends on the type of the current transaction. See the description of the transaction type for the meaning of this parameter.

hsz2

Identifies a string. The meaning of this parameter depends on the type of the current transaction. See the description of the transaction type for the meaning of this parameter.

hdata

Identifies DDE data. The meaning of this parameter depends on the type of the current transaction. See the description of the transaction type for the meaning of this parameter.

dwData1

Specifies transaction-specific data. See the description of the transaction type for the meaning of this parameter.

dwData2

Specifies transaction-specific data. See the description of the transaction type for the meaning of this parameter.

Return Value

The return value depends on the transaction class. See descriptions of the individual transaction types for the return values.

Comments

The callback function is called asynchronously for transactions that do not involve the creation or termination of conversations. An application that does not frequently accept incoming messages will have reduced DDE performance because the DDEML uses messages to initiate transactions.

An application must register the callback function by specifying a pointer to the function in a call to the DdeInitialize function.

DdeCallback is a placeholder for the application-defined or library-defined function name.

See Also

»DdeEnableCallback«, »DdeInitialize«


  DdeClientTransaction

HDDEDATA DdeClientTransaction(lpbData, cbData, hconv, hszItem, uFmt, uType,
uTimeout, lpdwResult)
LPBYTE  lpbData;   /* address of data to pass to server */
DWORD  cbData;   /* length of data */
HCONV  hconv;   /* handle of conversation */
HSZ  hszItem;   /* handle of item-name string */
UINT  uFmt;   /* clipboard data format */
UINT  uType;   /* transaction type */
DWORD  uTimeout;   /* time-out duration */
LPDWORD  lpdwResult;   /* points to transaction result */

The DdeClientTransaction function begins a data transaction between a client and a server. Only a dynamic data exchange (DDE) client application can call this function, and only after establishing a conversation with the server.

Parameters

lpbData

Points to the beginning of the data the client must pass to the server.

Optionally, an application can specify the data handle (HDDEDATA) to pass to the server, in which case the cbData parameter should be set to 0xFFFFFFFF. This parameter is required only if the uType parameter is XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be NULL.

For this optional usage of the parameter, XTYP_POKE transactions where lpbData is a data handle, the handle must have been created using the DdeCreateDataHandle function, using the same data format specified in the uFmt parameter.

cbData

Specifies the length, in bytes, of the data pointed to by the lpbData parameter. A value of 0xFFFFFFFF indicates that lpbData is a data handle that identifies the data being sent.

hconv

Identifies the conversation in which the transaction is to take place.

hszItem

Identifies the data item for which data is being exchanged during the transaction. This handle must have been created by a previous call to the DdeCreateStringHandle function. This parameter is ignored (and should be set to 0L) if the uType parameter is XTYP_EXECUTE.

uFmt

Specifies the standard clipboard format in which the data item is being submitted or requested.

If the transaction specified by the uType parameter does not pass data or is XTYP_EXECUTE, this parameter should be set to zero.

If the transaction specified by the uType parameter references non-execute DDE data (XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_REQUEST), the uFmt value must be either a valid predefined (CF_) DDE format or a valid registered clipboard format.

uType

Specifies the transaction type. This parameter can be one of the following values:

Value	Meaning
XTYP_ADVSTART	Begins an advise loop. Any number of distinct advise loops can exist within a conversation. An application can alter the advise loop type by combining the XTYP_ADVSTART transaction type with one or more of the following flags:
Value	Meaning
XTYPF_NODATA	Instructs the server to notify the client of any data changes without actually sending the data. This flag gives the client the option of ignoring the notification or requesting the changed data from the server.
XTYPF_ACKREQ	Instructs the server to wait until the client acknowledges that it received the previous data item before sending the next data item. This flag prevents a fast server from sending data faster than the client can process it.
XTYP_ADVSTOP	Ends an advise loop.
XTYP_EXECUTE	Begins an execute transaction.
XTYP_POKE	Begins a poke transaction.
XTYP_REQUEST	Begins a request transaction.
uTimeout

Specifies the maximum length of time, in milliseconds, the client will wait for a response from the server application in a synchronous transaction. This parameter should be set to TIMEOUT_ASYNC for asynchronous transactions.

lpdwResult

Points to a variable that receives the result of the transaction. An application that does not check the result can set this value to NULL. For synchronous transactions, the low-order word of this variable contains any applicable DDE_ flags resulting from the transaction. This provides support for applications dependent on DDE_APPSTATUS bits. (It is recommended that applications no longer use these bits because they may not be supported in future versions of the Dynamic Data Exchange Management Library (DDEML). For asynchronous transactions, this variable is filled with a unique transaction identifier for use with the DdeAbandonTransaction function and the XTYP_XACT_COMPLETE transaction.

Return Value

If the function succeeds, the return value is a data handle that identifies the data for successful synchronous transactions in which the client expects data from the server. The return value is non-zero for successful asynchronous transactions and for synchronous transactions in which the client does not expect data. The return value is zero for all unsuccessful transactions.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_ADVACKTIMEOUT
DMLERR_BUSY
DMLERR_DATAACKTIMEOUT
DMLERR_DLL_NOT_INITIALIZED
DMLERR_EXECACKTIMEOUT
DMLERR_INVALIDPARAMETER
DMLERR_MEMORY_ERROR
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR
DMLERR_NOTPROCESSED
DMLERR_POKEACKTIMEOUT
DMLERR_POSTMSG_FAILED
DMLERR_REENTRANCY
DMLERR_SERVER_DIED
DMLERR_UNADVACKTIMEOUT

Comments

When the application has finished using the data handle returned by the DdeClientTransaction function, the application should free the handle by calling the DdeFreeDataHandle function.

Transactions can be synchronous or asynchronous. During a synchronous transaction, DdeClientTransaction does not return until the transaction either completes successfully or fails. Synchronous transactions cause the client to enter a modal loop while waiting for various asynchronous events. Because of this, the client application can still respond to user input while waiting on a synchronous transaction but cannot begin a second synchronous transaction because of the activity associated with the first. DdeClientTransaction fails if any instance of the same task has a synchronous transaction already in progress.

During an asynchronous transaction, DdeClientTransaction returns after the transaction has begun, passing a transaction identifier for reference. When the server's DDE callback function finishes processing an asynchronous transaction, the system sends an XTYP_XACT_COMPLETE transaction to the client. This transaction provides the client with the results of the asynchronous transaction that it initiated by calling DdeClientTransaction. A client application can choose to abandon an asynchronous transaction by calling the DdeAbandonTransaction function.

See Also

»DdeAbandonTransaction«, »DdeAccessData«, »DdeConnect«, »DdeConnectList«, »DdeCreateStringHandle«


  DdeCmpStringHandles

int DdeCmpStringHandles(hsz1, hsz2)
HSZ  hsz1;   /* handle of first string */
HSZ  hsz2;   /* handle of second string */

The DdeCmpStringHandles function compares the values of two string handles. The value of a string handle is not related to the case of the associated string.

Parameters

hsz1

Specifies the first string handle.

hsz2

Specifies the second string handle.

Return Value

The return value can be one of the following:

Value	Meaning
−1	The value of hsz1 is either 0 or less than the value of hsz2.
0	The values of hsz1 and hsz2 are equal (both can be 0).
1	The value of hsz2 is either 0 or less than the value of hsz1.
Comments

An application that must do a case-sensitive comparison of two string handles should compare the string handles directly. An application should use DdeCmpStringHandles for all other comparisons to preserve the case-insensitive nature of dynamic data exchange (DDE).

DdeCmpStringHandles cannot be used to sort string handles alphabetically.

See Also

»DdeAccessData«, »DdeCreateStringHandle«, »DdeFreeStringHandle«


  DdeConnect

HCONV DdeConnect(idInst, hszService, hszTopic, pCC)
DWORD  idInst;   /* instance identifier */
HSZ  hszService;   /* handle of service-name string */
HSZ  hszTopic;   /* handle of topic-name string */
PCONVCONTEXT  pCC;   /* address of structure with context data */

The DdeConnect function establishes a conversation with a server application that supports the specified service name and topic name pair. If more than one such server exists, the system selects only one.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hszService

Identifies the string that specifies the service name of the server application with which a conversation is to be established. This handle must have been created by a previous call to the DdeCreateStringHandle function. If this parameter is 0L, a conversation is established with any available server.

hszTopic

Identifies the string that specifies the name of the topic on which a conversation is to be established. This handle must have been created by a previous call to DdeCreateStringHandle. If this parameter is 0L, a conversation on any topic supported by the selected server is established.

pCC

Points to the CONVCONTEXT structure that contains conversation-context information. If this parameter is NULL, the server receives the default CONVCONTEXT structure during the XTYP_CONNECT or XTYP_WILDCONNECT transaction.

The CONVCONTEXT structure has the following form:

typedef struct tagCONVCONTEXT {   /* cc */

    UINT  cb;

    UINT  wFlags;

    UINT  wCountryID;

    int   iCodePage;

    DWORD dwLangID;

    DWORD dwSecurity;

    SECURITY_QUALITY_OF_SERVICE qos;  /* client side's quality of service */

} CONVCONTEXT;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the established conversation; otherwise, it is 0L.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR

Comments

The client application cannot make assumptions regarding the server selected. If an instance-specific name is specified in the hszService parameter, a conversation is established with only the specified instance. Instance-specific service names are passed to an application's dynamic data exchange (DDE) callback function during the XTYP_REGISTER and XTYP_UNREGISTER transactions.

All members of the default CONVCONTEXT structure are set to zero except cb, which specifies the size of the structure, and iCodePage, which specifies CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.

See Also

»DdeConnectList«, »DdeCreateStringHandle«, »DdeDisconnect«, »DdeDisconnectList«, »DdeInitialize«


  DdeConnectList

HCONVLIST DdeConnectList(idInst, hszService, hszTopic, hConvList, pCC)
DWORD  idInst;   /* instance identifier */
HSZ  hszService;   /* handle of service-name string */
HSZ  hszTopic;   /* handle of topic-name string */
HCONVLIST  hConvList;   /* handle of conversation list */
PCONVCONTEXT  pCC;   /* address of structure with context data */

The DdeConnectList function establishes a conversation with all server applications that support the specified service name and topic name pair. An application can also use this function to retrieve a list of conversation handles by passing the function an existing conversation handle. The Dynamic Data Exchange Management Library (DDEML) removes the handles of any terminated conversations from the conversation list. The resulting conversation list contains the handles of all currently established conversations that support the specified service name and topic name.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hszService

Identifies the string that specifies the service name of the server application with which a conversation is to be established. If this parameter is 0L, the system attempts to establish conversations with all available servers that support the specified topic name.

hszTopic

Identifies the string that specifies the name of the topic on which a conversation is to be established. This handle must have been created by a previous call to the DdeCreateStringHandle function. If this parameter is 0L, the system will attempt to establish conversations on all topics supported by the selected server (or servers).

hConvList

Identifies the conversation list to be enumerated. This parameter should be set to 0L if a new conversation list is to be established.

pCC

Points to the CONVCONTEXT structure that contains conversation-context information. If this parameter is NULL, the server receives the default CONVCONTEXT structure during the XTYP_CONNECT or XTYP_WILDCONNECT transaction.

The CONVCONTEXT structure has the following form:

typedef struct tagCONVCONTEXT {   /* cc */

    UINT  cb;

    UINT  wFlags;

    UINT  wCountryID;

    int   iCodePage;

    DWORD dwLangID;

    DWORD dwSecurity;

    SECURITY_QUALITY_OF_SERVICE qos;  /* client side's quality of service */

} CONVCONTEXT;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of a new conversation list; otherwise, it is 0L. The handle of the old conversation list is no longer valid.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALID_PARAMETER
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR
DMLERR_SYS_ERROR

Comments

An application must free the conversation-list handle returned by this function, regardless of whether any conversation handles within the list are active. To free the handle, an application can call the DdeDisconnectList function.

All members of the default CONVCONTEXT structure are set to zero except cb, specifying the size of the structure, and iCodePage, specifying CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.

See Also

»DdeConnect«, »DdeCreateStringHandle«, »DdeDisconnect«, »DdeDisconnectList«, »DdeInitialize«, »DdeQueryNextServer«


  DdeCreateDataHandle

HDDEDATA DdeCreateDataHandle(idInst, lpbSrcBuf, cbInitData, offSrcBuf, hszItem,
uFmt, afCmd)
DWORD  idInst;   /* instance identifier */
LPBYTE  lpbSrcBuf;   /* address of source buffer */
DWORD  cbInitData;   /* length of DDE object */
DWORD  offSrcBuf;   /* offset from beginning of source buffer */
HSZ  hszItem;   /* handle of item-name string */
UINT  uFmt;   /* clipboard data format */
UINT  afCmd;   /* creation flags */

The DdeCreateDataHandle function creates a dynamic data exchange (DDE) object and fills the object with the data pointed to by the lpbSrcBuf parameter. A DDE application uses this function during transactions that involve passing data to the partner application.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

lpbSrcBuf

Points to a buffer that contains data to be copied to the DDE object. If this parameter is NULL, no data is copied to the object.

cbInitData

Specifies the amount of memory, in bytes, to allocate for the DDE object. If this parameter is zero, the lpbSrcBuf parameter is ignored.

offSrcBuf

Specifies an offset, in bytes, from the beginning of the buffer pointed to by the lpbSrcBuf parameter. The data beginning at this offset is copied from the buffer to the DDE object.

hszItem

Identifies the string that specifies the data item corresponding to the DDE object. This handle must have been created by a previous call to the DdeCreateStringHandle function. If the data handle is to be used in an XTYP_EXECUTE transaction, this parameter must be set to 0L.

uFmt

Specifies the standard clipboard format of the data.

afCmd

Specifies the creation flags. This parameter can be HDATA_APPOWNED, specifying that the server application that calls the DdeCreateDataHandle function owns the data handle this function creates. This enables the application to share the data handle with other Dynamic Data Exchange Management Library (DDEML) applications rather than creating a separate handle to pass to each application. If this flag is set, the application must eventually free the shared memory object associated with this handle by using the DdeFreeDataHandle function. If this flag is not set, after the data handle is returned by the application's DDE callback function or used as a parameter in another DDEML function, the handle becomes invalid in the application that creates the handle.

Return Value

If the function succeeds, the return value is a data handle; otherwise, it is 0L.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_MEMORY_ERROR
DMLERR_NO_ERROR

Comments

Any unfilled locations in the DDE object are undefined.

After a data handle has been used as a parameter in another DDEML function or has been returned by a DDE callback function, the handle may be used only for read access to the DDE object identified by the handle.

See Also

»DdeAccessData«, »DdeFreeDataHandle«, »DdeGetData«, »DdeInitialize«


  DdeCreateStringHandle

HSZ DdeCreateStringHandle(idInst, lpszString, codepage)
DWORD  idInst;   /* instance identifier */
LPTSTR  lpszString;   /* address of null-terminated string */
int  codepage;   /* code page identifier */

The DdeCreateStringHandle function creates a handle that identifies the string pointed to by the lpszString parameter. A dynamic data exchange (DDE) client or server application can pass the string handle as a parameter to other Dynamic Data Exchange Management Library (DDEML) functions.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

lpszString

Points to a buffer that contains the null-terminated string for which a handle is to be created. This string may be of any length.

codepage

Specifies the code page used to render the string. This value should be either CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode version of DdeInitialize was called by the client application.

Return Value

If the function succeeds, the return value is a string handle; otherwise, it is 0L.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_SYS_ERROR

Comments

The value of a string handle is not related to the case of the string it identifies.

When an application either creates a string handle or receives one in the callback function and uses the DdeKeepStringHandle function to keep it, the application must free that string handle when it is no longer needed.

An instance-specific string handle cannot be mapped from string handle to string and back to string handle. This is shown in the following example, in which the DdeQueryString function creates a string from a string handle and DdeCreateStringHandle creates a string handle from that string, but the two handles are not the same:

DWORD idInst;

DWORD cb;

HSZ hszInst, hszNew;

PSZ pszInst;

DdeQueryString(idInst, hszInst, pszInst, cb, CP_WINANSI);

hszNew = DdeCreateStringHandle(idInst, pszInst, CP_WINANSI);

/* hszNew != hszInst ! */

See Also

»DdeAccessData«, »DdeCmpStringHandles«, »DdeFreeStringHandle«, »DdeInitialize«, »DdeKeepStringHandle«, »DdeQueryString«


  DdeDisconnect

BOOL DdeDisconnect(hconv)
HCONV  hconv;   /* handle of conversation */

The DdeDisconnect function terminates a conversation started by either the DdeConnect or DdeConnectList function and invalidates the given conversation handle.

Parameters

hconv

Identifies the active conversation to be terminated.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR

Comments

Any incomplete transactions started before calling DdeDisconnect are immediately abandoned. The XTYP_DISCONNECT transaction type is sent to the dynamic data exchange (DDE) callback function of the partner in the conversation. Generally, only client applications must terminate conversations.

See Also

»DdeConnect«, »DdeConnectList«, »DdeDisconnectList«


  DdeDisconnectList

BOOL DdeDisconnectList(hConvList)
HCONVLIST  hConvList;   /* handle of conversation list */

The DdeDisconnectList function destroys the given conversation list and terminates all conversations associated with the list.

Parameters

hConvList

Identifies the conversation list. This handle must have been created by a previous call to the DdeConnectList function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Comments

An application can use the DdeDisconnect function to terminate individual conversations in the list.

See Also

»DdeConnect«, »DdeConnectList«, »DdeDisconnect«


  DdeEnableCallback

BOOL DdeEnableCallback(idInst, hconv, uCmd)
DWORD  idInst;   /* instance identifier */
HCONV  hconv;   /* handle of conversation */
UINT  uCmd;   /* the enable/disable function code */

The DdeEnableCallback function enables or disables transactions for a specific conversation or for all conversations currently established by the calling application.

After disabling transactions for a conversation, the system places the transactions for that conversation in a transaction queue associated with the application. The application should reenable the conversation as soon as possible to avoid losing queued transactions.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hconv

Identifies the conversation to enable or disable. If this parameter is 0L, the function affects all conversations.

uCmd

Specifies the function code. This parameter can be one of the following values:

Value	Meaning
EC_ENABLEALL	Enables all transactions for the specified conversation.
EC_ENABLEONE	Enables one transaction for the specified conversation.
EC_DISABLE	Disables all blockable transactions for the specified conversation.
	A server application can disable the following transactions:
	XTYP_ADVSTART XTYP_ADVSTOP XTYP_EXECUTE XTYP_POKE XTYP_REQUEST
	A client application can disable the following transactions:
	XTYP_ADVDATA XTYP_XACT_COMPLETE
EC_QUERYWAITING	Determines whether any transactions are in the queue for the specified conversation.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. If the uCmd parameter is EC_QUERYWAITING and the queue contains one or more transactions, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_NO_ERROR
DMLERR_INVALIDPARAMETER

Comments

An application can disable transactions for a specific conversation by returning CBR_BLOCK from its dynamic data exchange (DDE) callback function. When the conversation is reenabled by using the DdeEnableCallback function, the system generates the same transaction that was in process when the conversation was disabled.

Using the EC_QUERYWAITING flag does not change the enable state of the conversation and does not cause transactions to be issued within the context of the call to DdeEnableCallback.

See Also

»DdeConnect«, »DdeConnectList«, »DdeDisconnect«, »DdeInitialize«


  DdeFreeDataHandle

BOOL DdeFreeDataHandle(hdata)
HDDEDATA  hdata;   /* handle of DDE object */

The DdeFreeDataHandle function frees a dynamic data exchange (DDE) object and deletes the data handle associated with the object.

Parameters

hdata

Identifies the DDE object to be freed. This handle must have been created by a previous call to the DdeCreateDataHandle function or returned by the DdeClientTransaction function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Comments

An application must call DdeFreeDataHandle under the following circumstances:

•	To free a DDE object that the application allocated by calling the DdeCreateDataHandle function if the object's data handle was never passed by the application to another Dynamic Data Exchange Management Library (DDEML) function

•	To free a DDE object that the application allocated by specifying the HDATA_APPOWNED flag in a call to DdeCreateDataHandle

•	To free a DDE object whose handle the application received from the DdeClientTransaction function

The system automatically frees an unowned object when its handle is returned by a DDE callback function or is used as a parameter in a DDEML function.

See Also

»DdeAccessData«, »DdeCreateDataHandle«


  DdeFreeStringHandle

BOOL DdeFreeStringHandle(idInst, hsz)
DWORD  idInst;   /* instance identifier */
HSZ  hsz;   /* handle of string */

The DdeFreeStringHandle function frees a string handle in the calling application.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hsz

Identifies the string handle to be freed. This handle must have been created by a previous call to the DdeCreateStringHandle function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

An application can free string handles it creates with DdeCreateStringHandle but should not free those that the system passed to the application's dynamic data exchange (DDE) callback function or those returned in the CONVINFO structure by the DdeQueryConvInfo function.

See Also

»DdeCmpStringHandles«, »DdeCreateStringHandle«, »DdeInitialize«, »DdeKeepStringHandle«, »DdeQueryString«


  DdeGetData

DWORD DdeGetData(hdata, lpbDest, cbMax, offSrc)
HDDEDATA  hdata;   /* handle of DDE  object */
LPBYTE  lpbDest;   /* address of destination buffer */
DWORD  cbMax;   /* amount of data to copy */
DWORD  offSrc;   /* offset to beginning of data */

The DdeGetData function copies data from the given dynamic data exchange (DDE) object to the specified local buffer.

Parameters

hdata

Identifies the DDE object that contains the data to copy.

lpbDest

Points to the buffer that receives the data. If this parameter is NULL, the DdeGetData function returns the amount of data, in bytes, that would be copied to the buffer.

cbMax

Specifies the maximum amount of data, in bytes, to copy to the buffer pointed to by the lpbDest parameter. Typically, this parameter specifies the length of the buffer pointed to by lpbDest.

offSrc

Specifies an offset within the DDE object. Data is copied from the object beginning at this offset.

Return Value

If the lpbDest parameter points to a buffer, the return value is the size, in bytes, of the memory object associated with the data handle or the size specified in the cbMax parameter, whichever is lower.

If the lpbDest parameter is NULL, the return value is the size, in bytes, of the memory object associated with the data handle.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

See Also

»DdeAccessData«, »DdeCreateDataHandle«, »DdeFreeDataHandle«


  DdeGetLastError

UINT DdeGetLastError(idInst)
DWORD  idInst;   /* instance identifier */

The DdeGetLastError function returns the most recent error value set by the failure of a Dynamic Data Exchange Management Library (DDEML) function and resets the error value to DMLERR_NO_ERROR.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

Return Value

If the function succeeds, the return value is the last error value. Following are the possible DDEML error values:

Value	Meaning
DMLERR_ADVACKTIMEOUT	A request for a synchronous advise transaction has timed out.
DMLERR_BUSY	The response to the transaction caused the DDE_FBUSY bit to be set.
DMLERR_DATAACKTIMEOUT	A request for a synchronous data transaction has timed out.
DMLERR_DLL_NOT_INITIALIZED	A DDEML function was called without first calling the DdeInitialize function, or an invalid instance identifier was passed to a DDEML function.
DMLERR_DLL_USAGE	An application initialized as APPCLASS_MONITOR has attempted to perform a dynamic data exchange (DDE) transaction, or an application initialized as APPCMD_CLIENTONLY has attempted to perform server transactions.
DMLERR_EXECACKTIMEOUT	A request for a synchronous execute transaction has timed out.
DMLERR_INVALIDPARAMETER	A parameter failed to be validated by the DDEML. Some of the possible causes are as follows:
	The application used a data handle initialized with a different item-name handle than was required by the transaction.
	The application used a data handle that was initialized with a different clipboard data format than was required by the transaction.
	The application used a client-side conversation handle with a server-side function or vice versa.
	The application used a freed data handle or string handle.
	More than one instance of the application used the same object.
DMLERR_LOW_MEMORY	A DDEML application has created a prolonged race condition (in which the server application outruns the client), causing large amounts of memory to be consumed.
DMLERR_MEMORY_ERROR	A memory allocation has failed.
DMLERR_NO_CONV_ESTABLISHED	A client's attempt to establish a conversation has failed.
DMLERR_NOTPROCESSED	A transaction has failed.
DMLERR_POKEACKTIMEOUT	A request for a synchronous poke transaction has timed out.
DMLERR_POSTMSG_FAILED	An internal call to the PostMessage function has failed.
DMLERR_REENTRANCY	An application instance with a synchronous transaction already in progress attempted to initiate another synchronous transaction, or the DdeEnableCallback function was called from within a DDEML callback function.
DMLERR_SERVER_DIED	A server-side transaction was attempted on a conversation terminated by the client, or the server terminated before completing a transaction.
DMLERR_SYS_ERROR	An internal error has occurred in the DDEML.
DMLERR_UNADVACKTIMEOUT	A request to end an advise transaction has timed out.
DMLERR_UNFOUND_QUEUE_ID	An invalid transaction identifier was passed to a DDEML function. Once the application has returned from an XTYP_XACT_COMPLETE callback, the transaction identifier for that callback is no longer valid.
See Also

»DdeInitialize«


  DdeImpersonateClient

BOOL DdeImpersonateClient(hConv)
HCONV  hConv;   /* handle of DDE conversation */

The DdeImpersonateClient function impersonates a dynamic data exchange (DDE) client application in a DDE client conversation.

Parameters

hConv

Identifies the DDE client conversation to be impersonated.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Impersonation is the ability of a process to take on the security attributes of another process. When a client in a DDE conversation requests information from a DDE server, the server impersonates the client. When the server requests access to an object, the system verifies the access against the client's security attributes.

When the impersonation is complete, the server normally calls the RevertToSelf function.

See Also

»ImpersonateNamedPipeClient«, »RevertToSelf«


  DdeInitialize

UINT DdeInitialize(lpidInst, pfnCallback, afCmd, uRes)
LPDWORD  lpidInst;   /* address of instance identifier */
PFNCALLBACK  pfnCallback;   /* address of callback function */
DWORD  afCmd;   /* set of command and filter flags */
DWORD  uRes;   /* reserved */

The DdeInitialize function registers an application with the Dynamic Data Exchange Management Library (DDEML). An application must call this function before calling any other DDEML function.

Parameters

lpidInst

Points to the application-instance identifier. At initialization, this parameter should point to 0. If the function succeeds, this parameter points to the instance identifier for the application. This value should be passed as the idInst parameter in all other DDEML functions that require it. If an application uses multiple instances of the DDEML dynamic link library (DLL), the application should provide a different callback function for each instance.

If lpidInst points to a nonzero value, this implies a reinitialization of the DDEML. In this case, lpidInst must point to a valid application-instance identifier.

pfnCallback

Points to the application-defined dynamic data exchange (DDE) callback function. This function processes DDE transactions sent by the system. For more information, see the description of the callback function »DdeCallback«.

afCmd

Specifies a set of APPCMD_, CBF_, and MF_ flags. The APPCMD_ flags provide special instructions to the DdeInitialize function. The CBF_ flags set filters that prevent specific types of transactions from reaching the callback function. The MF_ flags specify the types of DDE activity that a DDE monitoring application monitors. Using these flags enhances the performance of a DDE application by eliminating unnecessary calls to the callback function.

This parameter can be a combination of the following flags:

Flag	Meaning
APPCLASS_MONITOR	Makes it possible for the application to monitor DDE activity in the system. This flag is for use by DDE monitoring applications. The application specifies the types of DDE activity to monitor by combining one or more monitor flags with the APPCLASS_MONITOR flag. For details, see the following Comments section.
APPCLASS_STANDARD	Registers the application as a standard (nonmonitoring) DDEML application.
APPCMD_CLIENTONLY	Prevents the application from becoming a server in a DDE conversation. The application can only be a client. This flag reduces consumption of resources by the DDEML. It includes the functionality of the CBF_FAIL_ALLSVRXACTIONS flag.
APPCMD_FILTERINITS	Prevents the DDEML from sending XTYP_CONNECT and XTYP_WILDCONNECT transactions to the application until the application has created its string handles and registered its service names or has turned off filtering by a subsequent call to the DdeNameService or DdeInitialize function. This flag is always in effect when an application calls DdeInitialize for the first time, regardless of whether the application specifies this flag. On subsequent calls to DdeInitialize, not specifying this flag turns off the application's service-name filters; specifying this flag turns on the application's service-name filters.
CBF_FAIL_ALLSVRXACTIONS	Prevents the callback function from receiving server transactions. The system returns DDE_FNOTPROCESSED to each client that sends a transaction to this application. This flag is equivalent to combining all CBF_FAIL_ flags.
CBF_FAIL_ADVISES	Prevents the callback function from receiving XTYP_ADVSTART and XTYP_ADVSTOP transactions. The system returns DDE_FNOTPROCESSED to each client that sends an XTYP_ADVSTART or XTYP_ADVSTOP transaction to the server.
CBF_FAIL_CONNECTIONS	Prevents the callback function from receiving XTYP_CONNECT and XTYP_WILDCONNECT transactions.
CBF_FAIL_EXECUTES	Prevents the callback function from receiving XTYP_EXECUTE transactions. The system returns DDE_FNOTPROCESSED to a client that sends an XTYP_EXECUTE transaction to the server.
CBF_FAIL_POKES	Prevents the callback function from receiving XTYP_POKE transactions. The system returns DDE_FNOTPROCESSED to a client that sends an XTYP_POKE transaction to the server.
CBF_FAIL_REQUESTS	Prevents the callback function from receiving XTYP_REQUEST transactions. The system returns DDE_FNOTPROCESSED to a client that sends an XTYP_REQUEST transaction to the server.
CBF_FAIL_SELFCONNECTIONS	Prevents the callback function from receiving XTYP_CONNECT transactions from the application's own instance. This prevents an application from establishing a DDE conversation with its own instance. An application should use this flag if it needs to communicate with other instances of itself but not with itself.
CBF_SKIP_ALLNOTIFICATIONS	Prevents the callback function from receiving any notifications. This flag is equivalent to combining all CBF_SKIP_ flags.
CBF_SKIP_CONNECT_CONFIRMS	Prevents the callback function from receiving XTYP_CONNECT_CONFIRM notifications.
CBF_SKIP_DISCONNECTS	Prevents the callback function from receiving XTYP_DISCONNECT notifications.
CBF_SKIP_REGISTRATIONS	Prevents the callback function from receiving XTYP_REGISTER notifications.
CBF_SKIP_UNREGISTRATIONS	Prevents the callback function from receiving XTYP_UNREGISTER notifications.
MF_CALLBACKS	Notifies the callback function whenever a transaction is sent to any DDE callback function in the system.
MF_CONV	Notifies the callback function whenever a conversation is established or terminated.
MF_ERRORS	Notifies the callback function whenever a DDE error occurs.
MF_HSZ_INFO	Notifies the callback function whenever a DDE application creates, frees, or increments the usage count of a string handle or whenever a string handle is freed as a result of a call to the DdeUninitialize function.
MF_LINKS	Notifies the callback function whenever an advise loop is started or ended.
MF_POSTMSGS	Notifies the callback function whenever the system or an application posts a DDE message.
MF_SENDMSGS	Notifies the callback function whenever the system or an application sends a DDE message.
uRes

Reserved; must be set to 0.

Return Value

If the function succeeds, the return value is one of the following:

DMLERR_DLL_USAGE
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_SYS_ERROR

Comments

An application that uses multiple instances of the DDEML must not pass DDEML objects between instances.

A DDE monitoring application should not attempt to perform DDE operations (establish conversations, issue transactions, and so on) within the context of the same application instance.

A synchronous transaction fails with a DMLERR_REENTRANCY error if any instance of the same task has a synchronous transaction already in progress.

The CBF_FAIL_ALLSVRACTIONS flag causes the DDEML to filter all server transactions and can be changed by a subsequent call to DdeInitialize. The APPCMD_CLIENTONLY flag prevents the DDEML from creating key resources for the server and cannot be changed by a subsequent call to DdeInitialize.

There is an ANSI version and a Unicode version of this function. The version called determines the type of the window procedures used to control DDE conversations (ANSI or Unicode), and the default value for the iCodePage member of the CONVCONTXT structure (CP_WINANSI or CP_WINUNICODE).

See Also

»DdeClientTransaction«, »DdeConnect«, »DdeCreateDataHandle«, »DdeEnableCallback«, »DdeNameService«, »DdePostAdvise«, »DdeUninitialize«


  DdeKeepStringHandle

BOOL DdeKeepStringHandle(idInst, hsz)
DWORD  idInst;   /* instance identifier */
HSZ  hsz;   /* handle of string */

The DdeKeepStringHandle function increments (increases by one) the usage count associated with the given handle. This function enables an application to save a string handle passed to the application's dynamic data exchange (DDE) callback function. Otherwise, a string handle passed to the callback function is deleted when the callback function returns. This function should also be used to keep a copy of a string handle referenced by the CONVINFO structure returned by the DdeQueryConvInfo function.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hsz

Identifies the string handle to be saved.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»DdeCreateStringHandle«, »DdeFreeStringHandle«, »DdeInitialize«, »DdeQueryConvInfo«, »DdeQueryString«


  DdeNameService

HDDEDATA DdeNameService(idInst, hsz1, hszRes, afCmd)
DWORD  idInst;   /* instance identifier */
HSZ  hsz1;   /* handle of service-name string */
HSZ  hszRes;   /* reserved */
UINT  afCmd;   /* service-name flags */

The DdeNameService function registers or unregisters the service names a dynamic data exchange (DDE) server supports. This function causes the system to send XTYP_REGISTER or XTYP_UNREGISTER transactions to other running Dynamic Data Exchange Management Library (DDEML) client applications.

A server application should call this function to register each service name that it supports and to unregister names it previously registered but no longer supports. A server should also call this function to unregister its service names just before terminating.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hsz1

Identifies the string that specifies the service name the server is registering or unregistering. An application that is unregistering all of its service names should set this parameter to 0L.

hszRes

Reserved; should be set to 0L.

afCmd

Specifies the service-name flags. This parameter can be one of the following values:

Value	Meaning
DNS_REGISTER	Registers the given service name.
DNS_UNREGISTER	Unregisters the given service name. If the hsz1 parameter is 0L, all service names registered by the server will be unregistered.
DNS_FILTERON	Turns on service-name initiation filtering. This filter prevents a server from receiving XTYP_CONNECT transactions for service names it has not registered. This is the default setting for this filter.
	If a server application does not register any service names, the application cannot receive XTYP_WILDCONNECT transactions.
DNS_FILTEROFF	Turns off service-name initiation filtering. If this flag is set, the server receives an XTYP_CONNECT transaction whenever another DDE application calls the DdeConnect function, regardless of the service name.
Return Value

The function returns a non-zero value if it succeeds. That value is not a true HDDEDATA value, merely a Boolean indicator of success. The function is typed HDDEDATA to allow for possible future expansion of the function and a more sophisticated return value.

The function returns 0L if it fails.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_DLL_USAGE
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Comments

The service name identified by the hsz1 parameter should be a base name (that is, the name should contain no instance-specific information). The system generates an instance-specific name and sends it along with the base name during the XTYP_REGISTER and XTYP_UNREGISTER transactions. The receiving applications can then connect to the specific application instance.

See Also

»DdeConnect«, »DdeConnectList«, »DdeInitialize«


  DdePostAdvise

BOOL DdePostAdvise(idInst, hszTopic, hszItem)
DWORD  idInst;   /* instance identifier */
HSZ  hszTopic;   /* handle of topic-name string */
HSZ  hszItem;   /* handle of item-name string */

The DdePostAdvise function causes the system to send an XTYP_ADVREQ transaction to the calling (server) application's dynamic data exchange (DDE) callback function for each client with an active advise loop on the specified topic and item. A server application should call this function whenever the data associated with the topic name or item name pair changes.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hszTopic

Identifies a string that specifies the topic name. To send notifications for all topics with active advise loops, an application can set this parameter to 0L.

hszItem

Identifies a string that specifies the item name. To send notifications for all items with active advise loops, an application can set this parameter to 0L.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_DLL_USAGE
DMLERR_NO_ERROR

Comments

A server that has nonenumerable topics or items should set the hszTopic and hszItem parameters to NULL so that the system generates transactions for all active advise loops. The server's DDE callback function returns NULL for any advise loops that must not be updated.

If a server calls DdePostAdvise with a topic, item, and format name set that includes the set currently being handled in an XTYP_ADVREQ callback, a stack overflow may result.

See Also

»DdeInitialize«


  DdeQueryConvInfo

UINT DdeQueryConvInfo(hconv, idTransaction, lpConvInfo)
HCONV  hconv;   /* handle of conversation */
DWORD  idTransaction;   /* transaction identifier */
PCONVINFO  lpConvInfo;   /* address of structure with conversation data */

The DdeQueryConvInfo function retrieves information about a dynamic data exchange (DDE) transaction and about the conversation in which the transaction takes place.

Parameters

hconv

Identifies the conversation.

idTransaction

Specifies the transaction. For asynchronous transactions, this parameter should be a transaction identifier returned by the DdeClientTransaction function. For synchronous transactions, this parameter should be QID_SYNC.

lpConvInfo

Points to the CONVINFO structure that receives information about the transaction and conversation. The cb member of the CONVINFO structure must specify the length of the buffer allocated for the structure.

The CONVINFO structure has the following form:

typedef struct tagCONVINFO {  /* ci */

    DWORD       cb;

    DWORD       hUser;

    HCONV       hConvPartner;

    HSZ         hszSvcPartner;

    HSZ         hszServiceReq;

    HSZ         hszTopic;

    HSZ         hszItem;

    UINT        wFmt;

    UINT        wType;

    UINT        wStatus;

    UINT        wConvst;

    UINT        wLastError;

    HCONVLIST   hConvList;

    CONVCONTEXT ConvCtxt;

    HWND        hwnd;

    HWND        hwndPartner;

} CONVINFO;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the number of bytes copied into the CONVINFO structure; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR
DMLERR_UNFOUND_QUEUE_ID

Comments

An application should not free a string handle referenced by the CONVINFO structure. If an application must use one of these string handles, it should call the DdeKeepStringHandle function to create a copy of the handle.

If the idTransaction parameter is set to QID_SYNC, the hUser member of the CONVINFO structure is associated with the conversation and can be used to hold data associated with the conversation. If idTransaction is the identifier of an asynchronous transaction, the hUser member is associated only with the current transaction and is valid only for the duration of the transaction.

See Also

»DdeConnect«, »DdeConnectList«, »DdeKeepStringHandle«, »DdeQueryNextServer«


  DdeQueryNextServer

HCONV DdeQueryNextServer(hConvList, hConvPrev)
HCONVLIST  hConvList;   /* handle of conversation list */
HCONV  hConvPrev;   /* previous conversation handle */

The DdeQueryNextServer function obtains the next conversation handle in the given conversation list.

Parameters

hConvList

Identifies the conversation list. This handle must have been created by a previous call to the DdeConnectList function.

hConvPrev

Identifies the conversation handle previously returned by this function. If this parameter is 0L, the function returns the first conversation handle in the list.

Return Value

If the list contains any more conversation handles, the return value is the next conversation handle in the list; otherwise, it is 0L.

See Also

»DdeConnectList«, »DdeDisconnectList«


  DdeQueryString

DWORD DdeQueryString(idInst, hsz, lpsz, cchMax, codepage)
DWORD  idInst;   /* instance identifier */
HSZ  hsz;   /* handle of string */
LPTSTR  lpsz;   /* address of destination buffer */
DWORD  cchMax;   /* length of buffer */
int  codepage;   /* code page identifier */

The DdeQueryString function copies text associated with a string handle into a buffer.

The string returned in the buffer is always null-terminated. If the string is longer than (cchMax − 1), only the first (cchMax − 1) characters of the string are copied.

If the lpsz parameter is NULL, this function obtains the length, in bytes, of the string associated with the string handle. The length does not include the terminating null character.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

hsz

Identifies the string to copy. This handle must have been created by a previous call to the DdeCreateStringHandle function.

lpsz

Points to a buffer that receives the string. To obtain the length of the string, this parameter should be set to NULL.

cchMax

Specifies the length, in characters, of the buffer pointed to by the lpsz parameter. If the string is longer than (cchMax − 1), it will be truncated. If the lpsz parameter is set to NULL, this parameter is ignored.

codepage

Specifies the code page used to render the string. This value should be either CP_WINANSI or CP_WINUNICODE.

Return Value

If the lpsz parameter specified a valid pointer, the return value is the length, in characters, of the returned text (not including the terminating null character). If the lpsz parameter specified a NULL pointer, the return value is the length of the text associated with the hsz parameter (not including the terminating null character). If an error occurs, the return value is 0L.

See Also

»DdeCmpStringHandles«, »DdeCreateStringHandle«, »DdeFreeStringHandle«, »DdeInitialize«


  DdeReconnect

HCONV DdeReconnect(hconv)
HCONV  hconv;   /* handle of conversation to reestablish */

The DdeReconnect function allows a client Dynamic Data Exchange Management Library (DDEML) application to attempt to reestablish a conversation with a service that has terminated a conversation with the client. When the conversation is reestablished, the DDEML attempts to reestablish any preexisting advise loops.

Parameters

hconv

Identifies the conversation to be reestablished. A client must have obtained the conversation handle by a previous call to the DdeConnect function or from an XTYP_DISCONNECT transaction.

Return Value

If the function succeeds, the return value is the handle of the reestablished conversation; otherwise, it is 0L.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR

See Also

»DdeConnect«, »DdeDisconnect«


  DdeSetQualityOfService

BOOL DdeSetQualityOfService(hwndClient, pqosNew, pqosPrev)
HWND  hwndClient;   /* window that will start DDE conversations */
CONST SECURITY_QUALITY_OF_SERVICE *  pqosNew;   /* desired quality of service */
PSECURITY_QUALITY_OF_SERVICE  pqosPrev;   /* prior quality of service */

The DdeSetQualityOfService function specifies the quality of service a raw DDE application desires for future DDE conversations it initiates. The specified quality of service applies to any conversations started while those settings are in place. A DDE conversation's quality of service lasts for the duration of the conversation; calls to the DdeSetQualityOfService function during a given conversation do not affect that conversation's quality of service.

Parameters

hwndClient

A window handle that specifies the source of WM_DDE_INITIATE messages that a client will send to start DDE conversations.

pqosNew

Points to a SECURITY_QUALITY_OF_SERVICE structure that contains the desired quality of service (qos) values. The SECURITY_QUALITY_OF_SERVICE structure has the following form:

typedef struct _SECURITY_QUALITY_OF_SERVICE { /* sqos */

    DWORD Length;

    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;

    SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;

    BOOLEAN EffectiveOnly;

} SECURITY_QUALITY_OF_SERVICE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

pqosPrev

Points to a SECURITY_QUALITY_OF_SERVICE structure that the function will fill with the previous quality of service (qos) values associated with hwndClient.

This parameter is optional. If an application has no interest in hwndClient's previous qos values, it should set pqosPrev to NULL.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. Call GetLastError for extended error information.

Comments

The settings associated with a given hwndClient affect any conversation started subsequent to calling the DdeSetQualityOfService function. The settings remain in force for the duration of any DDE conversation started under them. Once an application starts a DDE conversation using a particular quality of service (qos), it must terminate the conversation and restart the conversation in order to have a different qos take effect. If a qos has not been  specified for a given hwndClient prior to sending a WM_DDE_INITIATE with the wParam set to hwndClient, the system uses its default quality of service values. Those defaults are :

    {

    Length = sizeof(SECURITY_QUALITY_OF_SERVICE);

    ImpersonationLevel = SecurityImpersonation ;

    ContextTrackingMode = SECURITY_STATIC_TRACKING ;

    EffectiveOnly = TRUE ;

    }

See Also

»DdeConnect«, »DdeConnectList«, »ImpersonateDdeClientWindow«, »DdeImpersonateClient«


  DdeSetUserHandle

BOOL DdeSetUserHandle(hconv,id, hUser)
HCONV  hconv;   /* handle of conversation */
DWORD  id;   /* transaction identifier */
DWORD  hUser;   /* application-defined value */

The DdeSetUserHandle function associates an application-defined 32-bit value with a conversation handle or a transaction identifier. This is useful for simplifying the processing of asynchronous transactions. An application can use the DdeQueryConvInfo function to retrieve this value.

Parameters

hconv

Identifies the conversation.

id

Specifies the transaction identifier to associate with the value specified by the hUser parameter. An application should set this parameter to QID_SYNC to associate hUser with the conversation identified by the hconv parameter.

hUser

Identifies the value to associate with the conversation handle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_UNFOUND_QUEUE_ID

See Also

»DdeQueryConvInfo«


  DdeUnaccessData

BOOL DdeUnaccessData(hData)
HDDEDATA  hData;   /* handle of DDE object */

The DdeUnaccessData function unaccesses a dynamic data exchange (DDE) object. An application must call this function after it has finished accessing the object.

Parameters

hData

Identifies the DDE object.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error value, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

See Also

»DdeAccessData«, »DdeAddData«, »DdeCreateDataHandle«, »DdeFreeDataHandle«


  DdeUninitialize

BOOL DdeUninitialize(idInst)
DWORD  idInst;   /* instance identifier */

The DdeUninitialize function frees all Dynamic Data Exchange Management Library (DDEML) resources associated with the calling application.

Parameters

idInst

Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

DdeUninitialize terminates any conversations currently open for the application.

See Also

»DdeDisconnect«, »DdeDisconnectList«, »DdeInitialize«


  DebugActiveProcess

BOOL DebugActiveProcess(idProcess)
DWORD  idProcess;   /* process to be debugged */

The DebugActiveProcess function allows a debugger to attach to an active process and then debug it.

Parameters

idProcess

Identifies the process to be debugged. The debugger gets debugging access to the process as if it had created the process with the DEBUG_ONLY_THIS_PROCESS flag set.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The debugger must have appropriate access to the target process — it must be able to open the process for PROCESS_ALL_ACCESS access. In the Win32 application programming interface (API) for MS-DOS, this is always true if the process identifier is valid. In the Win32 API for Windows NT, this function can fail if the target process was created with a security descriptor that denies the debugger appropriate access.

After the system checks the process identifier and determines that a valid debugging attachment is being made, this function returns TRUE. The debugger is then expected to wait for debugging events by using the WaitForDebugEvent function. The system suspends all threads in the process and sends the debugger events representing the current state of the process.

The system sends the debugger a single CREATE_PROCESS_DEBUG_EVENT debugging event representing the process specified by the idProcess parameter. The lpStartAddress member of the CREATE_PROCESS_DEBUG_INFO structure is NULL.

For each thread currently part of the process, the system sends a CREATE_THREAD_DEBUG_EVENT debugging event. The lpStartAddress member of the CREATE_THREAD_DEBUG_INFO structure is NULL.

For each dynamic-link library (DLL) currently loaded into the address space of the target process, the system sends a LOAD_DLL_DEBUG_EVENT debugging event. The system arranges for the first thread in the process to execute a breakpoint instruction after it resumes. Continuing this thread causes it to return to whatever it was doing before the debugger was attached.

After all of this has been done, the system resumes all threads in the process. When the first thread in the process resumes, it executes a breakpoint instruction that causes an EXCEPTION_DEBUG_EVENT debugging event to be sent to the debugger. All future debugging events are sent to the debugger by using the normal mechanism and rules.

See Also

»CreateProcess«, »WaitForDebugEvent«


  DebugBreak

VOID DebugBreak(VOID)

The DebugBreak function causes a breakpoint exception to occur in the current process so that the calling thread can signal the debugger and force it to take some action. If the process is not being debugged, the search logic of a standard exception handler is invoked. In most cases, this causes the calling process to terminate because of an unhandled breakpoint exception.

Parameters

This function has no parameters.

Return Value

This function does not return a value.

See Also

»DebugActiveProcess«


  DebugProc

LRESULT CALLBACK DebugProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* type of hook about to be called */
LPARAM  lParam;   /* address of structure with debugging information */

The DebugProc hook procedure is an application-defined or library-defined callback function that Windows calls before calling the hook procedures associated with any other type of hook. The system passes information about the hook to be called to the DebugProc hook procedure, which examines the information and determines whether to allow the hook to be called.

Parameters

nCode

Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies the type of hook about to be called. This parameter can be one of the following values:

Value	Description
WH_CALLWNDPROC	Installs a hook procedure that monitors messages sent to a window procedure. For more information, see the description of the »CallWndProc« hook procedure.
WH_CBT	Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the description of the »CBTProc« hook procedure.
WH_DEBUG	Installs a hook procedure useful for debugging other hook procedures. For more information, see the description of the »DebugProc« hook procedure.
WH_GETMESSAGE	Installs a hook procedure that monitors messages posted to a message queue. For more information, see the description of the »GetMsgProc« hook procedure.
WH_JOURNALPLAYBACK	Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the description of the »JournalPlaybackProc« hook procedure.
WH_JOURNALRECORD	Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the description of the »JournalRecordProc« hook procedure.
WH_KEYBOARD	Installs a hook procedure that monitors keystroke messages. For more information, see the description of the »KeyboardProc« hook procedure.
WH_MOUSE	Installs a hook procedure that monitors mouse messages. For more information, see the description of the »MouseProc« hook procedure.
WH_MSGFILTER	Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages only for the application that installed the hook procedure. For more information, see the description of the »MessageProc« hook procedure.
WH_SHELL	Installs a hook procedure that receives notifications useful to a shell application. For more information, see the description of the »ShellProc« hook procedure.
WH_SYSMSGFILTER	Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see the description of the »SysMsgProc« hook procedure.
lParam

Points to a DEBUGHOOKINFO structure that contains the parameters to be passed to the destination hook procedure. The DEBUGHOOKINFO structure has the following form:

typedef struct tagDEBUGHOOKINFO { /* dh */

    DWORD  idThread;

    LPARAM reserved;

    LPARAM lParam;

    WPARAM wParam;

    int    code;

} DEBUGHOOKINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

To prevent the system from calling the hook, the return value must be a nonzero value. Otherwise, the hook procedure must pass the hook information to the CallNextHookEx function.

Comments

An application installs this hook procedure by specifying the WH_DEBUG hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

CallWndProc is a placeholder for the application-defined or library-defined function name.

See Also

»CallNextHookEx«, »SetWindowsHookEx«


  DefDlgProc

LRESULT DefDlgProc(hwndDlg, uMsg, wParam, lParam)
HWND  hwndDlg;   /* handle of dialog box */
UINT  uMsg;   /* message */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The DefDlgProc function carries out default message processing for a window procedure belonging to an application-defined dialog box class.

Parameters

hwndDlg

Identifies the dialog box.

uMsg

Specifies the message number.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message sent.

Comments

The DefDlgProc function is the window procedure for the predefined class of dialog box. This procedure provides internal processing for the dialog box by forwarding messages to the dialog box procedure and carrying out default processing for any messages that the dialog box procedure returns as FALSE. Applications that create custom window procedures for their custom dialog boxes often use this function instead of the DefWindowProc to carry out default message processing.

Applications create custom dialog box classes by filling a WNDCLASS structure with appropriate information and registering the class with the RegisterClass function. Some applications fill the structure by using the GetClassInfo function, specifying the name of the predefined dialog box. In such cases, the applications modify at least the lpszClassName member before registering. In all cases, the cbWndExtra member of the WNDCLASS structure for a custom dialog box class must be set to at least DLGWINDOWEXTRA.

DefDlgProc must not be called by a dialog box procedure; doing so results in recursive execution.

See Also

»DefWindowProc«, »GetClassInfo«, »RegisterClass«


  DeferWindowPos

HDWP DeferWindowPos(hdwp, hwnd, hwndInsertAfter, x, y, cx, cy, dwFlags)
HDWP  hdwp;   /* handle of internal structure */
HWND  hwnd;   /* handle of window to position */
HWND  hwndInsertAfter;   /* placement-order handle */
int  x;   /* horizontal position */
int  y;   /* vertical position */
int  cx;   /* width */
int  cy;   /* height */
UINT  dwFlags;   /* window-positioning flags */

The DeferWindowPos function updates the specified multiple-window-position structure for the given window. The function then returns the handle of the updated structure. The EndDeferWindowPos function uses the information in this structure to change the position and size of a number of windows simultaneously. The BeginDeferWindowPos function creates the structure.

Parameters

hdwp

Identifies a multiple-window-position structure that contains size and position information for one or more windows. This structure is returned by the BeginDeferWindowPos function or by the most recent call to the DeferWindowPos function.

hwnd

Identifies the window for which update information is stored in the structure.

hwndInsertAfter

Identifies the window that precedes the positioned window in the Z order. This parameter must be a window handle or one of the following values:

Value	Meaning
HWND_BOTTOM	Places the window at the bottom of the Z order. If the hwnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.
HWND_NOTOPMOST	Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.
HWND_TOP	Places the window at the top of the Z order.
HWND_TOPMOST	Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.
This parameter is ignored if the SWP_NOZORDER flag is set in the dwFlags parameter.

x

Specifies the x-coordinate of the window's upper-left corner.

y

Specifies the y-coordinate of the window's upper-left corner.

cx

Specifies the window's new width, in pixels.

cy

Specifies the window's new height, in pixels.

dwFlags

Specifies a combination of the following values that affect the size and position of the window:

Value	Meaning
SWP_DRAWFRAME	Draws a frame (defined in the window's class description) around the window.
SWP_HIDEWINDOW	Hides the window.
SWP_NOACTIVATE	Does not activate the window.
SWP_NOMOVE	Retains the current position (ignores the x and y parameters).
SWP_NOREDRAW	Does not redraw changes. If this flag is set, no repainting occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that needs to be redrawn.
SWP_NOSIZE	Retains the current size (ignores the cx and cy parameters).
SWP_NOZORDER	Retains the current Z order (ignores the hwndInsertAfter parameter).
SWP_SHOWWINDOW	Displays the window.
Return Value

The return value identifies the updated multiple-window-position structure. The handle returned by this function may differ from the handle passed to the function. The new handle that this function returns should be passed during the next call to the DeferWindowPos or EndDeferWindowPos function.

If insufficient system resources are available for the function to succeed, the return value is NULL.

Comments

If a call to DeferWindowPos fails, the application should abandon the window-positioning operation and not call the EndDeferWindowPos function.

If the SWP_NOZORDER flag is not specified, Windows places the window identified by the hwnd parameter in the position following the window identified by the hwndInsertAfter parameter. If hwndInsertAfter is NULL or the HWND_TOP flag, Windows places the hwnd window at the top of the Z order. If hwndInsertAfter is set to the HWND_BOTTOM flag, Windows places the hwnd window at the bottom of the Z order.

If either the SWP_SHOWWINDOW or the SWP_HIDEWINDOW flag is set, DeferWindowPos will not move or size windows. To show or hide windows, use the ShowWindow function.

All coordinates for child windows are relative to the upper-left corner of the parent window's client area.

A window can be made a topmost window either by setting hwndInsertAfter to the HWND_TOPMOST flag and ensuring that the SWP_NOZORDER flag is not set, or by setting the window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed.

If neither the SWP_NOACTIVATE nor SWP_NOZORDER flag is specified (that is, when the application requests that a window be simultaneously activated and its position in the Z order changed), the value specified in hwndInsertAfter is used only in the following circumstances:

•	Neither the HWND_TOPMOST nor HWND_NOTOPMOST flag is specified in hwndInsertAfter.

•	The window identified by hwnd is not the active window.

An application cannot activate an inactive window without also bringing it to the top of the Z order. An application can change an activated window's position in the Z order without restrictions, or it can activate a window and then move it to the top of the topmost or non-topmost windows.

A topmost window is no longer topmost if it is repositioned to the bottom (HWND_BOTTOM) of the Z order or after any non-topmost window. When a topmost window is made non-topmost, its owners and its owned windows are also made non-topmost windows.

A non-topmost window may own a topmost window, but not vice versa. Any window (for example, a dialog box) owned by a topmost window is itself made a topmost window to ensure that all owned windows stay above their owner.

See Also

»BeginDeferWindowPos«, »EndDeferWindowPos«


  DefFrameProc

LRESULT DefFrameProc(hwndFrame, hwndMDIClient, uMsg, wParam, lParam)
HWND  hwndFrame;   /* handle of MDI frame window */
HWND  hwndMDIClient;   /* handle of MDI client window */
UINT  uMsg;   /* message */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The DefFrameProc function provides default processing for any window messages that the window procedure of a multiple document interface (MDI) frame window does not process. All window messages that are not explicitly processed by the window procedure must be passed to the DefFrameProc function, not the DefWindowProc function.

Parameters

hwndFrame

Identifies the MDI frame window.

hwndMDIClient

Identifies the MDI client window.

uMsg

Specifies the message to be processed.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message. If the hwndMDIClient parameter is NULL, the return value is the same as for the DefWindowProc function.

Comments

When an application's window procedure does not handle a message, it typically passes the message to the DefWindowProc function to process the message. MDI applications use the DefFrameProc and DefMDIChildProc functions instead of DefWindowProc to provide default message processing. All messages that an application would usually pass to DefWindowProc (such as nonclient messages and the WM_SETTEXT message) should be passed to DefFrameProc instead. The DefFrameProc function also handles the following messages:

Message	Response
WM_COMMAND	Activates the MDI child window that the user chooses. This message is sent when the user chooses an MDI child window from the Window menu of the MDI frame window. The window identifier accompanying this message identifies the MDI child window to be activated.
WM_MENUCHAR	Opens the System menu of the active MDI child window when the user presses the ALT+ − (minus) key combination.
WM_SETFOCUS	Passes the keyboard focus to the MDI client window, which in turn passes it to the active MDI child window.
WM_SIZE	Resizes the MDI client window to fit in the new frame window's client area. If the frame window procedure sizes the MDI client window to a different size, it should not pass the message to the DefWindowProc function.
See Also

»DefMDIChildProc«, »DefWindowProc«


  DefHookProc

DWORD DefHookProc(nCode, wParam, lParam, lplpfnNextHook)
int  nCode;   /* hook code passed to hook procedure */
DWORD  wParam;   /* value passed to hook procedure */
LONG  lParam;   /* value passed to hook procedure */
FARPROC  *lplpfnNextHook;   /* not used */

The DefHookProc function is obsolete. For Win32 applications, use the CallNextHookEx function.


  DefineDosDevice

BOOL DefineDosDevice(dwFlags, lpDeviceName, lpTargetPath)
DWORD  dwFlags;   /* flags specifying aspects of device definition */
LPCTSTR  lpDeviceName;   /* pointer to DOS device name string */
LPCTSTR  lpTargetPath;   /* pointer to DOS or Windows NT path string */

The DefineDosDevice function lets an application define, redefine, or delete DOS device names.

DOS device names are stored as symbolic links in the Windows NT object name space. The code that converts a DOS path into a corresponding Windows NT path uses these symbolic links to map DOS devices and drive letters. The DefineDosDevice function provides a mechanism whereby a Win32 application can modify the symbolic links used to implement the DOS device namespace.

Parameters

dwFlags

Specifies several controllable aspects of the DefineDosDevice function. You can use one or more of the following values to set flags:

Value	Meaning
DDD_RAW_TARGET_PATH	If specified, the function does not convert the lpTargetPath string from a DOS path to a Windows NT path, but takes it as is.
DDD_REMOVE_DEFINITION	If specified, the function removes the specified definition for the specified device. To determine which definition to remove, this function walks the list of mappings for the device, looking for a match of lpTargetPath against a prefix  of each mapping associated with this device. The first mapping that matches is the one removed, and then the function returns.
	If lpTargetPath is NULL, or a pointer to a NULL string, then the function will remove the first mapping associated with the device,  and pop the most recent one pushed. If there is nothing left to pop,then the device name will be removed.
	If this flag is NOT set, then the string pointed to by the lpTargetPath parameter will become the new mapping for this device.
DDD_EXACT_MATCH_ON_REMOVE	If set, along with DDD_REMOVE_DEFINITION, then this function will use an exact match to determine which mapping to remove. Use this flag to insure that you don't delete something that you did not define.
lpDeviceName

Pointer to a DOS device name string specifying the device the function is defining, redefining, or deleting. The device name string must NOT have a trailing colon, unless a drive letter (C or D, for example) is being defined, redefined or deleted.

lpTargetPath

Pointer to a path string that will implement this device. Points to a DOS path string unless the DDD_RAW_TARGET_PATH flag is specified, in which case this parameter points to a Windows NT path string.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. Use the GetLastError function to obtain extended error information.

Comments

As stated above, in this function's introductory summary, the DefineDosDevice function provides a means whereby a Win32 application can create and modify the symbolic links used to implement the DOS device namespace. To query the current mapping for a particular DOS device name, or to obtain a list of all DOS devices known to the system, use the QueryDosDevice function.

DOS Device names are global. Once defined, a DOS device name remains visible to all processes until either it is explicity removed or the system reboots.

Note that drive letters and device names defined at system boot time are protected from redefinition and deletion unless a user is running in administrative mode (ADMIN).

See Also

»QueryDosDevice«


  DefineHandleTable

The DefineHandleTable function is obsolete.


  DefMDIChildProc

LRESULT DefMDIChildProc(hwndChild, uMsg, wParam, lParam)
HWND  hwndChild;   /* handle of MDI child window */
UINT  uMsg;   /* message */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The DefMDIChildProc function provides default processing for any window message that the window procedure of a multiple document interface (MDI) child window does not process. A window message not processed by the window procedure must be passed to the DefMDIChildProc function, not the DefWindowProc function.

Parameters

hwndChild

Identifies the MDI child window.

uMsg

Specifies the message to be processed.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message.

Comments

The DefMDIChildProc function assumes that the parent window of the MDI child window identified by the hwndChild parameter was created with the MDICLIENT class.

When an application's window procedure does not handle a message, it typically passes the message to the DefWindowProc function to process the message. MDI applications use the DefFrameProc and DefMDIChildProc functions instead of DefWindowProc to provide default message processing. All messages that an application would usually pass to DefWindowProc (such as nonclient messages and the WM_SETTEXT message) should be passed to DefMDIChildProc instead. In addition, DefMDIChildProc also handles the following messages:

Message	Response
WM_CHILDACTIVATE	Performs activation processing when MDI child windows are sized, moved, or displayed. This message must be passed.
WM_GETMINMAXINFO	Calculates the size of a maximized MDI child window, based on the current size of the MDI client window.
WM_MENUCHAR	Passes the message to the MDI frame window.
WM_MOVE	Recalculates MDI client scroll bars if they are present.
WM_SETFOCUS	Activates the child window if it is not the active MDI child window.
WM_SIZE	Performs operations necessary for changing the size of a window, especially for maximizing or restoring an MDI child window. Failing to pass this message to the DefMDIChildProc function produces highly undesirable results.
WM_SYSCOMMAND	Handles System menu commands: SC_NEXTWINDOW, SC_PREVWINDOW, SC_MOVE, SC_SIZE, and SC_MAXIMIZE.
See Also

»DefFrameProc«, »DefWindowProc«


  DefScreenSaverProc

LONG DefScreenSaverProc(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of screen saver window */
UINT  uMsg;   /* message */
DWORD  wParam;   /* first message parameter */
LONG  lParam;   /* second message parameter */

The DefScreenSaverProc function provides default processing for any messages that a screen saver application does not process.

Parameters

hwnd

Identifies the screen saver window.

uMsg

Specifies the message to be processed. The DefScreenSaverProc function responds to messages that affect the screen saver's operation as detailed in the Comments section.

If a screen saver application must perform a different action in response to any of these messages, the application's ScreenSaverProc window procedure should process the message.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message sent.

Comments

A screen saver application's ScreenSaverProc window procedure should use DefScreenSaverProc instead of the DefWindowProc function to provide default message processing. The DefScreenSaverProc function passes any messages that do not affect screen saver operation to DefWindowProc.

The following table describes how the DefScreenSaverProc processes a variety of window messages:

Message	Action
WM_ACTIVATE, WM_ACTIVATEAPP, WM_NCACTIVATE	Closes the screen saver if the wParam parameter is FALSE. A wParam value of FALSE indicates that the screen saver is losing the input focus. The screen saver is closed by sending a WM_CLOSE message.
WM_SETCURSOR	Removes the cursor from the screen by setting the cursor to NULL.
WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN, WM_KEYDOWN, WM_KEYUP, WM_MOUSEMOVE	Calls the PostQuitMessage function to close the screen saver.
WM_DESTROY	Posts a WM_CLOSE message to close the screen saver window.
WM_SYSCOMMAND	Returns FALSE if the wParam parameter of the WM_SYSCOMMAND message is either SC_SCREENSAVE or SC_CLOSE.
See Also

»ScreenSaverProc«


  DefWindowProc

LRESULT DefWindowProc(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of window */
UINT  uMsg;   /* message identifier */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The DefWindowProc function calls the default window procedure to provide default processing for any window messages that an application does not process. This function ensures that every message is processed. DefWindowProc is called with the same parameters received by the window procedure.

Parameters

hwnd

Identifies the window procedure that received the message.

uMsg

Specifies the message.

wParam

Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.

lParam

Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.

Return Value

The return value is the result of the message processing and depends on the message.

See Also

»CallWindowProc«, »DefDlgProc«, »WindowProc«


  DeleteAce

BOOL DeleteAce(pAcl, dwAceIndex)
PACL  pAcl;   /* address of access-control list */
DWORD  dwAceIndex;   /* index of ACE position in ACL */

The DeleteAce function deletes an ACE from an ACL.

An ACE is an access-control entry. An ACL is an access-control list.

Parameters

pAcl

Points to an ACL structure. The ACE specified by the dwAceIndex parameter is removed from this ACL.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwAceIndex

Specifies the ACE to delete. A value of 0 corresponds to the first ACE in the ACL, 1 to the second ACE, and so on.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can use the ACL_SIZE_INFORMATION structure retrieved by the GetAclInformation function to discover the size of the ACL and the number of ACEs it contains. The GetAce function retrieves information about an individual ACE.

See Also

»AddAccessAllowedAce«, »AddAccessDeniedAce«, »AddAce«, »AddAuditAccessAce«, »GetAce«, »GetAclInformation«


  DeleteAtom

ATOM DeleteAtom(atm)
ATOM  atm;   /* atom to delete */

The DeleteAtom function decrements the reference count of a local string atom. If the atom's reference count is reduced to zero, DeleteAtom removes the string associated with the atom from the local atom table.

Parameters

atm

Identifies the atom and character string to be deleted.

Return Value

If the function succeeds, the return value is zero; otherwise, it is the value of the atm parameter. To get extended error information, use the GetLastError function.

Comments

A string atom's reference count specifies the number of times the atom has been added to or removed from the atom table. The AddAtom function increments the count on each call. DeleteAtom decrements the count on each call but removes the string only if the atom's reference count is zero.

The only way to ensure that an atom has been deleted from the atom table is to call this function repeatedly until it fails. When the reference count is reduced to zero, the next call to the FindAtom or DeleteAtom function fails.

DeleteAtom has no effect on an integer atom (an atom created by using the MAKEINTATOM macro). The function always returns zero for an integer atom.

See Also

»AddAtom«, »FindAtom«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«, »MAKEINTATOM«


  DeleteCriticalSection

VOID DeleteCriticalSection(lpcsCriticalSection)
LPCRITICAL_SECTION  lpcsCriticalSection;   /* address of critical section object */

The DeleteCriticalSection function releases all resources used by an unowned critical section object.

Parameters

lpcsCriticalSection

Points to the critical section object.

Return Value

This function does not return a value.

Comments

Deleting a critical section object releases all system resources used by the object. Once deleted, the critical section object cannot be specified in the EnterCriticalSection or LeaveCriticalSection function.

See Also

»EnterCriticalSection«, »InitializeCriticalSection«, »LeaveCriticalSection«


  DeleteDC

BOOL DeleteDC(hdc)
HDC  hdc;   /* handle of device context */

The DeleteDC function deletes the given device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

An application must not delete a device context whose handle was obtained by calling the GetDC function. Instead, it must call the ReleaseDC function to free the device context.

See Also

»CreateDC«, »GetDC«, »ReleaseDC«


  DeleteEnhMetaFile

BOOL DeleteEnhMetaFile(hemf)
HENHMETAFILE  hemf;   /* handle of an enhanced metafile */

The DeleteEnhMetaFile function deletes an enhanced-format metafile or an enhanced-format metafile handle.

Parameters

hemf

Identifies an enhanced metafile.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

If the hemf parameter identifies an enhanced metafile stored in memory, this function deletes the metafile. If hemf identifies a metafile stored on a disk, the function deletes the metafile handle but does not destroy the actual metafile. An application can retrieve the file by calling the GetEnhMetaFile function.

See Also

»CopyEnhMetaFile«, »CreateEnhMetaFile«, »GetEnhMetaFile«


  DeleteFile

BOOL DeleteFile(lpszFileName)
LPTSTR  lpszFileName;   /* address of the name of the file to delete */

The DeleteFile function deletes an existing file.

Parameters

lpszFileName

Points to a null-terminated string that specifies the file to be deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If an application attempts to delete an open file or a file that does not exist, the DeleteFile function fails. Use the CloseHandle function to close an open file.

See Also

»CloseHandle«, »CreateFile«


  DeleteForm

BOOL DeleteForm(hPrinter, pFormName)
HANDLE  hPrinter;   /* handle of printer object */
LPTSTR  lpszFormName;   /* address of form name */

The DeleteForm function removes a form name from the list of supported forms.

Parameters

hPrinter

Indicates the open printer handle that this function is to be performed upon.

lpszFormName

Points to the form name to be removed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle is obtained by calling the OpenPrinter function. This function can delete only form names that were added by using the AddForm function.

See Also

»AddForm«


  DeleteMenu

BOOL DeleteMenu(hmenu, uItem, fuFlags)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item identifier or position */
UINT  fuFlags;   /* menu item flag */

The DeleteMenu function deletes an item from the given menu. If the menu item invokes a pop-up menu, this function destroys the handle of the pop-up menu and frees the memory used by the pop-up menu.

Parameters

hmenu

Identifies the menu to be changed.

uItem

Specifies the menu item to be deleted, as determined by the fuFlags parameter.

fuFlags

Specifies how the uItem parameter is interpreted. This parameter must be one of the following values:

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the menu item.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The application must call the DrawMenuBar function whenever a menu changes, whether or not the menu is in a displayed window.

See Also

»DrawMenuBar«, »RemoveMenu«


  DeleteMetaFile

BOOL DeleteMetaFile(hmf)
HMETAFILE  hmf;   /* handle of Windows-format metafile */

The DeleteMetaFile function deletes a Windows-format metafile or Windows-format metafile handle.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the DeleteEnhMetaFile function.

Parameters

hmf

Identifies a Windows-format metafile.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions, such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should use the enhanced format metafile functions.

If the metafile identified by the hmf parameter is stored in memory (rather than on a disk), its contents are lost when it is deleted by using the DeleteMetaFile function.

See Also

»BeginPath«, »CopyMetaFile«, »CreateMetaFile«, »GetMetaFile«, »PolyBezier«, »SetWorldTransform«


  DeleteMonitor

BOOL DeleteMonitor(pName, pEnvironment, pMonitorName)
LPTSTR  pName;   /* server name */
LPTSTR  pEnvironment;   /* environment string */
LPTSTR  pMonitorName;   /* monitor name */

The DeleteMonitor function removes a printer monitor added by the AddMonitor function.

Parameters

pName

Points to a null-terminated string that specifies the name of the server from which the monitor is to be removed. If this string is NULL, the printer monitor will be removed locally.

pEnvironment

Points to a null-terminated string that specifies the environment from which the monitor is to be removed (for example, "Windows NT x86", "Windows NT R4000", or "Windows NT Alpha_AXP"). If this string is NULL, the monitor is removed from the current environment of the caller/client (not of the destination/server).

pMonitorName

Points to a null-terminated string that specifies the name of the monitor to be removed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddMonitor«


  DeleteObject

BOOL DeleteObject(hObject)
HGDIOBJ  hObject;   /* handle of graphic object */

The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. After the object is deleted, the given handle is no longer valid.

Parameters

hObject

Identifies a logical pen, brush, font, bitmap, region, or palette.

Return Value

If the function succeeds, the return value is TRUE. If the given handle is not valid or is currently selected into a device context, the return value is FALSE.

Comments

The object to be deleted must not be currently selected into a device context.

When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be deleted independently.

See Also

»SelectObject«


  DeletePort

BOOL DeletePort(lpszName, hwnd, lpszPortName)
LPTSTR  lpszName;   /* address of server name */
HWND  hwnd;   /* handle of window that displays dialog box */
LPTSTR  lpszPortName;   /* address of port name */

The DeletePort function displays a dialog box that allows the user to delete a port name.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server for which the port should be deleted. If this string is NULL, a local port is deleted.

hwnd

Identifies the parent window of the port-deletion dialog box.

lpszPortName

Points to a null-terminated string that specifies the name of the port that should be deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can retrieve the names of valid ports by calling the EnumPorts function.

This function returns an error if a printer is currently connected to the specified port.

See Also

»AddPort«, »EnumPorts«


  DeletePrinter

BOOL DeletePrinter(hPrinter)
HANDLE  hPrinter;   /* handle of printer object */

The DeletePrinter function deletes the given printer object.

Parameters

hPrinter

Identifies a printer object that will be deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter is obtained by calling the OpenPrinter or AddPrinter function. Most users will use OpenPrinter.

If there are print jobs remaining to be processed for the given printer, DeletePrinter marks the printer for pending deletion, and then deletes it when all the print jobs have been printed. No print jobs can be added to a printer that is marked for pending deletion.

A printer marked for pending deletion cannot be held, but its print jobs can be held, resumed, and restarted. If the printer is held and there are jobs for the printer, DeletePrinter will fail with an InvalidState error.

See Also

»AddPrinter«, »EnumPrinters«,


  DeletePrinterDriver

BOOL DeletePrinterDriver(lpszName, lpszEnvironment, lpszDriverName)
LPTSTR  lpszName;   /* address of server name */
LPTSTR  lpszEnvironment;   /* address of environment */
LPTSTR  lpszDriverName;   /* address of driver name */

The DeletePrinterDriver function removes the specified printer-driver name from the list of names of supported drivers for the given server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server from which the driver is to be deleted. If this string is NULL, the printer-driver name will be removed locally.

lpszEnvironment

Points to a null-terminated string that specifies the environment from which the driver is to be deleted (for example, "Windows NT x86" or "Windows NT R4000"). If this string is NULL, the driver name is deleted from the current environment of the caller/client (not of the destination/server).

lpszDriverName

Points to a null-terminated string that specifies the name of the driver that should be deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function does not delete the associated files, it merely removes the driver-name from the list returned by the EnumPrinterDrivers function.

See Also

»EnumPrinterDrivers«


  DeletePrintProcessor

BOOL DeletePrintProcessor (pName, pEnvironment, pPrintProcessorName)
LPTSTR  pName;   /* server name */
LPTSTR  pEnvironment;   /* environment string */
LPTSTR  pPrintProcessorName;   /* processor name */

The DeletePrintProcessor function removes a printer processor added by the AddPrintProcessor function.

Parameters

pName

Points to a null-terminated string that specifies the name of the server from which the processor is to be removed. If this string is NULL, the printer processor will be removed locally.

pEnvironment

Points to a null-terminated string that specifies the environment from which the processor is to be removed (for example, "Windows NT x86", "Windows NT R4000", or "Windows NT Alpha_AXP"). If this string is NULL, the processor is removed from the current environment of the caller/client (not of the destination/server). NULL is the recommended value, as it provides maximum portability.

pPrintProcessorName

Points to a null-terminated string that specifies the name of the processor to be removed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrintProcessor«


  DeletePrintProvidor

BOOL DeletePrintProvidor (pName, pEnvironment, pPrintProvidorName)
LPTSTR  pName;   /* server name */
LPTSTR  pEnvironment;   /* environment string */
LPTSTR  pPrintProvidorName;   /* providor name */

The DeletePrintProvidor function removes a printer providor added by the AddPrintProvidor function.

Parameters

pName

Points to a null-terminated string that specifies the name of the server from which the providor is to be removed. If this string is NULL, the printer providor will be removed locally.

pEnvironment

Points to a null-terminated string that specifies the environment from which the providor is to be removed (for example, "Windows NT x86", "Windows NT R4000", or "Windows NT Alpha_AXP"). If this string is NULL, the providor is removed from the current environment of the caller/client (not of the destination/server). NULL is the recommended value, as it provides maximum portability.

pPrintProvidorName

Points to a null-terminated string that specifies the name of the providor to be removed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrintProvidor«


  DeleteService

BOOL DeleteService(schService)
SC_HANDLE  schService;   /* handle of service */

The DeleteService function marks the specified service for deletion from the service control manager database.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have DELETE access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Others may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with DELETE access.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_SERVICE_MARKED_FOR_DELETE
	The specified service has already been marked for deletion.
Comments

The DeleteService function marks a service for deletion from the service control manager database. The database entry is not removed until all open handles to the service have been closed by calls to the CloseServiceHandle function, and the service is not running. A running service is stopped by a call to the ControlService function with the SERVICE_CONTROL_STOP control code. If the service cannot be stopped, the database entry is removed when the system is rebooted.

The service control manager deletes the service by deleting the service key and its subkeys from the registry.

See Also

»CloseServiceHandle«, »ControlService«, »CreateService«, »OpenService«


  DeregisterEventSource

BOOL DeregisterEventSource(hEventLog)
HANDLE  hEventLog;   /* handle to event log */

The DeregisterEventSource function closes a handle returned by the RegisterEventSource function.

Parameters

hEventLog

Identifies the event log whose handle was returned by RegisterEventSource.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»RegisterEventSource«


  DestroyAcceleratorTable

BOOL DestroyAcceleratorTable(haccl)
HACCEL  haccl;   /* handle of accelerator table */

The DestroyAcceleratorTable function destroys an accelerator table. Before an application closes, it must use this function to destroy each accelerator table that it created by using the CreateAcceleratorTable function.

Parameters

haccl

Identifies the accelerator table to be destroyed. This handle must have been created by a previous call to the CreateAcceleratorTable function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CopyAcceleratorTable«, »CreateAcceleratorTable«, »LoadAccelerators«, »TranslateAccelerator«


  DestroyCaret

BOOL DestroyCaret(VOID)

The DestroyCaret function destroys the caret's current shape, frees the caret from the window, and removes the caret from the screen.

If the caret shape is based on a bitmap, DestroyCaret does not free the bitmap.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

DestroyCaret destroys the caret only if a window in the current task owns the caret. If a window that is not in the current task owns the caret, DestroyCaret does nothing and returns FALSE.

The caret is a shared resource; there is only one caret in the system. A window should create a caret only when it has the keyboard focus or is active. The window should destroy the caret before losing the keyboard focus or becoming inactive.

See Also

»CreateCaret«, »HideCaret«, »ShowCaret«


  DestroyCursor

BOOL DestroyCursor(hcur)
HCURSOR  hcur;   /* handle of cursor to destroy */

The DestroyCursor function destroys a cursor created by the CreateCursor function and frees any memory the cursor occupied. Do not use it to destroy a cursor that was not created with the CreateCursor function.

Parameters

hcur

Identifies the cursor to be destroyed. The cursor must not be in use.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreateCursor«


  DestroyIcon

BOOL DestroyIcon(hicon)
HICON  hicon;   /* handle of icon to destroy */

The DestroyIcon function destroys an icon created by the CreateIcon function and frees any memory the icon occupied. Do not use DestroyIcon to destroy an icon that was not created by the CreateIcon function.

Parameters

hicon

Identifies the icon to be destroyed. The icon must not be in use.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreateIcon«


  DestroyMenu

BOOL DestroyMenu(hmenu)
HMENU  hmenu;   /* handle of menu to destroy */

The DestroyMenu function destroys the given menu and frees any memory that the menu occupies.

Parameters

hmenu

Identifies the menu to be destroyed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before closing, an application must use this function to destroy a menu not assigned to a window. A menu that is assigned to a window is automatically destroyed when the application closes.

See Also

»CreateMenu«, »DeleteMenu«, »ModifyMenu«, »RemoveMenu«


  DestroyPrivateObjectSecurity

BOOL DestroyPrivateObjectSecurity(lppsdObject)
PSECURITY_DESCRIPTOR  *lppsdObject;   /* address of pointer to SD */

The DestroyPrivateObjectSecurity function deletes a protected server object's security descriptor. This security descriptor must have been created by a call to the CreatePrivateObjectSecurity function.

Parameters

lppsdObject

Points to a pointer to the SECURITY_DESCRIPTOR structure to be deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreatePrivateObjectSecurity«, »GetPrivateObjectSecurity«, »SetPrivateObjectSecurity«


  DestroyWindow

BOOL DestroyWindow(hwnd)
HWND  hwnd;   /* handle of window to destroy */

The DestroyWindow function destroys the given window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).

If the given window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.

The DestroyWindow function also destroys modeless dialog boxes created by the CreateDialog function.

Parameters

hwnd

Identifies the window to be destroyed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A thread cannot use the DestroyWindow function to destroy a window created by a different thread.

If the window being destroyed is a child window that does not have the WS_NOPARENTNOTIFY style, a WM_PARENTNOTIFY message is sent to the parent.

See Also

»CreateDialog«, »CreateWindow«, »CreateWindowEx«


  DeviceCapabilitiesEx

int DeviceCapabilitiesEx(lpDriverName, lpDeviceName, lpPort, iIndex, lpOutput, lpDevMode)
LPTSTR  lpDriverName;   /* address of driver name */
LPTSTR  lpDeviceName;   /* address of device name */
LPTSTR  lpPort;   /* address of port or file name */
int  iIndex;   /* index that identifies capability to be retrieved */
LPTSTR  lpOutput;   /* array receiving data */
LPDEVMODE  lpDevMode;   /* address of device mode structure */

The DeviceCapabilitiesEx function retrieves the requested capability of the specified printer or plotter.

Parameters

lpDriverName

Points to a null-terminated character string that specifies the name of the device driver (for example, "laser").

lpDeviceName

Points to a null-terminated character string that specifies the name of a device (for example, "duplex laser"). This parameter is used if the device driver supports multiple devices.

lpPort

Points to a null-terminated character string that specifies the file or device name (such as "LPT1") for the physical output medium.

iIndex

Specifies the capability to query. This parameter can be one of the following values:

Value	Meaning
DC_BINNAMES
	Specifies that the function enumerates the paper bins on the given device. If a device driver supports this constant, the array identified by lpOutput contains a data structure that contains two members. The first member is an array identifying valid paper bins:
short BinList[cBinMax]

	The second member is an array specifying the bin names:
char PaperNames[cBinMax][cchBinName]

	If a device driver does not support this value, the array identified by lpOutput is empty and the return value is NULL.
	If lpOutput is NULL, the return value specifies the number of bins supported.
DC_BINS
	Specifies that the function retrieves a list of constants that identify the available bins. The function copies the list to the array identified by lpOutput. If this array is NULL, the function returns the number of supported bins. Following are the bin identifiers that may be returned:
DMBIN_AUTO

DMBIN_CASSETTE

DMBIN_ENVELOPE

DMBIN_ENVMANUAL

DMBIN_FIRST

DMBIN_LARGECAPACITY

DMBIN_LARGEFMT

DMBIN_LAST

DMBIN_LOWER

DMBIN_MANUAL

DMBIN_MIDDLE

DMBIN_ONLYONE

DMBIN_SMALLFMT

DMBIN_TRACTOR

DMBIN_UPPER

DC_DRIVER
	Specifies that the function returns the driver version number.
DC_DUPLEX
	Specifies that the function returns the level of duplex support. The return value is 1 if the function supports duplex output; otherwise, it is zero.
DC_ENUMRESOLUTIONS
	Specifies that the function returns a list of available printer resolutions in the array identified by lpOutput. The resolutions are returned as pairs of LONG integers; the first pair specifies the horizontal resolution and the second pair specifies the vertical resolution.
	If lpOutput is NULL, the function returns the number of supported resolutions.
DC_EXTRA
	Specifies that the function returns the number of bytes required for the device-specific data appended to the DEVMODE structure.
DC_FIELDS
	Specifies that the function returns a value indicating which members of the DEVMODE structure are set by the device driver. This value can be one or more of the following constants:
DM_ORIENTATION

DM_PAPERSIZE

DM_PAPERLENGTH

DM_PAPERWIDTH

DM_SCALE

DM_COPIES

DM_DEFAULTSOURCE

DM_PRINTQUALITY

DM_COLOR

DM_DUPLEX

DM_YRESOLUTION

DM_TTOPTION

DC_FILEDEPENDENCIES
	Specifies that the function returns a list of files that must be loaded when the device driver is installed.
	If lpOutput is NULL and this value is specified, the function returns the number of filenames that must be loaded. If lpOutput is a valid pointer, the function returns the specified number of 64-character filenames.
DC_MAXEXTENT
	Specifies that the function returns the maximum supported paper size. These dimensions are returned in a POINT structure; the x member of this structure specifies the maximum paper width, and the y member of this structure specifies the maximum paper length.
DC_MINEXTENT
	Specifies that the function returns the minimum supported paper size. These dimensions are returned in a POINT structure; the x member of this structure specifies the minimum paper width, and the y member of this structure specifies the minimum paper length.
DC_PAPERS
	Specifies that the function returns a list of supported paper sizes. The paper sizes are returned in the array to which lpOutput points. The function return value specifies the number of sizes identified in the array.
	If lpOutput is NULL, the function returns the number of supported paper sizes.
DC_PAPERSIZE
	Specifies that the function returns the supported paper sizes in the array to which lpOutput points. These dimensions are specified in .1 millimeter units.
DC_SIZE
	Specifies that the function returns the size of the DEVMODE structure required by the device driver.
DC_VERSION
	Specifies that the function returns a version number identifying the specification to which the device driver conforms.
lpOutput

Points to an array of characters. The format of the array depends on the setting of iIndex. If lpOutput is set to zero, DeviceCapabilitiesEx returns the number of characters required for the output data.

lpDevMode

Points to a DEVMODE structure. If lpDevMode is NULL, this function retrieves the current default initialization values for the specified printer driver. Otherwise, the function retrieves the values contained in the structure to which lpDevMode points.

Return Value

If the function succeeds, the return value depends on the setting of the iIndex parameter; otherwise, the return value is GDI_ERROR.

See Also

»GetDeviceCaps«


  DeviceIoControl

BOOL DeviceIoControl(hDevice, dwIoControlCode, lpvInBuffer, cbInBuffer,
lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpoOverlapped)
HANDLE  hDevice;   /* handle of the device */
DWORD  dwIoControlCode;   /* control code of operation to perform */
LPVOID  lpvInBuffer;   /* address of buffer for input data */
DWORD  cbInBuffer;   /* size of input buffer */
LPVOID  lpvOutBuffer;   /* address of output buffer */
DWORD  cbOutBuffer;   /* size of output buffer */
LPDWORD  lpcbBytesReturned;   /* address of actual bytes of output */
LPOVERLAPPED  lpoOverlapped;   /* address of overlapped structure */

The DeviceIoControl function sends a control code directly to a given device driver, causing the device to perform the specified operation.

Parameters

hDevice

Identifies the device. The CreateFile function returns this handle.

dwIoControlCode

Specifies the control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. The following values are defined:

Value	Meaning
IOCTL_DISK_CHECK_VERIFY	Checks for change in removable-media device
IOCTL_DISK_EJECT_MEDIA	Ejects media from a SCSI device
IOCTL_DISK_FORMAT_TRACKS	Formats a contiguous set of disk tracks
IOCTL_DISK_GET_DRIVE_GEOMETRY	Obtain information on the physical disk's geometry
IOCTL_DISK_GET_DRIVE_LAYOUT	Provides info on each partition on a disk
IOCTL_DISK_GET_MEDIA_TYPES	Obtains information about media support
IOCTL_DISK_GET_PARTITION_INFO	Obtain disk partition information
IOCTL_DISK_LOAD_MEDIA	Loads media into a device
IOCTL_DISK_MEDIA_REMOVAL	Enables or disables media eject mechanism
IOCTL_DISK_PERFORMANCE	Provides disk performance information
IOCTL_DISK_REASSIGN_BLOCKS	Maps disk blocks to spare-block pool
IOCTL_DISK_SET_DRIVE_LAYOUT	Partitions a disk
IOCTL_DISK_SET_PARTITION_INFO	Set disk partition type
IOCTL_DISK_VERIFY	Performs logical format of a disk extent
IOCTL_SERIAL_LSRMST_INSERT	Enables or disables placement of line and modem status data into data stream
lpvInBuffer

Points to a buffer containing the data required to perform the operation. This parameter can be NULL if the dwIoControlCode parameter specifies an operation that does not require input data.

cbInBuffer

Specifies the size, in bytes, of the lpvInBuffer buffer.

lpvOutBuffer

Points to a buffer in which the operation's output data is returned. This parameter can be NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.

cbOutBuffer

Specifies the size, in bytes, of the lpvOutBuffer buffer.

lpcbBytesReturned

Points to a 32-bit variable that receives the actual size, in bytes, of the data returned in the lpvOutBuffer buffer.

lpoOverlapped

Points to an OVERLAPPED structure. This parameter is ignored if the hDevice handle was opened without specifying the FILE_FLAG_OVERLAPPED flag. This parameter can be NULL if overlapped operation is not desired. The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the lpoOverlapped parameter is NULL or the hDevice handle was opened without specifying the FILE_FLAG_OVERLAPPED flag, the DeviceIoControl function does not return until the operation has been completed, or an error occurs.

If the lpoOverlapped parameter points to an OVERLAPPED structure and the FILE_FLAG_OVERLAPPED flag was specified when hDevice handle was opened, DeviceIoControl is performed as an overlapped operation. In this case, the OVERLAPPED structure must contain a handle to a manual-reset event object (created by using the CreateEvent function).

If the overlapped operation cannot be completed immediately, the function returns FALSE and GetLastError returns ERROR_IO_PENDING, indicating that the operation is executing in the background. When this happens, the system sets the event object in the OVERLAPPED structure to the not-signaled state before DeviceIoControl returns, and then it sets it to the signaled state when the operation has been completed. The calling thread can use any of the wait functions to determine the event object's state, then use the GetOverlappedResult function to determine the results of the operation. GetOverlappedResult reports the success or failure of the operation and the number of bytes returned in the lpvOutBuffer buffer.

See Also

»CreateEvent«, »CreateFile«, »GetOverlappedResult«, »WaitForMultipleObjects«, »WaitForSingleObject«


  DialogBox

int DialogBox(hinst, lpszTemplate, hwndOwner, dlgprc)
HANDLE  hinst;   /* handle of application instance */
LPCTSTR  lpszTemplate;   /* identifies dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */

The DialogBox function creates a modal dialog box from a dialog box template resource. DialogBox does not return control until the given callback function terminates the modal dialog box by calling the EndDialog function.

Parameters

hinst

Identifies an instance of the module whose executable file contains the dialog box template.

lpszTemplate

Identifies the dialog box template. This parameter is either the address of a null-terminated character string that specifies the name of the dialog box template or an integer value that specifies the resource identifier of the dialog box template. If the parameter specifies a resource identifier, its high-order word must be zero and its low-order word must contain the identifier. You can use the MAKEINTRESOURCE macro to create this value.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

Return Value

If the function succeeds, the return value is the nResult parameter in the call to the EndDialog function used to terminate the dialog box; otherwise, the return value is −1.

Comments

The DialogBoxIndirect function uses the CreateWindowEx function to create the dialog box. DialogBox then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and finally starts its own message loop to retrieve and dispatch messages for the dialog box.

When the dialog box procedure calls the EndDialog function, DialogBox destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter given by the dialog procedure when it called EndDialog.

See Also

»CreateDialog«, »CreateWindowEx«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »DialogBoxParam«, »DialogProc«, »EndDialog«


  DialogBoxIndirect

int DialogBoxIndirect(hinst, hTemplate, hwndOwner, dlgprc)
HANDLE  hinst;   /* handle of application instance */
LPDLGTEMPLATE  hTemplate;   /* identifies dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */

The DialogBoxIndirect function creates a modal dialog box from a dialog box template in memory. The DialogBoxIndirect function does not return control until the given callback function terminates the modal dialog box by calling the EndDialog function.

Parameters

hinst

Identifies the instance of the module that creates the dialog box.

hTemplate

Identifies a global memory object that contains a dialog box template used to create the dialog box. This template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures. In Windows NT, this parameter can be either the handle to the global memory object or the address of the object.

The DLGTEMPLATE structure has the following form:

typedef struct { /* dltt */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  cdit;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

} DLGTEMPLATE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The DLGITEMTEMPLATE structure has the following form:

typedef struct { /* dlit */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

    WORD  id;

} DLGITEMTEMPLATE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

Return Value

If the function succeeds, the return value is the nResult parameter given in the call to the EndDialog function used to terminate the dialog box; otherwise, the return value is −1.

Comments

The DialogBoxIndirect function uses the CreateWindowEx function to create the dialog box. DialogBoxIndirect then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and finally starts its own message loop to retrieve and dispatch messages for the dialog box.

When the dialog box procedure calls the EndDialog function, DialogBoxIndirect destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter given by the dialog procedure when it called EndDialog.

See Also

»DialogBox«, »DialogBoxIndirectParam«, »DialogBoxParam«, »DialogProc«, »EndDialog«


  DialogBoxIndirectParam

int DialogBoxIndirectParam(hinst, hTemplate, hwndOwner, dlgprc, lParamInit)
HANDLE  hinst;   /* handle of application instance */
LPCDLGTEMPLATE  hTemplate;   /* identifies dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */
LPARAM  lParamInit;   /* initialization value */

The DialogBoxIndirectParam function creates a modal dialog box from a dialog box template in memory. Before displaying the dialog box, the function passes an application-defined value to the dialog box procedure as the lParam parameter of the WM_INITDIALOG message. An application can use this value to initialize dialog box controls.

Parameters

hinst

Identifies the instance of the module that creates the dialog box.

hTemplate

Identifies a global memory object that contains a dialog box template used to create the dialog box. This template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures. In Windows NT, this parameter can be either the handle of the global memory object or the address of the object.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

lParamInit

Specifies the value to pass to the dialog box in the lParam parameter of the WM_INITDIALOG message.

Return Value

If the function succeeds, the return value is the nResult parameter given in the call to the EndDialog function used to terminate the dialog box; otherwise, the return value is −1.

Comments

The DialogBoxIndirectParam function uses the CreateWindowEx function to create the dialog box. DialogBoxIndirectParam then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and finally starts its own message loop to retrieve and dispatch messages for the dialog box.

When the dialog box procedure calls the EndDialog function, DialogBoxIndirectParam destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter given by the dialog procedure when it called EndDialog.

See Also

»DialogBox«, »DialogBoxIndirect«, »DialogBoxParam«, »DialogProc«, »EndDialog«


  DialogBoxParam

int DialogBoxParam(hinst, lpszTemplate, hwndOwner, dlgprc, lParamInit)
HANDLE  hinst;   /* handle of application instance */
LPCTSTR  lpszTemplate;   /* identifies dialog box template */
HWND  hwndOwner;   /* handle of owner window */
DLGPROC  dlgprc;   /* address of dialog box procedure */
LPARAM  lParamInit;   /* initialization value */

The DialogBoxParam function creates a modal dialog box from a dialog box template resource. Before displaying the dialog box, the function passes an application-defined value to the dialog box procedure as the lParam parameter of the WM_INITDIALOG message. An application can use this value to initialize dialog box controls.

Parameters

hinst

Identifies an instance of the module whose executable file contains the dialog box template.

lpszTemplate

Identifies the dialog box template. This parameter is either the address of a null-terminated character string that specifies the name of the dialog box template or an integer value that specifies the resource identifier of the dialog box template. If the parameter specifies a resource identifier, its high-order word must be zero and its low-order word must contain the identifier. You can use the MAKEINTRESOURCE macro to create this value.

hwndOwner

Identifies the window that owns the dialog box.

dlgprc

Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the »DialogProc« callback function.

lParamInit

Specifies the value to pass to the dialog box in the lParam parameter of the WM_INITDIALOG message.

Return Value

If the function succeeds, the return value is the value of the nResult parameter given in the call to the EndDialog function used to terminate the dialog box; otherwise, the return value is −1.

Comments

The DialogBoxParam function uses the CreateWindowEx function to create the dialog box. DialogBoxParam then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT style) to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and finally starts its own message loop to retrieve and dispatch messages for the dialog box.

When the dialog box procedure calls the EndDialog function, DialogBoxParam destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter given by the dialog procedure when it called EndDialog.

See Also

»DialogBox«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »DialogProc«, »EndDialog«


  DialogProc

BOOL CALLBACK DialogProc(hwndDlg, uMsg, wParam, lParam)
HWND  hwndDlg;   /* handle of dialog box */
UINT  uMsg;   /* message */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The DialogProc function is an application-defined callback function that processes messages sent to a modal or modeless dialog box.

Parameters

hwndDlg

Identifies the dialog box.

uMsg

Specifies the message.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

Except in response to the WM_INITDIALOG message, the dialog box procedure should return nonzero if it processes the message, and zero if it does not. In response to a WM_INITDIALOG message, the dialog box procedure should return zero if it calls the SetFocus function to set the focus to one of the controls in the dialog box. Otherwise, it should return nonzero, in which case the system sets the focus to the first control in the dialog box that can be given the focus.

Comments

You should use the dialog box procedure only if you use the dialog box class for the dialog box. This is the default class and is used when no explicit class is given in the dialog box template. Although the dialog box procedure is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the dialog box window procedure.

DialogProc is a placeholder for the application-defined function name.

See Also

»CreateDialog«, »CreateDialogIndirect«, »CreateDialogIndirectParam«, »CreateDialogParam«, »DefWindowProc«, »DialogBox«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »DialogBoxParam«, »SetFocus«, »WM_INITDIALOG«


  DisconnectNamedPipe

BOOL DisconnectNamedPipe(hNamedPipe)
HANDLE  hNamedPipe;   /* handle of named pipe */

The DisconnectNamedPipe function disconnects the server end of a named pipe instance from a client process.

Parameters

hNamedPipe

Identifies an instance of a named pipe. This handle must be created by the CreateNamedPipe function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the client end of the named pipe is open, the DisconnectNamedPipe function forces that end of the named pipe closed. The client receives an error the next time it attempts to access the pipe. A client that is forced off a pipe by the DisconnectNamedPipe function must still use the CloseHandle function to close its end of the pipe.

When the server process disconnects a pipe instance, any unread data in the pipe is discarded. Before disconnecting, the server can make sure data is not lost by calling the FlushFileBuffers function, which does not return until the client process has read all the data.

The server process must call DisconnectNamedPipe to disconnect a pipe handle from its previous client before the handle can be connected to another client by calling the ConnectNamedPipe function.

See Also

»CloseHandle«, »ConnectNamedPipe«, »CreateNamedPipe«, »FlushFileBuffers«


  DispatchMessage

LONG DispatchMessage(lpmsg)
CONST MSG  *lpmsg;   /* address of structure with message */

The DispatchMessage function dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function.

Parameters

lpmsg

Points to an MSG structure that contains the message. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored.

Comments

The MSG structure must contain valid message values. If the lpmsg parameter points to a WM_TIMER message and the lParam parameter of the WM_TIMER message is not NULL, lParam points to a function that is called instead of the window procedure.

See Also

»GetMessage«, »PeekMessage«, »PostAppMessage«, »PostMessage«, »TranslateMessage«


  DlgDirList

int DlgDirList(hwndDlg, lpszPath, idListBox, idStaticPath, uFileType)
HWND  hwndDlg;   /* handle of dialog box with list box */
LPTSTR  lpszPath;   /* address of path or filename string */
int  idListBox;   /* identifier of list box */
int  idStaticPath;   /* identifier of static control */
UINT  uFileType;   /* file attributes to display */

The DlgDirList function fills the specified list box with the names of all files matching the specified path or filename.

Parameters

hwndDlg

Identifies the dialog box that contains the list box.

lpszPath

Points to a null-terminated string that contains the path or filename. DlgDirList modifies this string, which should be long enough to contain the modifications. For more information, see the Comments section.

idListBox

Specifies the identifier of a list box. If this parameter is zero, DlgDirList assumes that no list box exists and does not attempt to fill one.

idStaticPath

Specifies the identifier of the static control used for displaying the current drive and directory. If this parameter is zero, DlgDirList assumes that no such control is present.

uFileType

Specifies attributes of the filenames to be displayed. This parameter must be one or more of the following values:

Value	Description
DDL_ARCHIVE	Includes archived files.
DDL_DIRECTORY	Includes subdirectories. Subdirectory names are enclosed in square brackets ([ ]).
DDL_DRIVES	Includes drives. Drives are listed in the form [-x-], where x is the drive letter.
DDL_EXCLUSIVE	Includes only files with the specified attributes. By default, read-write files are listed even if DDL_READWRITE is not specified.
DDL_HIDDEN	Includes hidden files.
DDL_READONLY	Includes read-only files.
DDL_READWRITE	Includes read-write files with no additional attributes.
DDL_SYSTEM	Includes system files.
DDL_POSTMSGS	Posts messages to the application's message queue. By default, the DlgDirList function sends messages directly to the dialog box procedure.
Return Value

If a listing is made — even an empty listing — the return value is nonzero. If the input string does not contain a valid search path, the return value is zero.

Comments

If you specify a zero-length string for the lpszPath parameter or if you specify only a directory name with no filename, the string will be changed to *.*

The lpszPath parameter has the following form:

[drive:] [[\u]directory[\idirectory]\u] [filename]

In this example, drive is a drive letter, directory is a valid directory name, and filename is a valid filename that must contain at least one wildcard (? or *).

If the lpszPath parameter includes a drive or directory name, or both, the current drive and directory are changed to the specified drive and directory before the list box is filled. The static control identified by the idStaticPath parameter is also updated with the new drive or directory name, or both.

After the list box is filled, DlgDirList updates lpszPath by removing the drive or directory portion, or both, of the path and filename.

DlgDirList sends the LB_RESETCONTENT and LB_DIR messages to the list box.

See Also

»DlgDirListComboBox«, »DlgDirSelectComboBoxEx«, »DlgDirSelectEx«


  DlgDirListComboBox

int DlgDirListComboBox(hwndDlg, lpPathSpec, nIDComboBox, nIDStaticPath, uFiletype)
HWND  hwndDlg;   /* handle of dialog box with combo box */
LPTSTR  lpPathSpec;   /* address of path or filename string */
int  nIDComboBox;   /* identifier of combo box */
int  nIDStaticPath;   /* identifier of static control */
UINT  uFiletype;   /* file attributes to display */

The DlgDirListComboBox function fills the specified combo box with a directory listing. It fills the list with the names of all files, drives, and subdirectories that match the specified attributes and path string.

Parameters

hwndDlg

Identifies the dialog box that contains the combo box.

lpPathSpec

Points to a null-terminated string of the following form:

[drive:][\]][directory\[...]][filename]

If the specified string includes a drive or directory path, the DlgDirListComboBox function changes the current drive and directory before filling the list. After the list is filled, the drive and directory path are removed from the lpPathSpec string.

nIDComboBox

Specifies the identifier of a combo box control in a dialog box. If nIDComboBox is zero, the DlgDirListComboBox function assumes no combo box exists and does not attempt to fill it.

nIDStaticPath

Specifies the identifier of the static text control in which the DlgDirListComboBox function is to display the current directory. If nIDStaticPath is zero, DlgDirListComboBox assumes no such control is present.

uFiletype

Specifies the attributes of the files to be displayed. It can be any combination of the following values:

Value	Description
DDL_ARCHIVE	Includes archived files.
DDL_DIRECTORY	Includes subdirectories. Subdirectory names are enclosed in square brackets ([ ]).
DDL_DRIVES	Includes drives. Drives are listed in the form [-x-], where x is the drive letter.
DDL_EXCLUSIVE	Includes only files with the specified attributes. By default, read-write files are listed even if DDL_READWRITE is not specified.
DDL_HIDDEN	Includes hidden files.
DDL_READONLY	Includes read-only files.
DDL_READWRITE	Includes read-write files with no additional attributes.
DDL_SYSTEM	Includes system files.
DDL_POSTMSGS	Posts messages to the application's message queue. By default, the DlgDirList function sends messages directly to the dialog box procedure.
Return Value

If the function succeeds, the return value is nonzero; otherwise, it is zero. For example, if the string specified by lpPathSpec is not a valid path, the function fails. To get extended error information, use the GetLastError function.

Comments

If the lpszPath parameter points to a zero-length string or to a string specifying a drive, directory, or both — but no filename — the filename *.* is assumed.

See Also

»DlgDirList«, »DlgDirSelectEx«, »DlgDirSelectComboBoxEx«


  DlgDirSelect

The DlgDirSelect function has been deleted. Win32 applications should use the DlgDirSelectEx function.

See Also

»DlgDirSelectEx«


  DlgDirSelectComboBox

The DlgDirSelectComboBox function has been deleted. Win32 applications should use the DlgDirSelectComboBoxEx function.

See Also

»DlgDirSelectComboBoxEx«


  DlgDirSelectComboBoxEx

BOOL DlgDirSelectComboBoxEx(hwndDlg, lpszPath, cchString, nIDComboBox)
HWND  hwndDlg;   /* handle of dialog box with list box */
LPTSTR  lpszPath;   /* address of buffer for path string */
int  cchString;   /* number of characters in path string */
int  nIDComboBox;   /* identifier of combo box */

The DlgDirSelectComboBoxEx function retrieves the current selection from a combo box filled by using the DlgDirListComboBox function. The selection is interpreted as a drive letter, a file, or a directory name.

Parameters

hwndDlg

Identifies the dialog box that contains the combo box.

lpszPath

Points to the buffer that is to receive the selected path.

cchString

Specifies the length, in characters, of the buffer pointed to by the lpszPath parameter.

nIDComboBox

Specifies the integer ID of the combo box control in the dialog box.

Return Value

If the current selection is a directory name, the return value is nonzero; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

If the current selection specifies a directory name or drive letter, the DlgDirSelectComboBoxEx function removes the enclosing square brackets (and hyphens for drive letters) so the name or letter is ready to be inserted into a new path or filename. If there is no selection, the contents of the buffer pointed to by the lpszPath parameter do not change.

The DlgDirSelectComboBox function does not allow more than one filename to be returned from a combo box.

DlgDirSelectComboBoxEx sends CB_GETCURSEL and CB_GETLBTEXT messages to the combo box.

In the Win32 API, you can use this function with all three types of combo boxes (CBS_SIMPLE, CBS_DROPDOWN, and CBS_DROPDOWNLIST).

See Also

»DlgDirSelectEx«, »DlgDirListComboBox«


  DlgDirSelectEx

BOOL DlgDirSelectEx(hwndDlg, lpString, cchString, nIDListBox)
HWND  hwndDlg;   /* handle of dialog box with list box */
LPTSTR  lpString;   /* address of buffer for path string */
int  cchString;   /* number of characters in path string */
int  nIDListBox;   /* identifier of list box */

The DlgDirSelectEx function retrieves the current selection from a single-selection list box. It assumes that the list box has been filled by the DlgDirList function and that the selection is a drive letter, filename, or directory name.

Parameters

hwndDlg

Identifies the dialog box that contains the list box.

lpString

Points to a buffer that is to receive the selected path.

cchString

Specifies the length, in characters, of the buffer pointed to by lpString.

nIDListBox

Specifies the integer identifier of a list box in the dialog box.

Return Value

If the current selection is a directory name, the return value is nonzero; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The DlgDirSelectEx function copies the selection to the buffer pointed to by the lpString parameter. If the current selection is a directory name or drive letter, DlgDirSelectEx removes the enclosing square brackets (and hyphens, for drive letters) so that the name or letter is ready to be inserted into a new path. If there is no selection, lpString does not change.

DlgDirSelectEx sends LB_GETCURSEL and LB_GETTEXT messages to the list box.

The DlgDirSelectEx function does not allow more than one filename to be returned from a list box. The list box must not be a multiple-selection list box. If it is, this function does not return a zero value and lpString remains unchanged.

See Also

»DlgDirList«, »DlgDirSelectComboBoxEx«, »DlgDirListComboBox«


  DllEntryPoint

BOOL WINAPI DllEntryPoint(hinstDLL, fdwReason, lpvReserved)
HINSTANCE  hinstDLL;   /* handle of DLL module */
DWORD  fdwReason;   /* why function was called */
LPVOID  lpvReserved;   /* reserved; must be NULL */

The DllEntryPoint function is an optional method of entry into a Dynamic-Link Library (DLL) that, if provided, is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions. DllEntryPoint is a placeholder for the library-defined function name. The actual name must be specified on the linker command line by the hyphen entry switch.

Parameters

hinstDLL

Supplies a handle to the DLL. This handle can be used in subsequent calls to the GetModuleFileName function and other module functions.

fdwReason

Supplies a flag indicating why the DLL entry routine is being called. This value can be one of the following values:

Value	Meaning
DLL_PROCESS_ATTACH
	Indicates the DLL is attaching to the address space of the current process as a result of the process starting up or a call to LoadLibrary. DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.
	During initial process startup or after a call to LoadLibrary, the operating system scans the list of loaded DLLs for the process. For each DLL that has not already been called with a DLL_PROCESS_ATTACH flag, the system calls the DLL's entrypoint function. This call is made in the context of the thread that caused the process address space to change, such as the primary thread of the process or the thread that called LoadLibrary.
DLL_THREAD_ATTACH
	Indicates the current process is creating a new thread. When this occurs, the system calls the entrypoint of all DLLs currently attached to the process. The call is made in the context of the new thread. DLLs can use this opportunity to initialize a TLS slot for the thread. The thread calling the DLL entrypoint with the DLL_PROCESS_ATTACH flag does not call the DLL entrypoint with the DLL_THREAD_ATTACH flag.
	Note that a DLL's entrypoint is called with this flag value only by threads created after the DLL is attached to the process. When a DLL is attached by LoadLibrary, existing threads do not call the entrypoint of the newly loaded DLL.
DLL_THREAD_DETACH
	Indicates a thread is exiting cleanly. If the DLL has stored a pointer to allocated memory in a TLS slot, it uses this opportunity to free the memory. The operating system calls the entrypoint of all currently loaded DLLs with this flag value. The call is made in the context of the exiting thread. There are cases in which the entrypoint is invoked for a terminating thread even if the DLL never attached to the thread. For example, the entrypoint was never called with the DLL_THREAD_ATTACH flag in the context of the thread. This can occur in two situations:
•	The thread was the initial thread in the process so the system called the entrypoint with the DLL_PROCESS_ATTACH flag.

•	The thread was already running when a LoadLibrary call was made, so the system never called the entrypoint function for it.

DLL_PROCESS_DETACH
	Indicates the DLL is detaching from the address space of the calling process. This results from either a clean process exit, or from a FreeLibrary call. The DLL can use this opportunity to call the TlsFree function to free any TLS indices allocated by using TlsAlloc and to free any thread local data. When a DLL detaches from a process as a result of process termination, or FreeLibrary, the operating system does not call the DLL's entrypoint with the DLL_THREAD_DETACH flag for the individual threads of the process. The only notification given to the DLL is the DLL_PROCESS_DETACH notification. DLLs can take this opportunity to clean up all resources for all threads attached and known to the DLL.
lpvReserved

Specifies further aspects of DLL initialization and cleanup.

If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads, and non-NULL for static loads.

If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllEntryPoint has been called via FreeLibrary, and non-NULL if DllEntryPoint has been called during process termination.

Return Value

When the system calls the DllEntryPoint function with the DLL_PROCESS_ATTACH flag, the function returns TRUE if it succeeds or FALSE if the initialization fails. If the return value is FALSE when the DllEntryPoint was invoked because the process called the LoadLibrary function, LoadLibrary returns NULL. If the return value is FALSE when the DllEntryPoint is called during process initialization, the process terminates with an error. To get extended error information, use the GetLastError function.

When the system calls the DllEntryPoint function with any flag other than DLL_PROCESS_ATTACH, the return value is ignored.

See Also

»FreeLibrary«, »GetModuleFileName«, »LoadLibrary«, »TlsAlloc«


  DocumentProperties

LONG DocumentProperties(hwnd, hPrinter, lpszDeviceName, pdmOutput, pdmInput, fMode)
HWND  hwnd;   /* handle of window that displays dialog box */
HANDLE  hPrinter;   /* handle of printer object */
LPTSTR  pDeviceName;   /* address of device name */
PDEVMODE  pdmOutput;   /* address of modified device mode structure */
PDEVMODE  pdmInput;   /* address of original device mode structure */
DWORD  fMode;   /* mode flag */

The DocumentProperties function displays a printer-configuration dialog box for the given printer.

Parameters

hwnd

Identifies the parent window of the printer-configuration dialog box.

hPrinter

Identifies a printer object.

pDeviceName

Points to a null-terminated string that specifies the name of the device for which the printer-configuration dialog box should be displayed.

pdmOutput

Points to a DEVMODE structure that receives the printer configuration data specified by the user. The DEVMODE structure has the following form:

typedef struct _devicemode {    /* dvmd */

    TCHAR  dmDeviceName[32];

    WORD   dmSpecVersion;

    WORD   dmDriverVersion;

    WORD   dmSize;

    WORD   dmDriverExtra;

    DWORD  dmFields;

    short  dmOrientation;

    short  dmPaperSize;

    short  dmPaperLength;

    short  dmPaperWidth;

    short  dmScale;

    short  dmCopies;

    short  dmDefaultSource;

    short  dmPrintQuality;

    short  dmColor;

    short  dmDuplex;

    short  dmYResolution;

    short  dmTTOption;

    short  dmCollate;

    TCHAR  dmFormName[32];

    WORD   dmUnusedPadding;

    USHORT dmBitsPerPel;

    DWORD  dmPelsWidth;

    DWORD  dmPelsHeight;

    DWORD  dmDisplayFlags;

    DWORD  dmDisplayFrequency;

} DEVMODE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

pdmInput

Points to a DEVMODE structure used to initialize the dialog box controls.

fMode

Specifies a mask of values that determines the operations the function performs. If this parameter is zero, the DocumentProperties function returns the number of bytes required by the printer driver's DEVMODE data structure. Otherwise, use one or more of the following constants to construct a value for this parameter; note, however, that in order to change the print settings, an application must specify at least one input value and one output value :

Value	Meaning
DM_IN_BUFFER	Input value. Before prompting, copying, or updating, the function will merge the printer driver's current print settings with the settings in the DEVMODE structure specified by the pdmInput parameter. The structure is updated only for those members specified by the DEVMODE structure's dmFields member. This value is also defined as DM_MODIFY.
DM_IN_PROMPT	Input value. The function will present the printer driver's Print Setup dialog box, then change the settings in the printer's DEVMODE data structure to those values specified by the user. This value is also defined as DM_PROMPT.
DM_OUT_BUFFER	Output value. The function will write the printer driver's current print settings, including private data, to the DEVMODE data structure specified by the pdmOutput parameter. The caller must allocate a buffer sufficiently large to contain the information. If the bit DM_OUT_BUFFER sets is clear, the pdmOutput parameter can be NULL. This value is also defined as DM_COPY.
Return Value

If the fMode parameter is zero, the return value is the size of the buffer required to contain the printer driver initialization data. Note that this buffer can be larger than a DEVMODE structure if the printer driver appends private data to the structure.

If the function displays the initialization dialog box, the return value is either IDOK or IDCANCEL, depending on which button the user selects.

If the function does not display the dialog box and is successful, the return value is IDOK.

The return value is less than zero if the function fails.

Comments

The printer-object handle hPrinter can be obtained by calling the OpenPrinter function.

The string pointed to by pDeviceName can be obtained by calling the GetPrinter function.

In order to make changes to print settings that are local to an application, the application should:

•	Call the DocumentProperties function, specifying the DM_OUT_BUFFER value

•	Modify the returned DEVMODE structure

•	Then pass the modified DEVMODE structure back by calling the DocumentProperties function, specifying both DM_IN_BUFFER and DM_OUT_BUFFER (which are combined using the OR operator).

The DEVMODE structure returned by the second call to the DocumentProperties function can be used as an argument in a call to the CreateDC function.

An application can obtain a DEVMODE structure filled with the printer driver's initialization data by specifying DM_OUT_BUFFER. The application can then pass this structure on to the CreateDC function to set a private environment for the printer device context.

See Also

»AdvancedDocumentProperties«, »CreateDC«, »GetPrinter«, »OpenPrinter«


  DOS3Call

The DOS3Call function is obsolete. Win32 applications cannot call MS-DOS directly.


  DosDateTimeToFileTime

BOOL DosDateTimeToFileTime(wDOSDate, wDOSTime, lpft)
WORD  wDOSDate;   /* 16-bit MS-DOS date */
WORD  wDOSTime;   /* 16-bit MS-DOS time */
LPFILETIME  lpft;   /* address of buffer for 64-bit file time */

The DosDateTimeToFileTime function converts MS-DOS date and time values to a 64-bit file time.

Parameters

wDOSDate

Specifies the MS-DOS date. The date is a packed 16-bit value with the following format:

Bits	Contents
0−4	Day of the month (1−31)
5−8	Month (1 = January, 2 = February, etc.)
9−15	Year offset from 1980 (add 1980 to get actual year)
wDOSTime

Specifies the MS-DOS time. The time is a packed 16-bit value with the following format:

Bits	Contents
0−4	Second divided by 2
5−10	Minute (0−59)
11−15	Hour (0−23 on a 24-hour clock)
lpft

Points to a FILETIME structure to receive the converted 64-bit file time.

The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»FileTimeToDosDateTime«, »FileTimeToSystemTime«, »SystemTimeToFileTime«


  DPtoLP

BOOL DPtoLP(hdc, lpPoints, nCount)
HDC  hdc;   /* handle of device context */
LPPOINT  lpPoints;   /* address of array of points */
int  nCount;   /* count of points */

The DPtoLP function converts device coordinates into logical coordinates. The conversion depends on the mapping mode of the device context (DC), the settings of the origins and extents for the window and viewport, and the world transformation.

Parameters

hdc

Identifies the DC.

lpPoints

Points to an array of POINT structures. The x- and y-coordinates contained in each POINT structure will be transformed. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

nCount

Specifies the number of points in the array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function fails if the device coordinates exceed 27 bits, or if the converted logical coordinates exceed 32 bits. In the case of such an overflow, the results for all the points are undefined.

See Also

»LPtoDP«


  DragAcceptFiles

VOID DragAcceptFiles(hWnd, fAccept)
HWND  hWnd;   /* handle of the registering window */
BOOL  fAccept;   /* acceptance option */

The DragAcceptFiles function registers whether a window accepts dropped files.

Parameters

hWnd

Identifies the window registering whether it accepts dropped files.

fAccept

Specifies whether the window identified by the hWnd parameter accepts dropped files. This value is TRUE to accept dropped files; it is FALSE to discontinue accepting dropped files.

Return Value

This function does not return a value.

Comments

An application that calls DragAcceptFiles with the fAccept parameter set to TRUE has identified itself as able to process the WM_DROPFILES message from File Manager.


  DragFinish

VOID DragFinish(hDrop)
HDROP  hDrop;   /* handle of memory to free */

The DragFinish function releases memory that Windows allocated for use in transferring filenames to the application.

Parameters

hDrop

Identifies the structure describing dropped files. This handle is retrieved from the wParam parameter of the WM_DROPFILES message.

Return Value

This function does not return a value.


  DragQueryFile

UINT DragQueryFile(hDrop, iFile, lpszFile, cb)
HDROP  hDrop;   /* handle of structure for dropped files */
UINT  iFile;   /* index of file to query */
LPTSTR  lpszFile;  /* buffer for returned filename */
UINT  cb;   /* size of buffer for filename */

The DragQueryFile function retrieves the filenames of dropped files.

Parameters

hDrop

Identifies the structure containing the filenames of the dropped files.

iFile

Specifies the index of the file to query. If the value of the iFile parameter is 0xFFFFFFFF, DragQueryFile returns a count of the files dropped. If the value of the iFile parameter is between zero and the total number of files dropped, DragQueryFile copies the filename with the corresponding value to the buffer pointed to by the lpszFile parameter.

lpszFile

Points to a buffer to receive the filename of a dropped file when the function returns. This filename is a null-terminated string. If this parameter is NULL, DragQueryFile returns the required size, in characters, of the buffer.

cb

Specifies the size, in characters, of the lpszFile buffer.

Return Value

When the function copies a filename to the buffer, the return value is a count of the characters copied. If the index value is 0xFFFF, the return value is a count of the dropped files. If the index value is between zero and the total number of dropped files and the buffer address is NULL, the return value is the required size, in characters, of the buffer.

See Also

»DragQueryPoint«


  DragQueryPoint

BOOL DragQueryPoint(hDrop, lppt)
HDROP  hDrop;   /* handle of structure for dropped file */
LPPOINT  lppt;   /* address of structure for mouse coordinates */

The DragQueryPoint function retrieves the position of the mouse pointer at the time a file was dropped.

Parameters

hDrop

Identifies the structure describing the dropped file.

lppt

Points to a POINT structure that the function fills with the coordinates of the mouse pointer at the time the file was dropped.

The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the drop occurred in the client area of the window, the return value is TRUE; otherwise, it is FALSE.

The DragQueryPoint function fills the POINT structure with the coordinates of the mouse pointer at the time the user released the left mouse button. The window for which coordinates are returned is the window that received the WM_DROPFILES message.

See Also

»DragQueryFile«


  DrawEscape

int DrawEscape(hdc, nEscape, cbInput, lpszInData)
HDC  hdc;   /* handle of device context */
int  nEscape;   /* specifies escape function */
int  cbInput;   /* size of structure for input */
LPCSTR  lpszInData;   /* address of structure for input */

The DrawEscape function accesses drawing capabilities of a video display that are not directly available through the graphics device interface (GDI).

Parameters

hdc

Identifies the device context for the specified video display.

nEscape

Specifies the escape function to be performed.

cbInput

Specifies the number of bytes of data pointed to by the lpszInData parameter.

lpszInData

Points to the input structure required for the specified escape.

Return Value

The return value specifies the outcome of the function. It is greater than zero if the function is successful, except for the QUERYESCSUPPORT draw escape, which checks for implementation only. The return value is zero if the escape is not implemented. The return value is less than zero if an error occurred. Use the GetLastError function to obtain extended error information.

Comments

When an application calls the DrawEscape function, the data identified by cbInput and lpszInData is passed directly to the specified display driver.


  DrawFocusRect

BOOL DrawFocusRect(hdc, lprc)
HDC  hdc;   /* handle of device context */
CONST RECT  *lprc;   /* address of structure with rectangle */

The DrawFocusRect function draws a rectangle in the style used to indicate that the rectangle has the focus.

Parameters

hdc

Identifies the device context.

lprc

Points to a RECT structure that specifies the logical coordinates of the rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Because DrawFocusRect is an XOR function, calling it a second time with the same rectangle removes the rectangle from the screen.

The rectangle this function draws cannot be scrolled. To scroll an area containing a rectangle drawn by this function, call DrawFocusRect to remove the rectangle from the screen, scroll the area, and then call DrawFocusRect to draw the rectangle in the new position.

See Also

»FrameRect«


  DrawIcon

BOOL DrawIcon(hdc, X, Y, hicon)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of upper left corner */
int  Y;   /* y-coordinate of upper left corner */
HICON  hicon;   /* handle of icon to draw */

The DrawIcon function draws an icon in the client area of the window of the given device context.

Parameters

hdc

Identifies the device context for a window.

X

Specifies the logical x-coordinate of the upper left corner of the icon.

Y

Specifies the logical y-coordinate of the upper left corner of the icon.

hicon

Identifies the icon to be drawn. The icon resource must have been previously loaded by using the LoadIcon function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

DrawIcon places the icon's upper left corner at the location specified by the X and Y parameters. The location is subject to the current mapping mode of the device context.

See Also

»CreateIcon«, »LoadIcon«, »OpenIcon«


  DrawMenuBar

BOOL DrawMenuBar(hwnd)
HWND  hwnd;   /* handle of window with menu bar to redraw */

The DrawMenuBar function redraws the menu bar of the given window. If the menu bar changes after Windows has created the window, this function must be called to draw the changed menu bar.

Parameters

hwnd

Identifies the window whose menu bar needs redrawing.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AppendMenu«, »DeleteMenu«, »InsertMenu«, »ModifyMenu«, »RemoveMenu«


  DrawText

int DrawText(hdc, lpszStr, cchStr, lprc, wFormat)
HDC  hdc;   /* handle of device context */
LPCTSTR  lpszStr;   /* address of string to draw */
int  cchStr;   /* string length, in characters */
LPRECT  lprc;   /* address of structure with formatting dimensions */
UINT  wFormat;   /* text-drawing flags */

The DrawText function draws formatted text in the specified rectangle. It formats the text according to the specified method (expanding tabs, justifying characters, breaking lines, and so forth).

Parameters

hdc

Identifies the device context.

lpszStr

Points to the string to be drawn. If the cchStr parameter is −1, the string must be null-terminated.

cchStr

Specifies the number of characters in the string. If cchStr is −1, then the lpszStr parameter is assumed to be a pointer to a null-terminated string and DrawText computes the character count automatically.

lprc

Points to a RECT structure that contains the rectangle (in logical coordinates) in which the text is to be formatted. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

wFormat

Specifies the method of formatting the text. It can be any combination of the following values:

Value	Description
DT_BOTTOM	Bottom justifies text. This value must be combined with DT_SINGLELINE.
DT_CALCRECT	Determines the width and height of the rectangle. If there are multiple lines of text, DrawText uses the width of the rectangle pointed to by the lprc parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, DrawText returns the height of the formatted text but does not draw the text.
DT_CENTER	Centers text horizontally.
DT_EXPANDTABS	Expands tab characters. The default number of characters per tab is eight.
DT_EXTERNALLEADING	Includes the font external leading in line height. Normally, external leading is not included in the height of a line of text.
DT_LEFT	Aligns text to the left.
DT_NOCLIP	Draws without clipping. DrawText is somewhat faster when DT_NOCLIP is used.
DT_NOPREFIX	Turns off processing of prefix characters. Normally, DrawText interprets the mnemonic-prefix character & as a directive to underscore the character that follows, and the mnemonic-prefix characters && as a directive to print a single &. By specifying DT_NOPREFIX, this processing is turned off.
DT_RIGHT	Aligns text to the right.
DT_SINGLELINE	Displays text on a single line only. Carriage returns and linefeeds do not break the line.
DT_TABSTOP	Sets tab stops. Bits 15−8 (high-order byte of the low-order word) of the wFormat parameter specify is the number of characters for each tab. The default number of characters per tab is eight.
DT_TOP	Top justifies text (single line only).
DT_VCENTER	Centers text vertically (single line only).
DT_WORDBREAK	Breaks words. Lines are automatically broken between words if a word would extend past the edge of the rectangle specified by the lprc parameter. A carriage return-linefeed sequence also breaks the line.
Note that the DT_CALCRECT, DT_EXTERNALLEADING, DT_INTERNAL, DT_NOCLIP, and DT_NOPREFIX values cannot be used with the DT_TABSTOP value.

Return Value

If the function succeeds, the return value is the height of the text.

Comments

The DrawText function uses the device context's selected font, text color, and background color to draw the text. Unless the DT_NOCLIP format is used, DrawText clips the text so that it does not appear outside the given rectangle. All formatting is assumed to have multiple lines unless the DT_SINGLELINE format is specified.

If the selected font is too large for the specified rectangle, the DrawText function does not attempt to substitute a smaller font.

See Also

»GrayString«, »TabbedTextOut«, »TextOut«


  DuplicateHandle

BOOL DuplicateHandle(hSourceProcess, hSource, hTargetProcess, lphTarget, fdwAccess,
fInherit, fdwOptions)
HANDLE  hSourceProcess;   /* handle of process to duplicate from */
HANDLE  hSource;   /* handle to duplicate */
HANDLE  hTargetProcess;   /* handle of process to duplicate to */
LPHANDLE  lphTarget;   /* address of duplicate handle */
DWORD  fdwAccess;   /* access for duplicate handle */
BOOL  fInherit;   /* handle inherited by child process? */
DWORD  fdwOptions;   /* optional actions */

The DuplicateHandle function duplicates an object handle.

Parameters

hSourceProcess

Identifies the process containing the handle to duplicate. The handle must have PROCESS_DUP_HANDLE access.

hSource

Identifies the handle to duplicate. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles can be duplicated, refer to the Comments section.

hTargetProcess

Identifies the process that is to receive the duplicated handle. The handle must have PROCESS_DUP_HANDLE access.

lphTarget

Points to a variable receiving the value of the duplicate handle. This handle value is valid in the context of the target process.

This parameter can be NULL. A NULL value is useful when the function's effects are desired, but the caller has no interest in a duplicate handle.

fdwAccess

Specifies the access requested for the new handle. This parameter is ignored if the fdwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on the type of object whose handle is being duplicated. For the flags that can be specified for each object type, see the Comments section. Note that the new handle can have more access than the original handle.

fInherit

Indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the target process. If FALSE, the new handle cannot be inherited.

fdwOptions

Specifies optional actions. This parameter can be zero, or any combination of the following flags:

Value	Meaning
DUPLICATE_CLOSE_SOURCE	Close the source handle. This occurs regardless of any error status returned.
DUPLICATE_SAME_ACCESS	Ignore the fdwAccess parameter. The duplicate handle has the same access as the source handle.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The DuplicateHandle function can be called by either the source process or the target process. It can also be invoked where the source and target process are the same. For example, a process can use DuplicateHandle to create a noninheritable duplicate of an inheritable handle, or a handle with different access than the original handle.

The duplicating process uses the GetCurrentProcess function to get a handle of itself. To get the other process handle, it may be necessary to use some form of interprocess communication (for example, named pipe, shared memory) to communicate the process ID to the duplicating process. This ID is then used in the OpenProcess function to open a handle.

If the process that calls DuplicateHandle is not the target process, the duplicating process must use interprocess communication (for example, named pipe, shared memory) to pass the value of the duplicate handle to the target process.

The duplicate handle is the same object handle as the source handle. This means that the state of the object is the same for both handles. For example, the current file mark for a file handle is always the same for both handles.

DuplicateHandle can duplicate handles to the following types of objects:

Object	Description
Console input
	The handle is returned by the CreateFile function when "CONIN$" is specified, or by the GetStdHandle function when STD_INPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.
Console screen buffer
	The handle is returned by the CreateFile function when "CONOUT$" is specified, or by the GetStdHandle function when STD_OUTPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.
Event
	The handle is returned by the CreateEvent or OpenEvent function.
File or communications device
	The handle is returned by the CreateFile function.
File mapping
	The handle is returned by the CreateFileMapping function.
Mutex
	The handle is returned by the CreateMutex or OpenMutex function.
Pipe
	A named pipe handle is returned by the CreateNamedPipe or CreateFile function. An anonymous pipe handle is returned by the CreatePipe function.
Process
	The handle is returned by the CreateProcess or OpenProcess function.
Semaphore
	The handle is returned by the CreateSemaphore or OpenSemaphore function.
Thread
	The handle is returned by the CreateProcess, CreateThread or CreateRemoteThread function.
In addition to STANDARD_RIGHTS_REQUIRED, the following access flags can be specified in the fdwAccess parameter for the different object types. Note that the new handle can have more access than the original handle.

Any combination of the following access flags is valid for handles to communications devices, console input, console screen buffers, files, and pipes:

Access	Description
GENERIC_READ
	Enables read access.
GENERIC_WRITE
	Enables write access.
Any combination of the following access flags is valid for file mapping objects:

Access	Description
FILE_MAP_WRITE
	Enables mapping the object into memory that permits write access. For write access, PAGE_READWRITE protection must have been specified when the file mapping object was created by the CreateFileMapping function.
FILE_MAP_READ
	Enables mapping the object into memory that permits read access.
FILE_MAP_ALL_ACCESS
	Specifies all possible access flags for the file mapping object.
Any combination of the following access flags is valid for mutex objects:

Access	Description
SYNCHRONIZE	Enables use of the mutex handle in any of the wait functions to acquire ownership of the mutex, or in the ReleaseMutex function to release ownership.
MUTEX_ALL_ACCESS	Specifies all possible access flags for the mutex object.
Any combination of the following access flags is valid for semaphore objects:

Access	Description
SEMAPHORE_MODIFY_STATE	Enables use of the semaphore handle in the ReleaseSemaphore function to modify the semaphore's count.
SYNCHRONIZE	Enables use of the semaphore handle in any of the wait functions to wait for the semaphore's state to be signaled.
SEMAPHORE_ALL_ACCESS	Specifies all possible access flags for the semaphore object.
Any combination of the following access flags is valid for event objects:

Access	Description
EVENT_MODIFY_STATE	Enables use of the event handle in the SetEvent and ResetEvent functions to modify the event's state.
SYNCHRONIZE	Enables use of the event handle in any of the wait functions to wait for the event's state to be signaled.
EVENT_ALL_ACCESS	Specifies all possible access flags for the event object.
Any combination of the following access flags is valid for process objects:

Access	Description
PROCESS_CREATE_PROCESS	Used internally.
PROCESS_CREATE_THREAD	Enables using the process handle in the CreateRemoteThread function to create a thread in the process.
PROCESS_DUP_HANDLE	Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.
PROCESS_QUERY_INFORMATION	Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.
PROCESS_SET_INFORMATION	Enables using the process handle in the SetPriorityClass function to set the process's priority class.
PROCESS_TERMINATE	Enables using the process handle in the TerminateProcess function to terminate the process.
PROCESS_VM_OPERATION	Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.
PROCESS_VM_READ	Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process.
PROCESS_VM_WRITE	Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process.
SYNCHRONIZE	Enables using the process handle in any of the wait functions to wait for the process to terminate.
PROCESS_ALL_ACCESS	Specifies all possible access flags for the process object.
Any combination of the following access flags is valid for thread objects:

Access	Description
SYNCHRONIZE
	Enables using the thread handle in any of the wait functions to wait for the thread to terminate.
THREAD_DIRECT_IMPERSONATION
	Used internally.
THREAD_GET_CONTEXT
	Enables using the thread handle in the GetThreadContext function to read the thread's context.
THREAD_IMPERSONATE
	Used internally.
THREAD_QUERY_INFORMATION
	Enables using the thread handle in the GetExitCodeThread, GetThreadPriority, and GetThreadSelectorEntry functions to read information from the thread object.
THREAD_SET_CONTEXT
	Enables using the thread handle in the SetThreadContext function to set the thread's context.
THREAD_SET_INFORMATION
	Enables using the thread handle in the SetThreadPriority function to set the thread's priority.
THREAD_SET_THREAD_TOKEN
	Used internally.
THREAD_SUSPEND_RESUME
	Enables using the thread handle in the SuspendThread or ResumeThread functions to suspend or resume a thread.
THREAD_TERMINATE
	Enables using the thread handle in the TerminateThread function to terminate the thread.
THREAD_ALL_ACCESS
	Specifies all possible access flags for the thread object.
See Also

»CloseHandle«


  DuplicateToken

BOOL DuplicateToken(hSourceToken, sil, hDuplicateToken)
HANDLE  hSourceToken;   /* handle of token to duplicate */
SECURITY_IMPERSONATION_LEVEL  sil;   /* impersonation level */
PHANDLE  hDuplicateToken;   /* handle of duplicated token */

The DuplicateToken function creates a new access token that duplicates one already in existence.

Parameters

hSourceToken

Identifies an access token opened with TOKEN_DUPLICATE access.

sil

Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token.

The SECURITY_IMPERSONATION_LEVEL enumerated type has the following form:

typedef enum tagSECURITY_IMPERSONATION_LEVEL { /* sil */

    SecurityAnonymous,

    SecurityIdentification,

    SecurityImpersonation,

    SecurityDelegation

} SECURITY_IMPERSONATION_LEVEL;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

hDuplicateToken

Identifies the duplicate access token when the function returns. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY access to the new token.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Impersonation is the ability of a process to take on the security attributes of another process. Usually, a server process impersonates a client process to complete a task involving objects to which the client normally has no access. If a client does not have an account on the server's domain, for example, the server must impersonate the client to gain access to secured objects.

See Also

»DdeImpersonateClient«, »ImpersonateNamedPipeClient«, »RevertToSelf«


  Ellipse

BOOL Ellipse(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coord. of bounding rect. upper-left corner  */
int  nTopRect;   /* y-coord. of bounding rect. upper-left corner  */
int  nRightRect;   /* x-coord. of bounding rect. lower-right corner */
int  nBottomRect;   /* y-coord. of bounding rect. lower-right corner */

The Ellipse function draws an ellipse. The center of the ellipse is the center of the given bounding rectangle. The ellipse is outlined by using the current pen and is filled by using the current brush.

Parameters

hdc

Identifies the device context.

nLeftRect

Specifies the x-coordinate of the upper-left corner of the bounding rectangle.

nTopRect

Specifies the y-coordinate of the upper-left corner of the bounding rectangle.

nRightRect

Specifies the x-coordinate of the lower-right corner of the bounding rectangle.

nBottomRect

Specifies the y-coordinate of the lower-right corner of the bounding rectangle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The current position is neither used nor updated by this function.

See Also

»Arc«, »ArcTo«


  EmptyClipboard

BOOL EmptyClipboard(VOID)

The EmptyClipboard function empties the clipboard and frees handles to data in the clipboard. The function then assigns ownership of the clipboard to the window that currently has the clipboard open.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before calling the EmptyClipboard function, an application must open the clipboard by using the OpenClipboard function. If the application specifies a NULL window handle when opening the clipboard, EmptyClipboard succeeds but sets the clipboard owner to NULL.

See Also

»OpenClipboard«, »SetClipboardData«, »WM_DESTROYCLIPBOARD«


  EnableMenuItem

BOOL EnableMenuItem(hmenu, uItem, fuFlags)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item to enable, disable, or gray */
UINT  fuFlags;   /* menu item flags */

The EnableMenuItem function enables, disables, or grays the given menu item.

Parameters

hmenu

Identifies the menu.

uItem

Specifies the menu item to be enabled, disabled, or grayed, as determined by the fuFlags parameter. This parameter specifies an item in a menu bar or in a pop-up menu.

fuFlags

Specifies flags that control the interpretation of the uItem parameter and indicate whether the menu item is enabled, disabled, or grayed. This parameter must be a combination of either MF_BYCOMMAND or MF_BYPOSITION and MF_ENABLED, MF_DISABLED, or MF_GRAYED.

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the menu item.
MF_DISABLED	Indicates that the menu item is disabled, but not grayed, so it cannot be selected.
MF_ENABLED	Indicates that the menu item is enabled and restored from a grayed state so that it can be selected.
MF_GRAYED	Indicates that the menu item is disabled and grayed so that it cannot be selected.
Return Value

The return value specifies the previous state of the menu item (it is either MF_DISABLED, MF_ENABLED, or MF_GRAYED). If the menu item does not exist, the return value is 0xFFFFFFFF.

Comments

For information about enabling or disabling input to a menu bar, see the »WM_SYSCOMMAND« message.

The CreateMenu, InsertMenu, ModifyMenu, and LoadMenuIndirect functions can also set the state (enabled, disabled, or grayed) of a menu item.

An application must use the MF_BYPOSITION flag to specify the correct menu handle. If the menu handle of the menu bar is specified, the top-level menu item (an item in the menu bar) is affected. To set the state of an item in a pop-up or nested pop-up menu by position, an application must specify the handle of the pop-up menu.

When an application specifies the MF_BYCOMMAND flag, Windows checks all pop-up menu items that are subordinate to the menu identified by the specified menu handle. Therefore, unless duplicate menu items are present, specifying the menu handle of the menu bar is sufficient.

See Also

»CreateMenu«, »GetMenuItemID«, »InsertMenu«, »LoadMenuIndirect«, »ModifyMenu«


  EnableScrollBar

BOOL EnableScrollBar(hwnd, fuSBFlags, fuArrowFlags)
HWND  hwnd;   /* handle of window or scroll bar */
UINT  fuSBFlags;   /* scroll bar type flag */
UINT  fuArrowFlags;   /* scroll bar arrow flag */

The EnableScrollBar function enables or disables one or both scroll bar arrows.

Parameters

hwnd

Identifies a window or a scroll bar control, depending on the value of the fuSBFlags parameter.

fuSBFlags

Specifies the scroll bar type. This parameter can be one of the following values:

Value	Meaning
SB_BOTH	Enables or disables the arrows on the horizontal and vertical scroll bars associated with the given window. The hwnd parameter must be the handle of the window.
SB_CTL	Identifies the scroll bar as a scroll bar control. The hwnd parameter must be the handle of the scroll bar control.
SB_HORZ	Enables or disables the arrows on the horizontal scroll bar associated with the given window. The hwnd parameter must be the handle of the window.
SB_VERT	Enables or disables the arrows on the vertical scroll bar associated with the given window. The hwnd parameter must be the handle of the window.
fuArrowFlags

Specifies whether the scroll bar arrows are enabled or disabled and indicates which arrows are enabled or disabled. This parameter can be one of the following values:

Value	Meaning
ESB_ENABLE_BOTH	Enables both arrows on a scroll bar.
ESB_DISABLE_LTUP	Disables the left arrow on a horizontal scroll bar or the up arrow of a vertical scroll bar.
ESB_DISABLE_RTDN	Disables the right arrow on a horizontal scroll bar or the down arrow of a vertical scroll bar.
ESB_DISABLE_BOTH	Disables both arrows on a scroll bar.
Return Value

If the arrows are enabled or disabled as specified, the return value is TRUE. If the arrows are already in the requested state or an error occurs, the return value is FALSE.

See Also

»ShowScrollBar«


  EnableWindow

BOOL EnableWindow(hwnd, fEnable)
HWND  hwnd;   /* handle of window */
BOOL  fEnable;   /* flag for enabling or disabling input */

The EnableWindow function enables or disables mouse and keyboard input to the given window or control. When input is disabled, the window does not receive input such as mouse clicks and key presses. When input is enabled, the window receives all input.

Parameters

hwnd

Identifies the window to be enabled or disabled.

fEnable

Specifies whether to enable or disable the window. If this parameter is TRUE, the window is enabled. If the parameter is FALSE, the window is disabled.

Return Value

If the window was previously disabled, the return value is TRUE: otherwise, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

If the enabled state of a window is changing, a WM_ENABLE message is sent before this function returns. If a window is already disabled, all its child windows are implicitly disabled, although they are not sent a WM_ENABLE message.

A window must be enabled before it can be activated. For example, if an application is displaying a modeless dialog box and has disabled its main window, the application must enable the main window before destroying the dialog box. Otherwise, another window will receive the keyboard focus and be activated. If a child window is disabled, it is ignored when Windows tries to determine which window should receive mouse messages.

By default, a window is enabled when it is created. To create a window that is initially disabled, an application can specify the WS_DISABLED style in the CreateWindow or CreateWindowEx function. After a window has been created, an application can use the EnableWindow function to enable or disable the window.

An application can use this function to enable or disable a control in a dialog box. A disabled control cannot receive the keyboard focus, nor can a user access it.

See Also

»IsWindowEnabled«


  EndDeferWindowPos

BOOL EndDeferWindowPos(hdwp)
HDWP  hdwp;   /* handle of internal structure */

The EndDeferWindowPos function simultaneously updates the position and size of one or more windows in a single screen-refreshing cycle.

Parameters

hdwp

Identifies a multiple-window-position structure that contains size and position information for one or more windows. This internal structure is returned by the BeginDeferWindowPos function or by the most recent call to the DeferWindowPos function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function sends the WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to each window identified in the internal structure.

See Also

»BeginDeferWindowPos«, »DeferWindowPos«


  EndDialog

BOOL EndDialog(hwndDlg, nResult)
HWND  hwndDlg;   /* handle of dialog box */
int  nResult;   /* value to return */

The EndDialog function destroys a modal dialog box, causing the system to end any processing for the dialog box.

Parameters

hwndDlg

Identifies the dialog box to be destroyed.

nResult

Specifies the value to be returned to the application from the function that created the dialog box.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

Dialog boxes created by the DialogBox, DialogBoxParam, DialogBoxIndirect, and DialogBoxIndirectParam functions must be destroyed using the EndDialog function. An application calls EndDialog from within the dialog box procedure; the function must not be used for any other purpose.

A dialog box procedure can call EndDialog at any time, even during the processing of the WM_INITDIALOG message. If your application calls the function while WM_INITDIALOG is being processed, the dialog box is destroyed before it is shown and before the input focus is set.

EndDialog does not destroy the dialog box immediately. Instead, it sets a flag and allows the dialog box procedure to return control to the system. The system checks the flag before attempting to retrieve the next message from the application queue. If the flag is set, the system ends the message loop, destroys the dialog box, and uses the value given by nResult as the return value from the function that created the dialog box.

See Also

»DialogBox«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »DialogBoxParam«


  EndDoc

int EndDoc(hdc)
HDC  hdc;   /* handle of device context */

The EndDoc function ends a print job. This function replaces the ENDDOC printer escape.

Parameters

hdc

Identifies the device context for the print job.

Return Value

If the function succeeds, the return value is greater than zero.

If the function fails, the return value is SP_ERROR. To get extended error information, use the GetLastError function.

Comments

Applications should call the EndDoc function immediately after finishing a print job.

See Also

»StartDoc«


  EndDocPrinter

BOOL EndDocPrinter(hPrinter)
HANDLE  hPrinter;   /* handle of printer object */

The EndDocPrinter function ends a print job for the given printer.

Parameters

hPrinter

Identifies a printer for which the print job should be ended.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function returns an error if the print job was not started by calling the StartDocPrinter function.


  EndPage

int EndPage(hdc)
HDC  hdc;   /* handle of device context */

The EndPage function informs the device that the application has finished writing to a page. This function is typically used to direct the device driver to advance to a new page. This function replaces the NEWFRAME printer escape.

Parameters

hdc

Identifies the device context for the print job.

Return Value

If the function succeeds, the return value is greater than zero.

If the function fails, the return value is SP_ERROR. Use GetLastError to obtain extended error information.

Comments

Use the ResetDC function to change the device mode, if necessary, after calling the EndPage function.

See Also

»ResetDC«, »StartPage«


  EndPagePrinter

BOOL EndPagePrinter(hPrinter)
HANDLE  hPrinter;   /* handle of printer object */

The EndPagePrinter function indicates the end of one page and the beginning of the next page.

Parameters

hPrinter

Identifies the printer for which the page will be concluded.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer-object handle hPrinter is obtained by calling the OpenPrinter function.

Each page in a print job begins with a StartPagePrinter function call and ends with an EndPagePrinter function call. The data for each page is written to the print file by using the WritePrinter function.

See Also

»OpenPrinter«, »StartPagePrinter«, »WritePrinter«


  EndPaint

BOOL EndPaint(hwnd, lpPaint)
HWND  hwnd;   /* handle of window */
CONST PAINTSTRUCT  *lpPaint;   /* address of structure for paint data */

The EndPaint function marks the end of painting in the given window. This function is required for each call to the BeginPaint function, but only after painting is complete.

Parameters

hwnd

Identifies the window that has been repainted.

lpPaint

Points to a PAINTSTRUCT structure that contains the painting information retrieved by BeginPaint. The PAINTSTRUCT structure has the following form:

typedef struct tagPAINTSTRUCT { /* ps */

    HDC  hdc;

    BOOL fErase;

    RECT rcPaint;

    BOOL fRestore;

    BOOL fIncUpdate;

    BYTE rgbReserved[32];

} PAINTSTRUCT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function always returns TRUE.

Comments

If the caret was hidden by BeginPaint, EndPaint restores the caret to the screen.

See Also

»BeginPaint«


  EndPath

BOOL EndPath(hdc)
HDC  hdc;   /* handle of device context */

The EndPath function closes a path bracket and selects the path defined by the bracket into the given device context (DC).

Parameters

hdc

Identifies the DC into which the new path is selected.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get the error value, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER

See Also

»BeginPath«


  EndUpdateResource

BOOL EndUpdateResource(hUpdateFile, fDiscard)
HANDLE  hUpdateFile;   /* update-file handle */
BOOL  fDiscard;   /* write flag */

The EndUpdateResource function ends a resource update in an executable file.

Parameters

hUpdateFile

Specifies an update handle. This handle is returned by the BeginUpdateResource function.

fDiscard

Specifies whether to write resource updates to an executable file. If this parameter is TRUE, no changes are made to the executable file. If it is FALSE, the changes are made.

Return Value

If the function succeeds and the accumulated resource modifications specified by calls to the UpdateResource function are written to the specified executable file, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»BeginUpdateResource«, »UpdateResource«


  EnhMetaFileProc

int CALLBACK EnhMetaFileProc(hDC, lpHTable, lpEMFR, nObj, lpData)
HDC  hDC;   /* handle of device context */
HANDLETABLE FAR  *lpHTable;   /* address of metafile handle table */
ENHMETARECORD FAR  *lpEMFR;   /* address of metafile record */
int  nObj;   /* count of objects */
LPARAM  lpData;   /* address of optional data */

The EnhMetaFileProc function is an application-defined callback function that processes enhanced-format metafile records. This function is called by the EnumEnhMetaFile function.

Parameters

hDC

Identifies an enhanced-metafile device context (DC).

lpHTable

Points to a table of handles associated with the graphics objects (pens, brushes, and so on) in the metafile. The first entry contains the enhanced-metafile handle.

lpEMFR

Points to one of the records in the metafile. This record should not be modified. (If modification is necessary, it should be performed on a copy of the record.)

nObj

Specifies the number of objects with associated handles in the handle table.

lpData

Points to any application-supplied data.

Return Value

This function must return a nonzero value to continue enumeration; to stop enumeration, it must return zero.

Comments

An application must register the callback function by passing its address to the EnumEnhMetaFile function.

EnhMetaFileProc is a placeholder for the application-supplied function name.

See Also

»EnumEnhMetaFile«


  EnterCriticalSection

VOID EnterCriticalSection(lpcsCriticalSection)
LPCRITICAL_SECTION  lpcsCriticalSection;   /* address of critical section object */

The EnterCriticalSection function waits for ownership of the specified critical section object. The function returns when the calling thread is granted ownership.

Parameters

lpcsCriticalSection

Points to the critical section object.

Return Value

This function does not return a value.

Comments

The threads of a single process can use a critical section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection function to initialize the object.

To enable mutually exclusive access to a shared resource, each thread calls EnterCriticalSection to request ownership of the critical section before executing any section of code that accesses the protected resource. If another thread currently owns the critical section object, EnterCriticalSection blocks the execution of the calling thread indefinitely until the other thread releases its ownership. If the critical section object is currently unowned, the system grants ownership to the requesting thread so it can access the resource. When it has finished executing the protected code, the thread uses the LeaveCriticalSection function to relinquish ownership, enabling another thread to become owner and access the protected resource.

Once a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns. To release its ownership, the thread must call LeaveCriticalSection once for each time that it entered the critical section.

For similar synchronization between the threads of different processes, use a mutex object.

See Also

»CreateMutex«, »DeleteCriticalSection«, »InitializeCriticalSection«, »LeaveCriticalSection«


  EnumChildProc

BOOL CALLBACK EnumChildProc(hwnd, lParam)
HWND  hwnd;   /* handle of child window */
LPARAM  lParam;   /* application-defined value */

The EnumChildProc function is an application-defined callback function that receives child window handles as a result of a call to the EnumChildWindows function.

Parameters

hwnd

Identifies a child window of the parent window specified in the EnumChildWindows function.

lParam

Specifies the application-defined value given in the EnumChildWindows function.

Return Value

To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.

Comments

The callback function can carry out any desired task.

An application must register this callback function by passing its address to the EnumChildWindows function. EnumChildProc is a placeholder for the application-defined function name.

See Also

»EnumChildWindows«


  EnumChildWindows

BOOL EnumChildWindows(hwndParent, wndenmprc, lParam)
HWND  hwndParent;   /* handle of parent window */
WNDENUMPROC  wndenmprc;   /* address of callback function */
LPARAM  lParam;   /* application-defined value */

The EnumChildWindows function enumerates the child windows that belong to the given parent window by passing the handle of each child window, in turn, to an application-defined callback function. EnumChildWindows continues until the last child window is enumerated or the callback function returns FALSE.

Parameters

hwndParent

Identifies the parent window whose child windows are to be enumerated.

wndenmprc

Points to an application-defined callback function. For more information about the callback function, see the description of the »EnumChildProc« callback function.

lParam

Specifies a 32-bit application-defined value to be passed to the callback function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The EnumChildWindows function does not enumerate top-level windows owned by the given window, nor does it enumerate any other owned windows.

If a child window has created child windows of its own, this function enumerates those windows as well.

A child window that is moved or repositioned in the Z order during the enumeration process will be properly enumerated. The function does not enumerate a child window that is destroyed before being enumerated or that is created during the enumeration process.

This function is more reliable than calling GetWindow in a loop. An application that calls GetWindow  to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.

See Also

»EnumChildProc«, »EnumThreadWindows«, »EnumWindows«, »GetWindow«


  EnumClipboardFormats

UINT EnumClipboardFormats(uFormat)
UINT  uFormat;   /* known clipboard format */

The EnumClipboardFormats function enumerates the formats currently available on the clipboard. On each call to this function, the uFormat parameter specifies an available clipboard format, and the function returns the next available format.

Parameters

uFormat

Specifies a known available clipboard format. Zero is specified to retrieve the first format in the list.

Return Value

If the function succeeds, the return value is the next available clipboard format after the specified format; otherwise, it is zero. To get extended error information, use the GetLastError function.

If there are no more available clipboard formats or the clipboard is not open, the return value is zero.

Comments

Before it enumerates the formats by using the EnumClipboardFormats function, an application must open the clipboard by using the OpenClipboard function.

EnumClipboardFormats enumerates the formats in the order they where placed on the clipboard. A window copying information to the clipboard should add clipboard objects in order, from the most descriptive clipboard format to the least descriptive. A window pasting information from the clipboard should retrieve the first format it can handle.

If any of the three text formats (CF_UNICODETEXT, CF_TEXT, and CF_OEMTEXT) have been placed on the clipboard, all three text formats are enumerated. If either of the two metafile formats (CF_ENHMETAFILE and CF_METAFILEPICT) have been placed on the clipboard, both metafile formats are enumerated.

See Also

»CountClipboardFormats«, »OpenClipboard«, »RegisterClipboardFormat«


  EnumDependentServices

BOOL EnumDependentServices(schService, fdwServiceState, lpessServices, cbBufSize,
lpcbBytesNeeded, lpdwServicesReturned)
SC_HANDLE  schService;   /* handle of service */
DWORD  fdwServiceState;   /* state of services to enumerate */
LPENUM_SERVICE_STATUS  lpessServices;   /* address of service status buffer */
DWORD  cbBufSize;   /* size of service status buffer */
LPDWORD  lpcbBytesNeeded;   /* address of variable for bytes needed */
LPDWORD  lpdwServicesReturned;   /* address of variable for number returned */

The EnumDependentServices function enumerates services that depend on another specified service; that is, the specified service must be running before they can run. The name and status of each dependent service are provided.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_ENUMERATE_DEPENDENTS access.

fdwServiceState

Specifies the services to enumerate based on their running state. It must be one or both of the following values:

Value	Meaning
SERVICE_ACTIVE	Enumerates services that are in the following states: SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, and SERVICE_PAUSED.
SERVICE_INACTIVE	Enumerates services that are in the SERVICE_STOPPED state.
lpessServices

Points to an array of ENUM_SERVICE_STATUS structures where the name and service status information for each dependent service is returned. The order of the services in this array is the reverse of the start order. In other words, the dependent service that would be started last is listed first. The ENUM_SERVICE_STATUS structure has the following form:

typedef struct _ENUM_SERVICE_STATUS { /* ess */

    LPTSTR lpServiceName;

    LPTSTR lpDisplayName;

    SERVICE_STATUS ServiceStatus;

} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBufSize

Specifies the size, in bytes, of the buffer pointed to by the lpessServices parameter.

lpcbBytesNeeded

Points to a variable that receives the number of bytes needed to return the remaining service entries.

lpdwServicesReturned

Points to a variable that receives the number of service entries returned.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with SERVICE_ENUMERATE_DEPENDENTS access.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_INVALID_PARAMETER
	A parameter that was specified is invalid.
ERROR_MORE_DATA
	There are more service entries than would fit into the lpessServices buffer. The actual number of service entries written to lpessServices is returned in the lpdwServicesReturned parameter. The number of bytes required to get the remaining entries is returned in the lpcbBytesNeeded parameter.
Comments

The returned services entries are ordered in the reverse order of the start order, with group order taken into account. If you need to stop the dependent services, you can use the order of entries written to the lpessServices buffer to stop the dependent services in the proper order.

See Also

»CreateService«, »EnumServicesStatus«, »OpenService«


  EnumEnhMetaFile

BOOL EnumEnhMetaFile(hdc, hemf, lpEnhMetaFunc, lpData, lpRect)
HDC  hdc;   /* handle of device context */
HENHMETAFILE  hemf;   /* handle of enhanced metafile */
ENHMFENUMPROC  lpEnhMetaFunc;   /* address of callback function */
LPVOID  lpData;   /* address of callback-function data */
LPRECT  lpRect;   /* address of bounding rectangle */

The EnumEnhMetaFile function enumerates the records within an enhanced-format metafile by retrieving each record and passing it to the specified callback function. The application-supplied callback function processes each record as required. The enumeration continues until the last record is processed or when the callback function returns zero.

Parameters

hdc

Identifies a device context (DC). This handle is passed to the callback function.

hemf

Identifies an enhanced metafile.

lpEnhMetaFunc

Points to the application-supplied callback function. For more information, see the description of the »EnhMetaFileProc« function.

lpData

Points to optional callback-function data.

lpRect

Points to a RECT structure that specifies the coordinates of the picture's upper left and lower right corners. The dimensions of this rectangle are specified in logical units. The RECT structure has the following format:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the callback function successfully enumerates all the records in the enhanced metafile, the return value is TRUE; otherwise, it is FALSE.

Comments

Points along the edge of the rectangle pointed to by the lpRect parameter are included in the picture. If the hdc parameter is NULL, Windows ignores lpRect.

If the callback function calls the PlayEnhMetaFileRecord function, hdc must identify a valid device context. Windows uses the DC's transformation and mapping mode to transform the picture displayed by the PlayEnhMetaFileRecord function. If hdc is NULL, the picture is not transformed and will appear distorted.

You can use the EnumEnhMetaFile function to embed one enhanced-metafile within another.

See Also

»EnhMetaFileProc«, »PlayEnhMetaFile«, »PlayEnhMetaFileRecord«


  EnumFontFamilies

int EnumFontFamilies(hdc, lpszFamily, lpEnumFontFamProc, lParam)
HDC  hdc;   /* handle of device control */
LPCTSTR  lpszFamily;   /* address of family-name string */
FONTENUMPROC  lpEnumFontFamProc;   /* address of callback function */
LPARAM  lParam;   /* address of application-supplied data */

The EnumFontFamilies function enumerates the fonts in a specified font family that are available on a given device.

Parameters

hdc

Identifies the device context.

lpszFamily

Points to a null-terminated string that specifies the family name of the desired fonts. If lpszFamily is NULL, EnumFontFamilies randomly selects and enumerates one font of each available type family.

lpEnumFontFamProc

Specifies the procedure-instance address of the application-defined callback function. For information about the callback function, see the description of the »EnumFontFamProc« function.

lParam

Points to application-supplied data. The data is passed to the callback function along with the font information.

Return Value

If the function succeeds, the return value is the last value returned by the callback function. Its meaning is implementation specific.

Comments

The EnumFontFamilies function differs from the EnumFonts function in that it retrieves the style names associated with a TrueType® font. With EnumFontFamilies, information can be retrieved about unusual font styles (for example, Outline) that could not be enumerated by using the EnumFonts function. Applications should use EnumFontFamilies instead of EnumFonts.

For each font having the typeface name specified by the lpszFamily parameter, the EnumFontFamilies function retrieves information about that font and passes it to the function pointed to by the lpEnumFontFamProc parameter. The application-supplied callback function can process the font information as desired. Enumeration continues until there are no more fonts or the callback function returns zero.

See Also

»EnumFontFamProc«, »EnumFonts«


  EnumFontFamProc

int CALLBACK EnumFontFamProc(lpelf, lpntm, FontType, lParam)
ENUMLOGFONT FAR*  lpelf;   /* address of logical-font data */
NEWTEXTMETRIC FAR*  lpntm;   /* address of physical-font data */
int  FontType;   /* type of font */
LPARAM  lParam;   /* address of application-defined data */

The EnumFontFamProc function is an application-defined callback function that retrieves data describing available fonts.

Parameters

lpelf

Points to an ENUMLOGFONT structure that contains information about the logical attributes of the font. This structure is locally defined. The ENUMLOGFONT structure has the following form:

typedef struct tagENUMLOGFONT { /* elf */

    LOGFONT elfLogFont;

    BYTE    elfFullName[LF_FULLFACESIZE];

    BYTE    elfStyle[LF_FACESIZE];

} ENUMLOGFONT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpntm

Points to a NEWTEXTMETRIC structure that contains information about the physical attributes of the font, if the font is a TrueType® font. If the font is not a TrueType® font, this parameter points to a TEXTMETRIC structure. The NEWTEXTMETRIC structure has the following form:

typedef struct tagNEWTEXTMETRIC { /* ntm */

    LONG  tmHeight;

    LONG  tmAscent;

    LONG  tmDescent;

    LONG  tmInternalLeading;

    LONG  tmExternalLeading;

    LONG  tmAveCharWidth;

    LONG  tmMaxCharWidth;

    LONG  tmWeight;

    LONG  tmOverhang;

    LONG  tmDigitizedAspectX;

    LONG  tmDigitizedAspectY;

    BYTE  tmFirstChar;

    BYTE  tmLastChar;

    BYTE  tmDefaultChar;

    BYTE  tmBreakChar;

    BYTE  tmItalic;

    BYTE  tmUnderlined;

    BYTE  tmStruckOut;

    BYTE  tmPitchAndFamily;

    BYTE  tmCharSet;

    DWORD ntmFlags;

    UINT  ntmSizeEM;

    UINT  ntmCellHeight;

    UINT  ntmAvgWidth;

} NEWTEXTMETRIC;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5

The TEXTMETRIC structure has the following form:

typedef struct tagTEXTMETRIC { /* tm */

    LONG tmHeight;

    LONG tmAscent;

    LONG tmDescent;

    LONG tmInternalLeading;

    LONG tmExternalLeading;

    LONG tmAveCharWidth;

    LONG tmMaxCharWidth;

    LONG tmWeight;

    LONG tmOverhang;

    LONG tmDigitizedAspectX;

    LONG tmDigitizedAspectY;

    BYTE tmFirstChar;

    BYTE tmLastChar;

    BYTE tmDefaultChar;

    BYTE tmBreakChar;

    BYTE tmItalic;

    BYTE tmUnderlined;

    BYTE tmStruckOut;

    BYTE tmPitchAndFamily;

    BYTE tmCharSet;

} TEXTMETRIC;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

FontType

Specifies the type of the font. This parameter can be a combination of the following values:

DEVICE_FONTTYPE
RASTER_FONTTYPE
TRUETYPE_FONTTYPE

lParam

Points to the application-defined data passed by the EnumFontFamilies function.

Return Value

The return value must be a nonzero value to continue enumeration; to stop enumeration, it must return zero.

Comments

An application must register this callback function by passing its address to the EnumFontFamilies function.

The EnumFontFamProc function is a placeholder for the application-defined function name.

The AND (&) operator can be used with the RASTER_FONTTYPE, DEVICE_FONTTYPE, and TRUETYPE_FONTTYPE constants to determine the font type. If the RASTER_FONTTYPE bit is set, the font is a raster font. If the TRUETYPE_FONTTYPE bit is set, the font is a TrueType font. If neither bit is set, the font is a vector font. DEVICE_FONTTYPE is set when a device (for example, a laser printer) supports downloading TrueType fonts or when the font is a device-resident font; it is zero if the device is a display adapter, dot-matrix printer, or other raster device. An application can also use DEVICE_FONTTYPE to distinguish graphics device interface (GDI)-supplied raster fonts from device-supplied fonts. GDI can simulate bold, italic, underline, and strikeout attributes for GDI-supplied raster fonts, but not for device-supplied fonts.

See Also

»EnumFontFamilies«, »EnumFonts«


  EnumFonts

int EnumFonts(hdc, lpFaceName, lpFontFunc, lParam)
HDC  hdc;   /* handle of device context */
LPCTSTR  lpFaceName;   /* address of font typeface name string */
FONTENUMPROC  lpFontFunc;   /* address of callback function */
LPARAM  lParam;   /* address of application-supplied data */

The EnumFonts function enumerates the fonts available on a given device. For each font with the specified typeface name, the EnumFonts function retrieves information about that font and passes it to the application-supplied callback function. This callback function can process the font information as desired. Enumeration continues until there are no more fonts or the callback function returns zero.

Parameters

hdc

Identifies the device context.

lpFaceName

Points to a null-terminated character string that specifies the typeface name of the desired fonts. If lpFaceName is NULL, EnumFonts randomly selects and enumerates one font of each available typeface.

lpFontFunc

Points to the application-supplied callback function. For more information about the callback function, see the description of the »EnumFontsProc« function.

lParam

Points to any application-supplied data. The data is passed to the callback function along with the font information.

Return Value

If the function succeeds, the return value is the last value returned by the callback function. Its meaning is defined by the application.

See Also

»EnumFontFamilies«, »EnumFontsProc«, »GetDeviceCaps«


  EnumFontsProc

int CALLBACK EnumFontsProc(lplf, lptm, dwType, lpData)
lplf  lplf;   /* address of logical-font data */
lptm  lptm;   /* address of physical-font data */
DWORD  dwType;   /* font type */
LPARAM  lpData;   /* address of application-supplied data */

The EnumFontsProc function is an application-defined callback function that processes font data from the EnumFonts function.

Parameters

lplf

Points to a LOGFONT structure that contains information about the logical attributes of the font. The LOGFONT structure has the following form:

typedef struct tagLOGFONT { /* lf */

   LONG lfHeight;

   LONG lfWidth;

   LONG lfEscapement;

   LONG lfOrientation;

   LONG lfWeight;

   BYTE lfItalic;

   BYTE lfUnderline;

   BYTE lfStrikeOut;

   BYTE lfCharSet;

   BYTE lfOutPrecision;

   BYTE lfClipPrecision;

   BYTE lfQuality;

   BYTE lfPitchAndFamily;

   CHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5

lptm

Points to a TEXTMETRIC structure that contains information about the physical attributes of the font. The TEXTMETRIC structure has the following form:

typedef struct tagTEXTMETRIC { /* tm */

    LONG tmHeight;

    LONG tmAscent;

    LONG tmDescent;

    LONG tmInternalLeading;

    LONG tmExternalLeading;

    LONG tmAveCharWidth;

    LONG tmMaxCharWidth;

    LONG tmWeight;

    LONG tmOverhang;

    LONG tmDigitizedAspectX;

    LONG tmDigitizedAspectY;

    BYTE tmFirstChar;

    BYTE tmLastChar;

    BYTE tmDefaultChar;

    BYTE tmBreakChar;

    BYTE tmItalic;

    BYTE tmUnderlined;

    BYTE tmStruckOut;

    BYTE tmPitchAndFamily;

    BYTE tmCharSet;

} TEXTMETRIC;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5

dwType

Specifies the type of the font. This parameter can be a combination of the following values:

DEVICE_FONTTYPE
RASTER_FONTTYPE
TRUETYPE_FONTTYPE

lpData

Points to the application-supplied data passed by EnumFonts.

Return Value

The return value must be a nonzero value to continue enumeration; to stop enumeration, it must be zero.

Comments

The AND (&) operator can be used with the RASTER_FONTTYPE and DEVICE_FONTTYPE constants to determine the font type. The RASTER_FONTTYPE bit of the FontType parameter specifies whether the font is a raster or vector font. If the bit is one, the font is a raster font; if zero, it is a vector font. The DEVICE_FONTTYPE bit of FontType specifies whether the font is a device-based or graphics device interface (GDI)-based font. If the bit is one, the font is a device-based font; if zero, it is a GDI-based font.

If the device is capable of text transformations (scaling, italicizing, and so on) only the base font is enumerated. The user must inquire into the device's text-transformation abilities to determine which additional fonts are available directly from the device.

An application must register the EnumFontsProc function by passing its address to the EnumFonts function.

EnumFontsProc is a placeholder for the application-supplied function name.

See Also

»EnumFonts«, »LOGFONT«, »TEXTMETRIC«


  EnumForms

BOOL EnumForms(hPrinter, dwLevel, lpbForm, dwBuf, lpdwNeeded, lpdwReturned)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  dwLevel;   /* data-structure level */
LPBYTE  lpbForm;   /* address of data-structure array */
DWORD  dwBuf;   /* count of bytes in buffer */
LPDWORD  lpdwNeeded;   /* address of value for count of bytes required for array */
LPDWORD  lpdwReturned;   /* address of value for count of bytes returned in array */

The EnumForms function enumerates the forms supported by the given printer.

Parameters

hPrinter

Identifies the printer for which the forms should be enumerated.

dwLevel

Specifies the version of the structure to which lpbForm points. This value must be 1.

lpbForm

Points to a FORM_INFO_1 structure. The FORM_INFO_1 structure has the following form:

typedef struct _FORM_INFO_1 { /* fi1 */

    LPTSTR pName;

    SIZEL  Size;

    RECTL  ImageableArea;

} FORM_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwBuf

Specifies the size of the array to which lpbForm points.

lpdwNeeded

Points to a value that specifies the number of bytes copied to or the number of bytes required for the array to which lpbForm points. If dwBuf is too small, this value specifies the number of bytes required; otherwise, this value specifies the number of bytes copied.

lpdwReturned

Points to a value that specifies the number of FORM_INFO_1 structures copied into the array to which lpbForm points.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer-object handle hPrinter is normally obtained by calling the OpenPrinter function. The AddPrinter function can also be used.

See Also

»AddPrinter«, »OpenPrinter«


  EnumJobs

BOOL EnumJobs(hPrinter, dwFirstJob, dwNoJobs, dwLevel, lpbJob, dwBuf, lpdwNeeded,
lpdwReturned)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  dwFirstJob;   /* location of first job in print queue */
DWORD  dwNoJobs;   /* number of jobs to enumerate */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbJob;   /* address of structure array */
DWORD  dwBuf;   /* size of array, in bytes */
LPDWORD  lpdwNeeded;   /* addr. of variable with no. of bytes copied (or required) */
LPDWORD  lpdwReturned;   /* addr. of variable with no. of job info. structures copied */

The EnumJobs function initializes an array of either JOB_INFO_1 or JOB_INFO_2 structures with data describing the specified print jobs for the given printer.

Parameters

hPrinter

Identifies a printer object.

dwFirstJob

Specifies the location of the first enumerated job in the print queue. For example, a value of 10 indicates that enumeration should begin at the tenth job.

dwNoJobs

Specifies the total number of print jobs to enumerate.

dwLevel

Specifies whether the function should use JOB_INFO_1 or JOB_INFO_2 structures to store data for the enumerated jobs. A value of 1 specifies that the JOB_INFO_1 structure should be used; a value of 2 specifies that the JOB_INFO_2 structure should be used.

lpbJob

Points to an array of either JOB_INFO_1 or JOB_INFO_2 structures. The JOB_INFO_1 structure has the following form:

typedef struct _JOB_INFO_1 {    /* ji1 */

    DWORD  JobId;

    LPTSTR pPrinterName;

    LPTSTR pMachineName;

    LPTSTR pUserName;

    LPTSTR pDocument;

    LPTSTR pDatatype;

    LPTSTR pStatus;

    DWORD  Status;

    DWORD  Priority;

    DWORD  Position;

    DWORD  TotalPages;

    DWORD  PagesPrinted;

    SYSTEMTIME Submitted;

} JOB_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The JOB_INFO_2 structure has the following form:

typedef struct _JOB_INFO_2 { /* ji2 */

    DWORD      JobId;

    LPTSTR     pPrinterName;

    LPTSTR     pMachineName;

    LPTSTR     pUserName;

    LPTSTR     pDocument;

    LPTSTR     pNotifyName;

    LPTSTR     pDatatype;

    LPTSTR     pPrintProcessor;

    LPTSTR     pParameters;

    LPTSTR     pDriverName;

    LPDEVMODE  pDevMode;

    LPTSTR     pStatus;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD      Status;

    DWORD      Priority;

    DWORD      Position;

    DWORD      StartTime;

    DWORD      UntilTime;

    DWORD      TotalPages;

    DWORD      Size;

    SYSTEMTIME Submitted;

    DWORD      Time;

    DWORD      PagesPrinted ;

} JOB_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwBuf

Specifies the size, in bytes, of the array lpbJob.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds; otherwise, this value specifies the number of bytes required.

lpdwReturned

Points to a value that specifies the number of JOB_INFO_1 or JOB_INFO_2 structures that were initialized.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The handle hPrinter is obtained by calling the OpenPrinter function.

The JOB_INFO_1 structure contains general print-job data; the JOB_INFO_2 structure is much more detailed.

See Also

»GetJob«, »OpenPrinter«, »SetJob«


  EnumMetaFile

BOOL EnumMetaFile(hdc, hmf, lpMetaFunc, lParam)
HDC  hdc;   /* handle of device context */
HMETAFILE  hmf;   /* handle of Windows-format metafile */
MFENUMPROC  lpMetaFunc;   /* address of callback function */
LPARAM  lParam;   /* address of callback function data */

The EnumMetaFile function enumerates the records within a Windows-format metafile by retrieving each record and passing it to the specified callback function. The application-supplied callback function processes each record as required. The enumeration continues until the last record is processed or when the callback function returns zero.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use EnumEnhMetaFile function.

Parameters

hdc

Identifies a device context (DC). This handle is passed to the callback function.

hmf

Identifies a Windows-format metafile.

lpMetaFunc

Points to an application-supplied callback function. For more information, see the description of the »EnumMetaFileProc« callback function.

lParam

Points to optional callback-function data.

Return Value

If the callback function successfully enumerates all the records in the Windows-format metafile, the return value is TRUE; otherwise, it is FALSE.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions, such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should use the enhanced-format metafile functions.

To convert a Windows-format metafile into an enhanced-format metafile, use the SetWinMetaFileBits function.

You can use the EnumMetaFile function to embed one Windows-format metafile within another.

See Also

»BeginPath«, »EnumMetaFileProc«, »PlayMetaFile«, »PlayMetaFileRecord«, »PolyBezier«, »SetWinMetaFileBits«, »SetWorldTransform«


  EnumMetaFileProc

int CALLBACK EnumMetaFileProc(hDC, lpHTable, lpMFR, nObj, lpClientData)
HDC  hDC;   /* handle of device context */
HANDLETABLE FAR  *lpHTable;   /* address of metafile handle table */
METARECORD FAR  *lpMFR;   /* address of metafile record */
int  nObj;   /* count of objects */
LPARAM  lpClientData;   /* address of optional data */

The EnumMetaFileProc function is an application-defined callback function that processes Windows-format metafile records. This function is called by the EnumMetaFile function.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the EnhMetaFileProc and EnumEnhMetaFile function.

Parameters

hDC

Identifies a Windows-format metafile device context.

lpHTable

Points to a table of handles associated with the graphics objects (pens, brushes, and so on) in the metafile.

lpMFR

Points to one of the records in the metafile. This record should not be modified. (If modification is necessary, it should be performed on a copy of the record.)

nObj

Specifies the number of objects with associated handles in the handle table.

lpClientData

Points to any application-supplied data.

Return Value

This function must return a nonzero value to continue enumeration; to stop enumeration, it must return zero.

Comments

An application must register the callback function by passing its address to the EnumMetaFile function.

EnumMetaFileProc is a placeholder for the application-supplied function name.

See Also

»EnumMetaFile«


  EnumMonitors

BOOL EnumMonitors(lpszName, dwLevel, lpbMonitors, cbBuf, lpdwNeeded, lpdwReturned)
LPTSTR  lpszName;   /* address of server name */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbMonitors;   /* address of structure array */
DWORD  cbBuf;   /* size, in bytes, of buffer */
LPDWORD  lpdwNeeded;   /* addr. of variable with no. of bytes copied (or required) */
LPDWORD  lpdwReturned;   /* addr. of variable with no. of job info. structures copied */

The EnumMonitors function initializes an array of MONITOR_INFO_1 structures with data describing the specified monitors for the given server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the monitors reside. If this string is NULL, the local monitors are enumerated.

dwLevel

Specifies the version of the structure to which lpbMonitors points. This value must be 1.

lpbMonitors

Points to an array of MONITOR_INFO_1 structures. The MONITOR_INFO_1 structure has the following form:

typedef struct _MONITOR_INFO_1 { /* mi1 */

    LPTSTR pName;

} MONITOR_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the buffer to which lpbMonitors points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

lpdwReturned

Points to a value that specifies the number of MONITOR_INFO_1 structures that were returned in the array to which lpbMonitors points.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.


  EnumObjects

int EnumObjects(hdc, nObjectType, lpObjectFunc, lParam)
HDC  hdc;   /* handle of device context */
int  nObjectType;   /* object-type identifier */
GOBJENUMPROC  lpObjectFunc;   /* address of callback function */
LPARAM  lParam;   /* address of application-supplied data */

The EnumObjects function enumerates the pens or brushes available for the given device context. This function calls the application-defined callback function once for each available object, supplying data describing that object. EnumObjects continues calling the callback function until the callback function returns zero or until all of the objects have been enumerated.

Parameters

hdc

Identifies the device context.

nObjectType

Specifies the object type. This parameter can be OBJ_BRUSH or OBJ_PEN.

lpObjectFunc

The address of the application-defined callback function. For more information about the callback function, see the description of the »EnumObjectsProc« function.

lParam

Points to the application-defined data. The data is passed to the callback function along with the object information.

Return Value

The return value specifies the last value returned by the callback function. Its meaning is user-defined.

See Also

»GetObject«


  EnumObjectsProc

VOID CALLBACK EnumObjectsProc(lpLogObject, lpData)
LPVOID  lpLogObject;   /* address of graphic-object structure */
LPARAM  lpData;   /* address of application-defined data */

The EnumObjectsProc function is an application-defined callback function that processes object data supplied by the EnumObjects function.

Parameters

lpLogObject

Points to a LOGPEN or LOGBRUSH structure describing the attributes of the object.

The LOGPEN structure has the following form:

typedef struct tagLOGPEN { /* lgpn */

    UINT     lopnStyle;

    POINT    lopnWidth;

    COLORREF lopnColor;

} LOGPEN;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

The LOGBRUSH structure has the following form:

typedef struct tagLOGBRUSH { /* lb */

   UINT     lbStyle;

   COLORREF lbColor;

   LONG     lbHatch;

} LOGBRUSH;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

lpData

Points to the application-defined data passed by the EnumObjects function.

Return Value

This function does not return a value.

Comments

An application must register this function by passing its address to the EnumObjects function. EnumObjectsProc is a placeholder for the application-defined function name.

See Also

»EnumObjects«, »GlobalAlloc«, »GlobalLock«,


  EnumPorts

BOOL EnumPorts(lpszName, dwLevel, lpbPorts, cbBuf, lpdwNeeded, lpdwReturned)
LPTSTR  lpszName;   /* address of server name */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbPorts;   /* address of structure array */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwNeeded;   /* addr. of variable with no. of bytes copied (or required) */
LPDWORD  lpdwReturned;   /* addr. of variable with no. of job info. structures copied */

The EnumPorts function enumerates the ports available for printing on a specified server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server whose ports you wish to enumerate. If this string is NULL, the local ports are enumerated.

dwLevel

Specifies the version of the structure to which lpbPorts points. This value must be 1.

lpbPorts

Points to an array of PORT_INFO_1 structures that will contain data describing the available ports. The PORT_INFO_1 structure has the following form:

typedef struct _PORT_INFO_1 { /* pi1 */

    LPSTR pName;

} PORT_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the buffer to which lpbPorts points.

lpdwNeeded

Points to a value that will contain the actual, required buffer size identified by lpbPorts. If cbBuf is too small, GetLastError will indicate ERROR_INSUFFICIENT_BUFFER, and lpdwNeeded will contain the size required. If cbBuf is large enough, lpdwNeeded will contain the number of bytes that were copied.

lpdwReturned

Points to a variable that will contain the number of PORT_INFO_1 structures returned in lpbPorts.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The server doesn't need to have a printer defined for this function to work.

See Also

»AddPort«, »DeletePort«


  EnumPrinterDrivers

BOOL EnumPrinterDrivers(lpszName, lpszEnvironment, dwLevel, lpbDriverInfo, cbBuf,
lpdwNeeded, lpdwReturned)
LPTSTR  lpszName;   /* address of server name */
LPTSTR  lpszEnvironment;   /* address of environment */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbDriverInfo;   /* address of structure array */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwNeeded;   /* addr. of variable with no. of bytes copied (or required) */
LPDWORD  lpdwReturned;   /* addr. of variable with no. of job info. structures copied */

The EnumPrinterDrivers function enumerates all of the printer drivers installed on the specified printer server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the drivers should be enumerated. If this string is NULL, the local drivers are enumerated.

lpszEnvironment

Points to a null-terminated string that specifies the environment. For example, "Windows NT x86" specifies Windows NT running on an Intel® 80386 or 80486 processor. If this string is NULL, the current environment of the caller/client (not of the destination/server) is used.

dwLevel

Specifies the version of the structure to which lpbDriverInfo points. This value must be 1 or 2.

lpbDriverInfo

Points to an array of DRIVER_INFO_1 or DRIVER_INFO_2 structures. One structure is created for each available driver.

The DRIVER_INFO_1 structure has the following form:

typedef struct _DRIVER_INFO_1 { /* dri1 */

    LPTSTR pName;

} DRIVER_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The DRIVER_INFO_2 structure has the following form:

typedef struct _DRIVER_INFO_2 { /* dri2 */

    DWORD  cVersion;

    LPTSTR pName;

    LPTSTR pEnvironment;

    LPTSTR pDriverPath;

    LPTSTR pDataFile;

    LPTSTR pConfigFile;

} DRIVER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the buffer to which lpbDriverInfo points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

lpdwReturned

Points to a value that specifies the number of DRIVER_INFO_1 structures that returned in the array to which lpbDriverInfo points.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrinterDriver«, »GetPrinterDriver«


  EnumPrinters

BOOL EnumPrinters(dwType, lpszName, dwLevel, lpbPrinters, cbBuf, lpdwNeeded, lpdwReturned)
DWORD  dwType;   /* printer type or types */
LPTSTR  lpszName;   /* address of server name */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbPrinters;   /* printer info array */
DWORD  cbBuf;   /* address of structure count of bytes in array */
LPDWORD  lpdwNeeded;   /* addr. of variable with no. of bytes copied (or required) */
LPDWORD  lpdwReturned;   /* addr. of variable with no. of job info. structures copied */

The EnumPrinters function enumerates the available printers on the specified server.

Parameters

dwType

Specifies the type of printers that the function should enumerate. This value can be any combination of the following constants:

Value	Meaning
PRINTER_ENUM_DEFAULT	Enumerates the default printer.
PRINTER_ENUM_LOCAL	Enumerates the locally installed printers.
PRINTER_ENUM_FAVORITE	Enumerates a list of favorite printers. This is essentially the list of printers that the user has made previous connections to.
PRINTER_ENUM_NAME	Enumerates the printer identified by lpszName. This could be a server lpszName, or a domain lpszName. If lpszName is NULL, available domains (actually, print providors) will be enumerated.
PRINTER_ENUM_REMOTE	Enumerates network printers.
PRINTER_ENUM_SHARED	Enumerates printers with the shared attribute.
lpszName

Points to a null-terminated string that specifies the name of the server for which to enumerate the printers. If this string is NULL, the local printers are enumerated.

dwLevel

Specifies the version of the structure to which lpbPrinters points. This value must be 1 or 2.

lpbPrinters

Points to an array of PRINTER_INFO_1 or PRINTER_INFO_2 structures. If dwLevel is 1, the array contains PRINTER_INFO_1 structures; if dwLevel is 2, the array contains PRINTER_INFO_2 structures. The PRINTER_INFO_1 structure has the following form:

typedef struct _PRINTER_INFO_1 { /* pri1 */

    DWORD  Flags;

    LPTSTR pDescription;

    LPTSTR pName;

    LPTSTR pComment;

} PRINTER_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The PRINTER_INFO_2 structure has the following form:

typedef struct _PRINTER_INFO_2 { /* pri2 */

    LPTSTR    pServerName;

    LPTSTR    pPrinterName;

    LPTSTR    pShareName;

    LPTSTR    pPortName;

    LPTSTR    pDriverName;

    LPTSTR    pComment;

    LPTSTR    pLocation;

    LPDEVMODE pDevMode;

    LPTSTR    pSepFile;

    LPTSTR    pPrintProcessor;

    LPTSTR    pDatatype;

    LPTSTR    pParameters;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD     Attributes;

    DWORD     Priority;

    DWORD     DefaultPriority;

    DWORD     StartTime;

    DWORD     UntilTime;

    DWORD     Status;

    DWORD     cJobs;

    DWORD     AveragePPM;

} PRINTER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the array to which lpbPrinters points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

lpdwReturned

Points to a value that specifies the number of PRINTER_INFO_1 or PRINTER_INFO_2 structures that returned in the array to which lpbPrinters points.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrinter«, »DeletePrinter«, »GetPrinter«, »SetPrinter«


  EnumPrintProcessors

BOOL EnumPrintProcessors(lpszName, lpszEnvir, dwLevel, lpbPPInfo, cbBuf,
lpdwNeeded, lpdwReturned)
LPTSTR  lpszName;   /* address of server name */
LPTSTR  lpszEnvir;   /* address of environment name */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbPPInfo;   /* address of structure array */
DWORD  cbBuf;   /* array length in bytes */
LPDWORD  lpdwNeeded;   /* addr. of variable with no. of bytes copied (or required) */
LPDWORD  lpdwReturned;   /* addr. of variable with no. of job info. structures copied */

The EnumPrintProcessors function enumerates the print processors installed on the specified server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the print processors reside. If this string is NULL, the local print processors are enumerated.

lpszEnvir

Points to a null-terminated string that specifies the environment. For example, "Windows NT x86" specifies Windows NT running on an Intel® 80386 or 80486 processor. If this string is NULL, the current environment of the caller/client (not of the destination/server) is used.

dwLevel

Specifies the version of the structure to which lpbPPInfo points. This value must be 1.

lpbPPInfo

Points to an array PRINTPROCESSOR_INFO_1 structures. One structure is created for each available print processor. The PRINTPROCESSOR_INFO_1 structure has the following form:

typedef struct _PRINTPROCESSOR_INFO_1 { /* ppi1 */

    LPSTR pName;

} PRINTPROCESSOR_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the buffer pointed to by lpbPPInfo.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

lpdwReturned

Points to a value that specifies the number of PRINTPROCESSOR_INFO_1 structures that returned in the array which lpbPPInfo points.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrintProcessor«


  EnumPropProc

BOOL CALLBACK EnumPropProc(hwnd, lpszString, hData)
HWND  hwnd;   /* handle of window with property */
LPCSTR  lpszString;   /* atom or address of string */
HANDLE  hData;   /* data handle */

The EnumPropProc function is an application-defined callback function that receives a window's property data as a result of a call to the EnumProps function.

Parameters

hwnd

Identifies the window that contains the property list.

lpszString

Points to the null-terminated string associated with the data identified by the hData parameter. The application specified the string and data handle in a previous call to the SetProp function. If the application passed an atom instead of a string to the SetProp function, the lpszString parameter contains the atom in the low-order word and zero in the high-order word.

hData

Identifies the property data.

Return Value

The callback function should return TRUE to continue enumeration or FALSE to stop enumeration.

Comments

The following restrictions apply to this callback function:

•	The callback function must not yield control or do anything that might yield control to other tasks.

•	The callback function can call the RemoveProp function. However, RemoveProp can remove only the property passed to the callback function through the callback function's parameters.

•	The callback function should not attempt to add properties.

EnumPropProc is a placeholder for the application-defined function name.

See Also

»EnumProps«, »EnumPropsEx«, »RemoveProp«, »SetProp«


  EnumProps

int EnumProps(hwnd, lpEnumFunc)
HWND  hwnd;   /* handle of window */
PROPENUMPROC  lpEnumFunc;   /* address of callback function */

The EnumProps function enumerates all entries in the property list of the given window by passing them, one by one, to the specified callback function. EnumProps continues until the last entry is enumerated or the callback function returns FALSE.

Parameters

hwnd

Identifies the window whose property list is to be enumerated.

lpEnumFunc

Points to the callback function. For more information, see the description of the »EnumPropProc« callback function.

Return Value

The return value specifies the last value returned by the callback function. It is -1 if the function did not find a property for enumeration.

Comments

An application can remove only those properties it has added. It must not remove properties added by other applications or by Windows itself.

See Also

»EnumPropsEx«, »GetProp«, »RemoveProp«, »SetProp«


  EnumPropsEx

int EnumPropsEx(hwnd, lpEnumFunc, lParam)
HWND  hwnd;   /* handle of window */
PROPENUMPROC  lpEnumFunc;   /* address of callback function */
LPARAM  lParam;   /* application-defined data */

The EnumPropsEx function enumerates all entries in the property list of the given window by passing them, one by one, to the specified callback function. EnumPropsEx continues until the last entry is enumerated or the callback function returns FALSE.

Parameters

hwnd

Identifies the window whose property list is to be enumerated.

lpEnumFunc

Points to the callback function. For more information, see the description of the »EnumPropProc« callback function.

lParam

Contains application-defined data to be passed to the callback function.

Return Value

The return value specifies the last value returned by the callback function. It is -1 if the function did not find a property for enumeration.

Comments

An application can remove only those properties it has added. It must not remove properties added by other applications or by Windows itself.

See Also

»EnumProps«, »GetProp«, »RemoveProp«, »SetProp«


  EnumResLangProc

BOOL CALLBACK EnumResLangProc(hModule, lpszType, lpszName, wIDLanguage, lParam)
HANDLE  hModule;   /* resource-module handle */
LPCTSTR  lpszType;   /* address of resource type */
LPCTSTR  lpszName;   /* address of resource name */
WORD  wIDLanguage;   /* resource language identifier */
LONG  lParam;   /* application-defined parameter */

The EnumResLangProc function is an application-defined callback function that receives resource languages as a result of a call to the EnumResourceLanguages function.

Parameters

hModule

Identifies the module whose executable file contains the resources for which the languages are being enumerated. If this parameter is NULL, the function enumerates the resource languages in the module used to create the current process.

lpszType

Points to a null-terminated string specifying the type name of the resource for which the language is being enumerated. For standard resource types, this parameter should be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lpszName

Points to a null-terminated string specifying the name of the resource for which the language is being enumerated.

wIDLanguage

Specifies the language identifier for the resource for which the language is being enumerated. The EnumResourceLanguages function provides this value. For a list of the primary language identifiers and sublanguage identifiers that constitute a language identifier, see the »MAKELANGID« macro in the Microsoft Win32 Programmer's Reference, Volume 5.

lParam

Specifies the application-defined parameter passed to the EnumResourceLanguages function. This parameter can be used in error checking.

Return Value

This callback function should return TRUE to continue enumeration; otherwise, it should return FALSE to stop enumeration.

Comments

The EnumResLangProc function is a placeholder for the application-defined or library-defined function name.

See Also

»EnumResourceLanguages«


  EnumResNameProc

BOOL CALLBACK EnumResNameProc(hModule, lpszType, lpszName, lParam)
HANDLE  hModule;   /* resource-module handle */
LPCTSTR  lpszType;   /* address of resource type */
LPTSTR  lpszName;   /* address of resource name */
LONG  lParam;   /* application-defined parameter */

The EnumResNameProc function is an application-defined callback function that receives resource names as a result of a call to the EnumResourceNames function.

Parameters

hModule

Identifies the module whose executable file contains the resources for which the names are being enumerated. If this parameter is NULL, the function enumerates the resource names in the module used to create the current process.

lpszType

Points to a null-terminated string specifying the type name of the resource for which the name is being enumerated. For standard resource types, this parameter should be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lpszName

Points to a null-terminated string specifying the name of the resource for which the name is being enumerated.

lParam

Specifies the application-defined parameter passed to the EnumResourceNames function. This parameter can be used in error checking.

Return Value

This callback function should return TRUE to continue enumeration; otherwise, it should return FALSE to stop enumeration.

Comments

The EnumResNameProc function is a placeholder for the application-defined or library-defined function name.

See Also

»EnumResourceNames«


  EnumResourceLanguages

BOOL EnumResourceLanguages(hModule, lpszType, lpszName, lpEnumFunc, lParam)
HINSTANCE  hModule;   /* resource-module handle */
LPCTSTR  lpszType;   /* address of resource type */
LPCTSTR  lpszName;   /* address of resource name */
ENUMRESLANGPROC  lpEnumFunc;   /* address of callback function */
LONG  lParam;   /* application-defined parameter */

The EnumResourceLanguages function searches a module for each resource of the specified type and name and passes the language of each resource it locates to a defined callback function.

Parameters

hModule

Identifies the module whose executable file contains the resources for which the languages are to be enumerated. If this parameter is NULL, the function enumerates the resource languages in the module used to create the current process.

lpszType

Points to a null-terminated string specifying the type of the resource for which the language is being enumerated. For standard resource types, this parameter can be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lpszName

Points to a null-terminated string specifying the name of the resource for which the language is being enumerated.

lpEnumFunc

Points to the callback function to be called for each enumerated resource language. For more information, see the description of the »EnumResLangProc« function.

lParam

Specifies an application-defined value passed to the callback function. This parameter may be used in error checking.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The EnumResourceLanguages function continues to enumerate resource languages until the callback function returns FALSE or all resource languages have been enumerated.

See Also

»EnumResLangProc«, »EnumResourceNames«, »EnumResourceTypes«


  EnumResourceNames

BOOL EnumResourceNames(hModule, lpszType, lpEnumFunc, lParam)
HINSTANCE  hModule;   /* resource-module handling */
LPCTSTR  lpszType;   /* address of resource type */
ENUMRESNAMEPROC  lpEnumFunc;   /* address of callback function */
LONG  lParam;   /* application-defined parameter */

The EnumResourceNames function searches a module for each resource of the specified type passes the name of each resource it locates to an application-defined callback function.

Parameters

hModule

Identifies the module whose executable file contains the resources for which the names are to be enumerated. If this parameter is NULL, the function enumerates the resource names in the module used to create the current process.

lpszType

Points to a null-terminated string specifying the type name of the resource for which the name is being enumerated. For standard resource types, this parameter can be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lpEnumFunc

Points to the callback function to be called for each enumerated resource name. For more information, see the description of the »EnumResNameProc« function.

lParam

Specifies an application-defined value passed to the callback function. This parameter can be used in error checking.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The EnumResourceNames function continues to enumerate resource names until the callback function returns FALSE or all resource names have been enumerated.

See Also

»EnumResNameProc«, »EnumResourceLanguages«, »EnumResourceTypes«


  EnumResourceTypes

BOOL EnumResourceTypes(hModule, lpEnumFunc, lParam)
HINSTANCE  hModule;   /* resource-module handle */
ENUMRESTYPEPROC  lpEnumFunc;   /* address of callback function */
LONG  lParam;   /* application-defined parameter */

The EnumResourceTypes function searches a module for resources and passes each resource type it finds to an application-defined callback function.

Parameters

hModule

Identifies the module whose executable file contains the resources for which the types are to be enumerated. If this parameter is NULL, the function enumerates the resource types in the module used to create the current process.

lpEnumFunc

Points to the callback function to be called for each enumerated resource type. For more information, see the description of the »EnumResTypeProc« function.

lParam

Specifies an application-defined value passed to the callback function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The EnumResourceTypes function continues to enumerate resource types until the callback function returns FALSE or all resource types have been enumerated.

See Also

»EnumResourceLanguages«, »EnumResourceNames«, »EnumResTypeProc«


  EnumResTypeProc

BOOL CALLBACK EnumResTypeProc(hModule, lpszType, lParam)
HANDLE  hModule;   /* resource-module handle */
LPTSTR  lpszType;   /* address of resource type */
LONG  lParam;   /* application-defined parameter */

The EnumResTypeProc function is an application-defined callback function that receives resource types as a result of a call to the EnumResourceTypes function.

Parameters

hModule

Identifies the module whose executable file contains the resources for which the types are to be enumerated. If this parameter is NULL, the function enumerates the resource types in the module used to create the current process.

lpszType

Points to a null-terminated string specifying the type name of the resource for which the type is being enumerated. For standard resource types, this parameter can be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lParam

Specifies the application-defined parameter passed to the EnumResourceTypes function. This parameter can be used in error checking.

Return Value

The callback function should return TRUE to continue enumeration; otherwise, it should be FALSE to stop enumeration.

Comments

The EnumResTypeProc function is a placeholder for the application-defined or library-defined function name.

See Also

»EnumResourceTypes«


  EnumServicesStatus

BOOL EnumServicesStatus(schSCManager, fdwServiceType, fdwServiceState,
lpessServices, cbBufSize, lpcbBytesNeeded, lpdwServicesReturned, lpdwResumeHandle)
SC_HANDLE  schSCManager;   /* handle of service control manager database */
DWORD  fdwServiceType;   /* type of services to enumerate */
DWORD  fdwServiceState;   /* state of services to enumerate */
LPENUM_SERVICE_STATUS  lpessServices;   /* address of service status buffer */
DWORD  cbBufSize;   /* size of service status buffer */
LPDWORD  lpcbBytesNeeded;   /* address of variable for bytes needed */
LPDWORD  lpdwServicesReturned;   /* address of variable for number returned */
LPDWORD  lpdwResumeHandle;   /* address of variable for next entry */

The EnumServicesStatus function enumerates services in the specified service control manager database. The name and status of each service are provided.

Parameters

schSCManager

Identifies the service control manager database. The OpenSCManager function returns this handle which must have SC_MANAGER_ENUMERATE_SERVICE access.

fdwServiceType

Specifies the type of services to enumerate. It must be one or both of the following values:

Value	Meaning
SERVICE_WIN32	Enumerates services of type SERVICE_WIN32_OWN_PROCESS and SERVICE_WIN32_SHARE_PROCESS.
SERVICE_DRIVER	Enumerates services of type SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER.
fdwServiceState

Specifies the services to enumerate based on their running state. It must be one or both of the following values:

Value	Meaning
SERVICE_ACTIVE	Enumerates services that are in the following states: SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, and SERVICE_PAUSED.
SERVICE_INACTIVE	Enumerates services that are in the SERVICE_STOPPED state.
lpessServices

Points to an array of ENUM_SERVICE_STATUS structures in which the name and service status information for each service in the database is returned. The ENUM_SERVICE_STATUS structure has the following form:

typedef struct _ENUM_SERVICE_STATUS { /* ess */

    LPTSTR lpServiceName;

    LPTSTR lpDisplayName;

    SERVICE_STATUS ServiceStatus;

} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBufSize

Specifies the size, in bytes, of the buffer pointed to by the lpessServices parameter.

lpcbBytesNeeded

Points to a variable that receives the number of bytes needed to return the remaining service entries.

lpdwServicesReturned

Points to a variable that receives the number of service entries returned.

lpdwResumeHandle

Points to a 32-bit variable that, on input, specifies the starting point of enumeration. The first time this function is called, the variable's value is set to zero. On output, the variable's value is zero if the function succeeds. If the function returns FALSE and the GetLastError function returns ERROR_MORE_DATA, the variable's value is used to indicate the next unread service entry when the function is called again to retrieve the additional data.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with SC_MANAGER_ENUMERATE_SERVICE access.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_INVALID_PARAMETER
	A parameter that was specified is invalid.
ERROR_MORE_DATA
	There are more service entries than would fit into the lpessServices buffer. The actual number of service entries written to lpessServices is returned in the lpdwServicesReturned parameter. The number of bytes required to get the remaining entries is returned in the lpcbBytesNeeded parameter. The remaining services can be enumerated by additional calls to EnumServicesStatus with the lpdwResumeHandle parameter indicating the next service to read.
See Also

»EnumDependentServices«, »OpenSCManager«


  EnumTaskWindows

The EnumTaskWindows function is now obsolete. It has been replaced by the EnumThreadWindows function.

To maintain compatibility for older applications, EnumTaskWindows has been replaced with a macro that calls EnumThreadWindows. Older applications may continue to call EnumTaskWindows as previously documented, but new applications should use EnumThreadWindows.

See Also

»EnumThreadWindows«


  EnumThreadWindows

BOOL EnumThreadWindows(dwThreadId, lpfn, lParam)
DWORD  dwThreadId;   /* thread identifier */
WNDENUMPROC  lpfn;   /* address of callback function */
LPARAM  lParam;   /* application-defined value */

The EnumThreadWindows function enumerates all windows associated with a thread by passing the handle of each window, in turn, to an application-defined callback function. EnumThreadWindows continues until the last window is enumerated or the callback function returns FALSE.

Parameters

dwThreadId

Identifies the thread whose windows are to be enumerated.

lpfn

Points to an application-defined callback function. For more information about the callback function, see the description of the »EnumThreadWndProc« callback function.

lParam

Specifies a 32-bit application-defined value to be passed to the callback function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»EnumChildWindows«, »EnumThreadWndProc«, »EnumWindows«


  EnumThreadWndProc

BOOL CALLBACK EnumThreadWndProc(hwnd, lParam)
HWND  hwnd;   /* handle of window */
LPARAM  lParam;   /* application-defined value */

The EnumThreadWndProc function is an application-defined callback function that receives the window handles associated with a thread as a result of a call to the EnumThreadWindows function.

Parameters

hwnd

Identifies a window associated with the thread specified in the EnumThreadWindows function.

lParam

Specifies the application-defined value given in the EnumThreadWindows function.

Return Value

To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.

Comments

The callback function can carry out any desired task.

An application must register this callback function by passing its address to the EnumThreadWindows function. EnumThreadWndProc is a placeholder for the application-defined function name.

See Also

»EnumThreadWindows«


  EnumWindows

BOOL EnumWindows(wndenmprc, lParam)
WNDENUMPROC  wndenmprc;   /* address of callback function */
LPARAM  lParam;   /* application-defined value */

The EnumWindows function enumerates all top-level windows on the screen by passing the handle of each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.

Parameters

wndenmprc

Points to an application-defined callback function. For more information, see the description of the »EnumWindowsProc« callback function.

lParam

Specifies a 32-bit application-defined value to be passed to the callback function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The EnumWindows function does not enumerate child windows.

This function is more reliable than calling GetWindow in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle of a window that has been destroyed.

See Also

»EnumChildWindows«, »EnumWindowsProc«


  EnumWindowsProc

BOOL CALLBACK EnumWindowsProc(hwnd, lParam)
HWND  hwnd;   /* handle of parent window */
LPARAM  lParam;   /* application-defined value */

The EnumWindowsProc function is an application-defined callback function that receives top-level window handles as a result of a call to the EnumWindows function.

Parameters

hwnd

Identifies a top-level window.

lParam

Specifies the application-defined value given in the EnumWindows function.

Return Value

To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE.

Comments

The callback function can carry out any desired task.

An application must register this callback function by passing its address to the EnumWindows function. EnumWindowsProc is a placeholder for the application-defined function name.

See Also

»EnumWindows«


  EqualPrefixSid

BOOL EqualPrefixSid(psid1, psid2)
PSID  psid1;   /* address of first SID to compare */
PSID  psid2;   /* address of second SID to compare */

The EqualPrefixSid function tests two security-identifier (SID) prefix values for equality. An SID prefix is the entire SID except for the last subauthority value.

Parameters

psid1

Points to the first SID structure to compare. This structure is assumed to be valid.

psid2

Points to the second SID structure to compare. It also is assumed to be valid.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The EqualPrefixSid function enables a server application in one domain to verify an attempt by a user to log on to another domain. For example, if a user attempts to log on to RemoteDomain from a workstation in LocalDomain, the server for LocalDomain can request the SIDs for the user and the user's groups from RemoteDomain. The domain controller for RemoteDomain responds with the relevant SIDs.

All SIDs for a given domain necessarily have the same prefix. When the server receives the user's SIDs, it can call the EqualPrefixSid function for each SID, comparing the user or group SID against the SID for RemoteDomain. If any of the SID prefixes are not equal, the server refuses the logon attempt.

It is advisable to modify the SID for a domain before comparing it with a group or user SID. If the SID for RemoteDomain is S-1−1234−8, each group or user SID for that domain will have S-1−1234−8 as its prefix. To compare the SIDs by using the EqualPrefixSid function, an application copies the domain SID and adds any subauthority (RID) value to the copy, thereby creating an SID in the form S-1−1234−8−0. The application then uses the modified domain SID as a template against which the group and user SIDs are compared.

See Also

»CopySid«, »EqualSid«, »IsValidSid«


  EqualRect

BOOL EqualRect(lprc1, lprc2)
CONST RECT  *lprc1;   /* address of structure with first rectangle */
CONST RECT  *lprc2;   /* address of structure with second rectangle */

The EqualRect function determines whether the two specified rectangles are equal by comparing the coordinates of their upper left and lower right corners.

Parameters

lprc1

Points to a RECT structure that contains the logical coordinates of the first rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprc2

Points to a RECT structure that contains the logical coordinates of the second rectangle.

Return Value

If the two rectangles are identical, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»IsRectEmpty«, »PtInRect«


  EqualRgn

BOOL EqualRgn(hSrcRgn1, hSrcRgn2)
HRGN  hSrcRgn1;   /* handle of first region */
HRGN  hSrcRgn2;   /* handle of second region */

The EqualRgn function checks the two given regions to determine whether they are identical. The function considers two regions identical if they are equal in size and shape.

Parameters

hSrcRgn1

Identifies a region.

hSrcRgn2

Identifies a region.

Return Value

If the two regions are equal, the return value is TRUE; otherwise, it is FALSE. A return value of ERROR means at least one of the region handles is invalid.

See Also

»CreateRectRgn«, »CreateRectRgnIndirect«


  EqualSid

BOOL EqualSid(psid1, psid2)
PSID  psid1;   /* address of first SID to compare */
PSID  psid2;   /* address of second SID to compare */

The EqualSid function tests two security identifier (SID) values for equality. Two SIDs must match exactly to be considered equal.

Parameters

psid1

Points to the first SID structure to compare. This structure is assumed to be valid.

psid2

Points to the second SID structure to compare. It also is assumed to be valid.

Return Value

If the SID structures are equal, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLostError function.

If either SID structure is invalid, the return value is undefined.

See Also

»EqualPrefixSid«, »IsValidSid«


  EraseTape

DWORD EraseTape(hDevice, fdwEraseType, bImmediate)
HANDLE  hDevice;   /* handle of open device */
DWORD  fdwEraseType;   /* type of erasure to perform */
BOOL  bImmediate;   /* return after erase operation begins */

The EraseTape function erases all or part of a tape.

Parameters

hDevice

Identifies the device where the tape is to be erased. This handle is created by using the CreateFile function.

fdwEraseType

Specifies the erasing technique. This parameter can be one of the following values:

Value	Description
TAPE_ERASE_LONG	Erases the tape from the current position to the end of the current partition.
TAPE_ERASE_SHORT	Writes an erase gap or end-of-data marker at the current position.
bImmediate

Specifies whether to return as soon as the erase operation begins. If this parameter is TRUE, the function returns immediately; if it is FALSE, the function does not return until the erase operation has been completed.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

Some tape devices do not support certain tape operations. See your tape device documentation and use the »GetTapeParameters« function to determine your tape device's capabilities.


  Escape

int Escape(hdc, nEscape, cbInput, lpvInData, lpvOutData)
HDC  hdc;   /* handle of device context */
int  nEscape;   /* escape function */
int  cbInput;   /* size of structure for input */
LPCSTR  lpvInData;   /* address of input structure */
LPVOID  lpvOutData;   /* address of output structure */

The Escape function allows applications to access capabilities of a particular device not directly available through GDI. Escape calls made by an application are translated and sent to the driver.

Parameters

hdc

Identifies the device context.

nEscape

Specifies the escape function to be performed. This parameter must be one of the predefined escape values. Use the ExtEscape function if your application defines a private escape value.

cbInput

Specifies the number of bytes of data pointed to by the lpvInData parameter.

lpvInData

Points to the input structure required for the specified escape.

lpvOutData

Points to the structure that receives output from this escape. This parameter should be NULL if no data is returned.

Return Value

If the function succeeds, the return value is greater than zero, except with the QUERYESCSUPPORT printer escape, which checks for implementation only. If the escape is not implemented, the return value is zero. Otherwise, the return value is an error. To get extended error information, use the GetLastError function.

Errors

If the function fails, the return value is one of the following:

Value	Meaning
SP_ERROR	General error.
SP_OUTOFDISK	Not enough disk space is currently available for spooling, and no more space will become available.
SP_OUTOFMEMORY	Not enough memory is available for spooling.
SP_USERABORT	User terminated the job through Windows Print Manager.
Comments

The Win32 API provides six new functions that supersede some printer escapes:

Function	Description
AbortDoc	Terminates a print job. Supersedes the ABORTDOC escape.
EndDoc	Ends a print job. Supersedes the ENDDOC escape.
EndPage	Ends a page. Supersedes the NEWFRAME escape. Unlike NEWFRAME, this function is always called after printing a page.
SetAbortProc	Sets the abort function for a print job. Supersedes the SETABORTPROC escape.
StartDoc	Starts a print job. Supersedes the STARTDOC escape.
StartPage	Prepares printer driver to receive data.
The ResetDC function was new for Windows version 3.1. ResetDC updates a device context, allowing such new functionality as changing the paper orientation or paper bin within a single print job. This ability was not supported by an escape in previous versions of Windows.

Following is a list of the obsolete printer escapes that are supported only for compatibility with earlier versions of Windows:

Escape	Description
ABORTDOC	Stops the current print job and erases everything the application has written to the device since the last ENDDOC escape.
ENDDOC	Ends a print job started by the STARTDOC escape.
GETPHYSPAGESIZE	Retrieves the physical page size and copies it to the specified location.
GETPRINTINGOFFSET	Retrieves the offset from the upper-left corner of the physical page where the actual printing or drawing begins.
GETSCALINGFACTOR	Retrieves the scaling factors for the x-axis and the y-axis of a printer.
NEWFRAME	Informs the printer that the application has finished writing to a page.
NEXTBAND	Informs the printer that the application has finished writing to a band.
PASSTHROUGH	Allows the application to send data directly to a printer.
SETABORTPROC	Sets the Abort function for a print job.
STARTDOC	Informs a printer driver that a new print job is starting.


  EscapeCommFunction

BOOL EscapeCommFunction(hCommDev, fdwFunc)
HANDLE  hCommDev;   /* handle of the communications device */
DWORD  fdwFunc;   /* extended function to perform */

The EscapeCommFunction function directs a given communications device to perform an extended function.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

fdwFunc

Specifies the code of the extended function to perform. This parameter can be one of the following values:

Value	Meaning
CLRDTR	Clears the DTR (data-terminal-ready) signal.
CLRRTS	Clears the RTS (request-to-send) signal.
SETDTR	Sends the DTR (data-terminal-ready) signal.
SETRTS	Sends the RTS (request-to-send) signal.
SETXOFF	Causes transmission to act as if an XOFF character has been received.
SETXON	Causes transmission to act as if an XON character has been received.
SETBREAK	Suspends character transmission and places the transmission line in a break state until the ClearCommBreak function is called (or EscapeCommFunction is called with the CLRBREAK extended function code). The SETBREAK extended function is identical to the SetCommBreak function. Note that this extended function does not flush data that has not been transmitted.
CLRBREAK	Restores character transmission and places the transmission line in a non-break state. The CLRBREAK extended function is identical to the ClearCommBreak function.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»ClearCommBreak«, »SetCommBreak«


  ExcludeClipRect

int ExcludeClipRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coordinate of upper-left corner of rectangle */
int  nTopRect;   /* y-coordinate of upper-left corner of rectangle */
int  nRightRect;   /* x-coordinate of lower-right corner of rectangle */
int  nBottomRect;   /* y-coordinate of lower-right corner of rectangle */

The ExcludeClipRect function creates a new clipping region that consists of the existing clipping region minus the specified rectangle.

Parameters

hdc

Identifies the device context.

nLeftRect

Specifies the logical x-coordinate of the upper-left corner of the rectangle.

nTopRect

Specifies the logical y-coordinate of the upper-left corner of the rectangle.

nRightRect

Specifies the logical x-coordinate of the lower-right corner of the rectangle.

nBottomRect

Specifies the logical y-coordinate of the lower-right corner of the rectangle.

Return Value

If the function succeeds, the return value specifies the new clipping region's complexity. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	No region was created.
Comments

The lower and right edges of the given rectangle are not excluded from the clipping region.

See Also

»IntersectClipRect«


  ExcludeUpdateRgn

int ExcludeUpdateRgn(hdc, hwnd)
HDC  hdc;   /* handle of device context */
HWND  hwnd;   /* handle of window */

The ExcludeUpdateRgn function prevents drawing within invalid areas of a window by excluding an updated region in the window from a clipping region.

Parameters

hdc

Identifies the device context associated with the clipping region.

hwnd

Identifies the window to be updated.

Return Value

The return value specifies the complexity of the excluded region; it can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region consists of more than one rectangle.
ERROR	An error occurred.
See Also

»BeginPaint«, »GetUpdateRect«, »GetUpdateRgn«, »UpdateWindow«


  ExitProcess

VOID ExitProcess(uExitCode)
UINT  uExitCode;   /* exit code for all threads */

The ExitProcess function ends a process and all its threads.

Parameters

uExitCode

Specifies the exit code for the process, and for all threads that are terminated as a result of this call. Use the GetExitCodeProcess function to retrieve the process's exit code. Use the GetExitCodeThread function to retrieve a thread's exit code.

Return Value

This function does not return a value.

Comments

The ExitProcess function is the preferred method of ending a process. This function provides a clean process shutdown. This includes calling the entrypoint function of all attached DLLs with a code indicating that the process is detaching from the DLL. If a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination.

After all attached DLLs have executed any process termination code, this function terminates the current process.

Terminating a process causes the following:

1.	All of the object handles opened by the process are closed.

2.	All of the threads in the process terminate their execution.

3.	The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.

4.	The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.

5.	The termination status of the process changes from STILL_ACTIVE to the exit code of the process.

Terminating a process does not cause child processes to be terminated.

Terminating a process does not necessarily remove the process object from the operating system. A process object is deleted when the last handle to the process is closed.

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

1.	During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

2.	Only one thread in a process can be in a DLL initialization or detach routine at a time.

3.	The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

See Also

»CreateProcess«, »CreateRemoteThread«, »CreateThread«, »ExitThread«, »GetExitCodeProcess«, »GetExitCodeThread«, »OpenProcess« »TerminateProcess«


  ExitThread

VOID ExitThread(dwExitCode)
DWORD  dwExitCode;   /* exit code for this thread */

The ExitThread function ends a thread.

Parameters

dwExitCode

Specifies the exit code for the calling thread. Use the GetExitCodeThread function to retrieve a thread's exit code.

Return Value

This function does not return a value.

Comments

The ExitThread function is the preferred method of exiting a thread. When this function is called (either explicitly or by returning from a thread procedure), the current thread's stack is deallocated and the thread terminates. The entrypoint function of all attached DLLs is invoked with a code indicating that the thread is detaching from the DLL.

If the thread is the last thread in the process when this function is called, the thread's process is also terminated.

The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.

Terminating a thread does not necessarily remove the thread object from the operating system. A thread object is deleted when the last handle to the thread is closed.

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

1.	During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

2.	Only one thread in a process can be in a DLL initialization or detach routine at a time.

3.	The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

See Also

»CreateProcess«, »CreateRemoteThread«, »CreateThread«, »ExitProcess«, »GetExitCodeThread«, »TerminateThread«


  ExitWindows

BOOL ExitWindows(dwReserved, uReturnCode)
DWORD  dwReserved;   /* reserved */
UINT  uReserved;   /* reserved */

The ExitWindows function logs the current user off.

Parameters

dwReserved

Reserved; must be zero.

uReserved

Reserved; must be zero.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ExitWindows function asks applications if they want to terminate by sending the WM_QUERYENDSESSION message to the main window of all running applications. An application agrees to terminate by returning TRUE when it receives this message (or by allowing the DefWindowProc function to process the message). If any application returns FALSE when it receives the WM_QUERYENDSESSION message, the shutdown is canceled.

After Windows processes the results of the WM_QUERYENDSESSION message, it sends the WM_ENDSESSION message with the wParam parameter set to TRUE if the system is shutting down and to FALSE if it is not.

Windows does not allow new applications to start up during the shutdown process.

See Also

»ExitWindowsEx«


  ExitWindowsEx

BOOL ExitWindowsEx(fuOptions, dwReserved)
UINT  fuOptions;   /* shutdown operation */
DWORD  dwReserved;   /* reserved */

The ExitWindowsEx function either logs off, shuts down, or shuts down and restarts the system.

Parameters

fuOptions

Specifies the type of shutdown. This parameter must be some combination of the following values:

Value	Action
EWX_FORCE	Forces processes to terminate. Instead of bringing up the "application not responding" dialog box for the user, this flag forces an application to terminate if it does not respond.
EWX_LOGOFF	Shuts down all processes running in the security context of the process that called the ExitWindowsEx function. It then logs the user off.
EWX_REBOOT	Shuts down the system and then restarts the system. The application must have the SE_SHUTDOWN_NAME privilege (For more information, see the Comments section).
EWX_SHUTDOWN	Shuts down the system to a point at which it is safe to turn off the power. All file buffers have been flushed to disk, and all running processes have stopped. The application must have the SE_SHUTDOWN_NAME privilege (For more information, see the Comments section).
dwReserved

Reserved. This parameter is ignored.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. For more information about security privileges, see Chapter 49, "Security," in Microsoft Win32 Programmer's Reference, Volume 2.

This function returns as soon as it has initiated the shutdown. The shutdown or logoff then proceeds asynchronously.

During a shutdown or log-off operation, applications that are shut down are allowed a specific amount of time to respond to the shutdown request. If the time expires, Windows displays a dialog box that allows the user to forcibly shut down the application, to retry the shutdown, or to cancel the shutdown request. If the EWX_FORCE flag is specified, Windows always forces applications to close and does not display the dialog box.

See Also

»ExitWindows«


  ExpandEnvironmentStrings

DWORD ExpandEnvironmentStrings(lpszSrc, lpszDest, cchDest)
LPCTSTR  lpszSrc;   /* address of string with environment variables */
LPTSTR  lpszDest;   /* address of string with expanded env. variables */
DWORD  cchDest;   /* maximum chars. in expanded string */

The ExpandEnvironmentStrings function expands environment-variable strings and replaces them with their defined values.

Parameters

lpszSrc

Points to a null-terminated string that might contain references to environment-variable strings of the form "%variableName%". For each such reference, the %variableName% portion is replaced with the current value of that environment variable.

The replacement rules are the same as those used by the command interpreter. Case is ignored when looking up the environment-variable name. If the name is not found, the %variableName% portion is left undisturbed.

lpszDest

Points to a buffer to receive a copy of the source buffer, after all environment-variable name substitutions have been performed.

cchDest

Specifies the maximum number of characters that can be stored in the buffer pointed to by the lpszDest parameter, including the terminating null character.

Return Value

If the function succeeds, the return value is the number of characters stored in the destination buffer. If the number of characters is greater than the size of the destination buffer, the return value is the size of the buffer required to hold the expanded strings.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.


  ExtCreateFontIndirect

HFONT ExtCreateFontIndirect(pExtLogFont)
LPEXTLOGFONT  pExtLogFont;   /* address of logical font structure */

The ExtCreateFontIndirect function creates a logical font.

Parameters

pExtLogFont

Points to an EXTLOGFONT structure that defines the characteristics of the logical font. The EXTLOGFONT structure has the following form:

typedef struct tagEXTLOGFONT {

    LOGFONT elfLogFont;

    BYTE    elfFullName[LF_FULLFACESIZE];

    BYTE    elfStyle[LF_FACESIZE];

    DWORD   elfVersion;

    DWORD   elfStyleSize;

    DWORD   elfMatch;

    DWORD   elfReserved;

    BYTE    elfVendorId[ELF_VENDOR_SIZE];

    DWORD   elfCulture;

    PANOSE  elfPanose;

} EXTLOGFONT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle of the logical font; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

This function is an extension of the CreateFont and CreateFontIndirect functions. (The handle returned by ExtCreateFontIndirect is identical to the handles returned by either of these two functions.)

The ExtCreateFontIndirect function creates a logical font that has all the specified characteristics. When an application calls the SelectObject function to select the desired font, the graphics device interface (GDI) font mapper attempts to match the logical font with an existing physical font. If it fails to find an exact match, it provides an alternative font whose characteristics match as many of the requested characteristics as possible.

See Also

»CreateFont«, »CreateFontIndirect«, »SelectObject«


  ExtCreatePen

HPEN ExtCreatePen(dwPenStyle, dwWidth, lplb, dwStyleCount, lpStyle)
DWORD  dwPenStyle;   /* pen style */
DWORD  dwWidth;   /* pen width */
LPLOGBRUSH  lplb;   /* address of struc. for brush attributes */
DWORD  dwStyleCount;   /* length of array containing custom style bits */
LPDWORD  lpStyle;   /* optional array of custom style bits */

The ExtCreatePen function creates a logical cosmetic or geometric pen that has the specified style, width, and brush attributes.

Parameters

dwPenStyle

Specifies a combination of type, style, end cap, and join attributes. The values from each category should be combined by using the bitwise OR operator (|).

The pen type can be one of the following values:

Type	Description
PS_GEOMETRIC	Pen is geometric.
PS_COSMETIC	Pen is cosmetic.
The pen style can be any one of the following values:

Style	Description
PS_ALTERNATE	Pen sets every other pixel. (This style is applicable only for cosmetic pens.)
PS_SOLID	Pen is solid.
PS_DASH	Pen is dashed.
PS_DOT	Pen is dotted.
PS_DASHDOT	Pen has alternating dashes and dots.
PS_DASHDOTDOT	Pen has alternating dashes and double dots.
PS_NULL	Pen is invisible.
PS_USERSTYLE	Pen uses a styling array supplied by the user.
PS_INSIDEFRAME	Pen is solid. When this pen is used in any graphics device interface (GDI) drawing function that takes a bounding rectangle, the dimensions of the figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to geometric pens.
The end cap can be one of the following values:

End cap	Description
PS_ENDCAP_ROUND	End caps are round.
PS_ENDCAP_SQUARE	End caps are square.
PS_ENDCAP_FLAT	End caps are flat.
The join can be one of the following values:

Line join	Description
PS_JOIN_BEVEL	Joins are beveled.
PS_JOIN_MITER	Joins are mitered when they are within the current limit set by the SetMiterLimit function. If it exceeds this limit, the join is beveled.
PS_JOIN_ROUND	Joins are round.
dwWidth

Specifies the width of the pen. If the dwPenStyle parameter is PS_GEOMETRIC, the width is given in logical units. If dwPenStyle is PS_COSMETIC, the width must be set to 1.

lplb

Points to a LOGBRUSH structure. If dwPenStyle is PS_COSMETIC, the lbColor member specifies the color of the pen and the lbStyle member must be set to BS_SOLID. If dwPenStyle is PS_GEOMETRIC, all members must be used to specify the brush attributes of the pen. The LOGBRUSH structure has the following form:

typedef struct tagLOGBRUSH { /* lb */

   UINT     lbStyle;

   COLORREF lbColor;

   LONG     lbHatch;

} LOGBRUSH;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwStyleCount

Specifies the length, in doubleword units, of the lpStyle array. This value must be zero if dwPenStyle is not PS_USERSTYLE.

lpStyle

Points to an array of doubleword values. The first value specifies the length of the first dash in a user-defined style, the second value specifies the length of the first space, and so on. This pointer must be NULL if dwPenStyle is not PS_USERSTYLE.

Return Value

If the function succeeds, the return value is a handle that identifies a logical pen; otherwise, it is zero.

Comments

The width of a cosmetic pen is always 1; the width of a geometric pen is always specified in world units.

After an application creates a logical pen, it can select that pen into a device context by calling the SelectObject function. After a pen is selected into a device context, it can be used to draw lines and curves.

If dwPenStyle is PS_COSMETIC and PS_USERSTYLE, the entries in the lpStyle array specify lengths of dashes and spaces in style units. A style unit is defined by the device where the pen is used to draw a line.

If dwPenStyle is PS_GEOMETRIC and PS_USERSTYLE, the entries in the lpStyle array specify lengths of dashes and spaces in logical units.

If dwPenStyle is PS_ALTERNATE, the style unit is ignored and every other pixel is set.

When an application no longer requires a given pen, it should call the DeleteObject function to delete the pen from the device context.

See Also

»CreatePen«, »CreatePenIndirect«, »DeleteObject«, »GetObject«, »SelectObject«


  ExtCreateRegion

HRGN ExtCreateRegion(lpXform, nCount, lpRgnData)
LPXFORM  lpXform;   /* address of transformation data */
DWORD  nCount;   /* size of structure containing region data */
LPRGNDATA  lpRgnData;   /* address of region data */

The ExtCreateRegion function creates a region from the given region and transformation data.

Parameters

lpXform

Points to an XFORM structure that defines the transformation to be performed on the region. If this pointer is NULL, the identity transformation is used. The XFORM structure has the following form:

typedef struct  tagXFORM {  /* xfrm */

    FLOAT eM11;

    FLOAT eM12;

    FLOAT eM21;

    FLOAT eM22;

    FLOAT eDx;

    FLOAT eDy;

} XFORM;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

nCount

Specifies the number of bytes pointed to by lpRgnData.

lpRgnData

Points to a RGNDATA structure that contains the region data. The RGNDATA structure has the following form:

typedef struct _RGNDATA { /* rgnd */

    RGNDATAHEADER rdh;

    char          Buffer[1];

} RGNDATA;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the value of the region; otherwise, it is NULL.

Comments

An application can retrieve data for a region by calling the GetRegionData function.

See Also

»GetRegionData«


  ExtEscape

int ExtEscape(hdc, nEscape, cbInput, lpszInData, cbOutput, lpszOutData)
HDC  hdc;   /* handle of device context */
int  nEscape;   /* escape function */
int  cbInput;   /* size of structure for input */
LPCSTR  lpszInData;   /* address of input structure */
int  cbOutput;   /* size, in bytes, of output data */
LPSTR  lpszOutData;   /* address of output structure */

The ExtEscape function allows applications to access capabilities of a particular device that are not available through GDI.

Parameters

hdc

Identifies the device context.

nEscape

Specifies the escape function to be performed.

cbInput

Specifies the number of bytes of data pointed to by the lpszInData parameter.

lpszInData

Points to the input structure required for the specified escape.

cbOutput

Specifies the number of bytes of data pointed to by the lpszOutData parameter.

lpszOutData

Points to the structure that receives output from this escape. This parameter should be NULL if no data is returned.

Return Value

The return value specifies the outcome of the function. It is greater than zero if the function is successful, except for the QUERYESCSUPPORT printer escape, which checks for implementation only. The return value is zero if the escape is not implemented. A return value less than zero indicates an error. To get extended error information, use the GetLastError function.

Comments

Use this function to pass a driver-defined escape value to a device.

Use the Escape function to pass one of the escape values defined by Windows to a device.

See Also

»Escape«, »GetDeviceCaps«


  ExtFloodFill

BOOL ExtFloodFill(hdc, nXStart, nYStart, crColor, fuFillType)
HDC  hdc;   /* handle of device context */
int  nXStart;   /* x-coordinate where filling begins */
int  nYStart;   /* y-coordinate where filling begins */
COLORREF  crColor;   /* fill color */
UINT  fuFillType;   /* fill type */

The ExtFloodFill function fills an area of the display surface with the current brush.

Parameters

hdc

Identifies a device context.

nXStart

Specifies the logical x-coordinate of the point where filling is to begin.

nYStart

Specifies the logical y-coordinate of the point where filling is to begin.

crColor

Specifies the color of the boundary or of the area to be filled. The interpretation of crColor depends on the value of the fuFillType parameter.

fuFillType

Specifies the type of fill operation to be performed. It must be one of the following values:

Value	Meaning
FLOODFILLBORDER	The fill area is bounded by the color specified by the crColor parameter. This style is identical to the filling performed by the FloodFill function.
FLOODFILLSURFACE	The fill area is defined by the color that is specified by crColor. Filling continues outward in all directions as long as the color is encountered. This style is useful for filling areas with multicolored boundaries.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Following are some of the reasons this function might fail:

•	The filling could not be completed.

•	The given point has the boundary color specified by the crColor parameter (if FLOODFILLBORDER was requested).

•	The given point does not have the color specified by crColor (if FLOODFILLSURFACE was requested).

•	The point is outside the clipping region — that is, it is not visible on the device.

If the fuFillType parameter is FLOODFILLBORDER, Windows assumes that the area to be filled is completely bounded by the color specified by the crColor parameter. The function begins filling at the point specified by the nXStart and nYStart parameters and continues in all directions until it reaches the boundary.

If fuFillType is FLOODFILLSURFACE, Windows assumes that the area to be filled is a single color. The function begins to fill the area at the point specified by nXStart and nYStart and continues in all directions, filling all adjacent regions containing the color specified by crColor.

Only memory device contexts and devices that support raster-display operations support the ExtFloodFill function. To determine whether a device supports this technology, an application can call the GetDeviceCaps function.

See Also

»GetDeviceCaps«


  ExtractIcon

HICON ExtractIcon(hInst, lpszExeName, nIconIndex)
HINSTANCE  hInst;   /* instance handle */
LPCTSTR  lpszExeName;   /* filename of file with icon */
UINT  nIconIndex;   /* index of icon to extract */

The ExtractIcon function retrieves the handle of an icon from the given executable file, dynamic-link library (DLL), or icon file.

Parameters

hInst

Identifies the instance of the application calling the function.

lpszExeName

Points to a null-terminated string specifying the name of an executable file, DLL, or icon file.

nIconIndex

Specifies the index of the icon to retrieve. If this value is 0, the function returns the handle of the first icon in the specified file. If this value is −1, the function returns the total number of icons in the specified file.

Return Value

If the function succeeds, the return value is the handle of an icon. If the file specified was not an executable file, DLL, or icon file, the return is 1. If no icons were found in the file, the return value is NULL.


  ExtSelectClipRgn

int ExtSelectClipRgn(hdc, hrgn, fnMode)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region */
int  fnMode;   /* region-selection mode */

The ExtSelectClipRgn function combines the given region with the current clipping region by using the specified mode.

Parameters

hdc

Identifies the device context.

hrgn

Identifies the region to be selected. This handle can only be NULL when the RGN_COPY mode is specified.

fnMode

Specifies the operation to be performed. It must be one of the following values:

Value	Meaning
RGN_AND	The new clipping region combines the overlapping areas of the current clipping region and the region identified by hrgn.
RGN_COPY	The new clipping region is a copy of the region identified by hrgn. This is identical to SelectClipRgn. If the region identified by hrgn is NULL, the new clipping region is the default clipping region (the default clipping region is a null region).
RGN_DIFF	The new clipping region combines the areas of the current clipping region with those areas excluded from the region identified by hrgn.
RGN_OR	The new clipping region combines the current clipping region and the region identified by hrgn.
RGN_XOR	The new clipping region combines the current clipping region and the region identified by hrgn but excludes any overlapping areas.
Return Value

If the function succeeds, the return value specifies the new clipping region's complexity. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred.
Comments

If an error occurs when this function is called, the previous clipping region for the given device context is not affected.

The ExtSelectClipRgn function assumes that the coordinates for the given region are specified in device units.

Only a copy of the given region identified by the hrgn parameter is used. The region itself can be reused after this call or it can be deleted.

See Also

»SelectClipRgn«


  ExtTextOut

BOOL ExtTextOut(hdc, X, Y, fuOptions, lprc, lpszString, cbCount, lpDx)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of reference point */
int  Y;   /* y-coordinate of reference point */
UINT  fuOptions;   /* text-output options */
CONST RECT  *lprc;   /* optional clipping and/or opaquing rectangle */
LPCTSTR  lpszString;   /* address of string */
UINT  cbCount;   /* number of characters in string */
LPINT  lpDx;   /* address of array of inter-character spacing values */

The ExtTextOut function draws a character string by using the currently selected font. An optional rectangle may be provided, to be used for clipping, opaquing, or both.

Parameters

hdc

Identifies the device context.

X

Specifies the logical x-coordinate of the reference point used to position the string.

Y

Specifies the logical y-coordinate of the reference point used to position the string.

fuOptions

Specifies how to use the application-defined rectangle. This parameter can be a combination of the following values:

Value	Meaning
ETO_CLIPPED	The text will be clipped to the rectangle.
ETO_OPAQUE	The current background color should be used to fill the rectangle.
lprc

Points to an optional RECT structure that specifies the dimensions of a rectangle that is used to clip the string of text and/or to fill the text background by using the current background color. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpszString

Points to the character string to be drawn.

cbCount

Specifies the number of characters in the string.

lpDx

Points to an optional array of values that indicate the distance between origins of adjacent character cells. For example, lpDx[i] logical units separate the origins of character cell i and character cell i + 1.

Return Value

If the string is drawn, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The current text-alignment settings for the specified device context determine how the reference point is used to position the text. The text-alignment settings are retrieved by calling the GetTextAlign function. The text-alignment settings are altered by calling the SetTextAlign function.

If the lpDx parameter is NULL, the function uses the default spacing between characters. The character-cell origins and the contents of the array pointed to by the lpDx parameter are given in logical units. A character-cell origin is defined as the upper left corner of the character cell.

By default, the current position is not used or updated by this function. However, an application can call the SetTextAlign function with the fMode parameter set to TA_UPDATECP to permit Windows to use and update the current position each time the application calls ExtTextOut for a given device context. When this flag is set, Windows ignores the X and Y parameters on subsequent ExtTextOut calls.

See Also

»GetTextAlign«, »SetTextAlign«


  FatalAppExit

VOID FatalAppExit(uAction, lpszMessageText)
UINT  uAction;   /* reserved */
LPCTSTR  lpszMessageText;   /* address of string to display in message box */

The FatalAppExit function displays a message box and terminates the application when the message box is closed. If Windows is running with a kernel debugger, the message box gives the user the opportunity to terminate the application or to cancel the message box and return to the application that called FatalAppExit.

Parameters

uAction

Reserved; must be zero.

lpszMessageText

Points to a null-terminated string that is displayed in the message box. The message is displayed on a single line. To accommodate low-resolution screens, the string should be no more than 35 characters in length.

Return Value

This function does not return a value.

Comments

An application calls FatalAppExit only when it is not capable of terminating any other way. FatalAppExit may not always free an application's memory or close its files, and it may cause a general failure of Windows. An application that encounters an unexpected error should terminate by freeing all its memory and returning from its main message loop.

See Also

»FatalExit«


  FatalExit

VOID FatalExit(nExitCode)
int  nExitCode;   /* error code */

The FatalExit function transfers execution control to the debugger. The behavior of the debugger thereafter is specific to the type of debugger used.

Parameters

nExitCode

Specifies the error code associated with this exit.

Return Value

This function does not return a value.

Comments

An application should only use FatalExit for debugging purposes. It should not call the function in a retail version of the application because doing so will terminate the application.

See Also

»FatalAppExit«


  FileIOCompletionRoutine

VOID WINAPI FileIOCompletionRoutine(fdwError, cbTransferred, lpo)
DWORD  fdwError;   /* completion code */
DWORD  cbTransferred;   /* number of bytes transferred */
LPOVERLAPPED  lpo;   /* address of structure with I/O information */

The FileIOCompletionRoutine function is called when an asynchronous input and output (I/O) function (ReadFileEx or WriteFileEx) is completed and the calling thread is in an alertable wait (using the SleepEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx function with the fAlertable flag set to TRUE).

Parameters

fdwError

Specifies the I/O completion status. This may be one of the following values:

Value	Meaning
0	The I/O was successful.
ERROR_HANDLE_EOF	The ReadFileEx function tried to read past the end of the file.
cbTransferred

Specifies the number of bytes transferred. This parameter is zero if an error occurs.

lpo

Points to the OVERLAPPED structure specified by the asynchronous I/O function. The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Windows does not use the hEvent member of the OVERLAPPED structure; the calling application may use this member to pass information to the completion routine. Windows does not use the OVERLAPPED structure after the completion routine is called, so the completion routine can deallocate the memory used by the overlapped structure.

Return Value

This function does not return a value.

Comments

FileIOCompletionRoutine is a placeholder for an application-defined or library-defined function name.

Returning from this function allows another pending I/O completion routine to be called. All waiting completion routines are called before the alertable thread's wait is satisfied with a return code of WAIT_IO_COMPLETION. Windows may call the waiting completion routines in any order. They may or may not be called in the order the I/O functions are completed.

Each time Windows calls a completion routine, it uses some of the application's stack. If the completion routine does additional asynchronous I/O and alertable waits, the stack may grow.

See Also

»ReadFileEx«, »SleepEx«, »WaitForMultipleObjectsEx«, »WaitForSingleObjectEx«, »WriteFileEx«


  FileTimeToDosDateTime

BOOL FileTimeToDosDateTime(lpft, lpwDOSDate, lpwDOSTime)
LPFILETIME  lpft;   /* address of 64-bit file time */
LPWORD  lpwDOSDate;   /* address of variable for MS-DOS date */
LPWORD  lpwDOSTime;   /* address of variable for MS-DOS time */

The FileTimeToDosDateTime function converts a 64-bit file time to MS-DOS date and time values.

Parameters

lpft

Points to a FILETIME structure containing the 64-bit file time to convert to MS-DOS date and time format.

The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpwDOSDate

Points to a variable to receive the MS-DOS date. The date is a packed 16-bit value with the following format:

Bits	Contents
0−4	Day of the month (1−31)
5−8	Month (1 = January, 2 = February, etc.)
9−15	Year offset from 1980 (add 1980 to get actual year)
lpwDOSTime

Points to a variable to receive the MS-DOS time. The time is a packed 16-bit value with the following format:

Bits	Contents
0−4	Second divided by 2
5−10	Minute (0−59)
11−15	Hour (0−23 on a 24-hour clock)
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The MS-DOS date format can represent only dates between 1/1/1980 and 12/31/2107; this conversion fails if the input file time is outside this range.

See Also

»DosDateTimeToFileTime«, »FileTimeToSystemTime«, »SystemTimeToFileTime«


  FileTimeToLocalFileTime

BOOL FileTimeToLocalFileTime(LPFILETIME lpft, LPFILETIME lpftLocal)
LPFILETIME  lpft;   /* address of UTC file time to convert */
LPFILETIME  lpftLocal;   /* address of converted file time */

The FileTimeToLocalFileTime function converts a file time based on the Coordinated Universal Time (UTC) to a local file time.

Parameters

lpft

Points to a FILETIME structure containing the UTC-based file time to be converted into a local file time. The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpftLocal

Points to a FILETIME structure to receive the converted local file time. This parameter cannot be the same as the lpft parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»LocalFileTimeToFileTime«


  FileTimeToSystemTime

BOOL FileTimeToSystemTime(lpft, lpst)
LPFILETIME  lpft;   /* address of file time to convert */
LPSYSTEMTIME  lpst;   /* address of converted system time */

The FileTimeToSystemTime function converts a 64-bit file time to system time format.

Parameters

lpft

Points to a FILETIME structure containing the file time to convert to system date and time format. The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpst

Points to a SYSTEMTIME structure to receive the converted file time. The SYSTEMTIME structure has the following form:

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»DosDateTimeToFileTime«, »FileTimeToDosDateTime«, »SystemTimeToFileTime«


  FillConsoleOutputAttribute

BOOL FillConsoleOutputAttribute(hConsole, wAttribute, cCharCells, coordAttr, lpcWritten)
HANDLE  hConsole;   /* handle of screen buffer */
WORD  wAttribute;   /* color attribute to write */
DWORD  cCharCells;   /* number of character cells to write to */
COORD  coordAttr;   /* x- and y-coordinates of first cell */
LPDWORD  lpcWritten;   /* address of number of cells written to */

The FillConsoleOutputAttribute function sets the text and background color attributes for a specified number of character cells, beginning at the given coordinates in a screen buffer.

Parameters

hConsole

Identifies a screen buffer. The handle must have GENERIC_WRITE access.

wAttribute

Specifies the foreground and background color attributes to write to the screen buffer. Any combination of the following values can be specified: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces white text on a black background.

    FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE

cCharCells

Specifies the number of character cells to be set to the specified color attributes.

coordAttr

Specifies a COORD structure containing the screen buffer coordinates of the first cell whose attributes are to be set. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcWritten

Points to the variable that receives the number of character cells whose attributes were actually set.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of character cells whose attributes are to be set extends beyond the end of the specified row in the screen buffer, the cells of the next row are set. If the number of cells to write to extends beyond the end of the screen buffer, the cells are written up to the end of the screen buffer.

The character values at the positions written to are not changed.

See Also

»FillConsoleOutputCharacter«, »SetConsoleTextAttribute«, »WriteConsoleOutputAttribute«


  FillConsoleOutputCharacter

BOOL FillConsoleOutputCharacter(hConsole, chFillChar, cCharCells, coordChar, lpcWritten)
HANDLE  hConsole;   /* handle of screen buffer */
TCHAR  chFillChar;   /* character to write */
DWORD  cCharCells;   /* number of character cells to write to */
COORD  coordChar;   /* x- and y-coordinates of first cell */
LPDWORD  lpcWritten;   /* address of number of cells written to */

The FillConsoleOutputCharacter function writes a character to the screen buffer a specified number of times, beginning at the given coordinates.

Parameters

hConsole

Identifies a screen buffer. The handle must have GENERIC_WRITE access.

chFillChar

Specifies the character to write to the screen buffer.

cCharCells

Specifies the number of character cells to write the character to.

coordChar

Specifies a COORD structure containing the screen buffer coordinates of the first cell to write the character to. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcWritten

Points to the variable that receives the number of characters actually written to the screen buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of characters to write to extends beyond the end of the specified row in the screen buffer, characters are written to the next row. If the number of characters to write to extends beyond the end of the screen buffer, the characters are written up to the end of the screen buffer.

The attribute values at the positions written are not changed.

See Also

»FillConsoleOutputAttribute«, »WriteConsoleOutputCharacter«


  FillMemory

VOID FillMemory (Destination, Length)
PVOID  Destination;   /* address of block to fill */
DWORD  Length;   /* size in bytes of block to fill */
BYTE  Fill;   /* the byte value with which to fill */

The FillMemory function fills a block of memory with a specified value.

Parameters

Destination

Points to the starting address of the block of memory to fill.

Length

Specifies the size in bytes of the block of memory to fill.

Fill

Specifies the byte value with which to fill the memory block.

Return Value

This function has no return value.

See Also

»CopyMemory«, »MoveMemory«, »ZeroMemory«


  FillPath

BOOL FillPath(hdc)
HDC  hdc;   /* handle of device context */

The FillPath function closes any open figures in the current path and fills the path's interior by using the current brush and polygon-filling mode.

Parameters

hdc

Identifies a device context that contains a valid path.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get the error value, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

Comments

After its interior is filled, the path is discarded from the device context identified by the hdc parameter.

See Also

»BeginPath«, »SetPolyFillMode«, »StrokeAndFillPath«, »StrokePath«


  FillRect

int FillRect(hdc, lprc, hbr)
HDC  hdc;   /* handle of device context */
CONST RECT  *lprc;   /* address of structure with rectangle */
HBRUSH  hbr;   /* handle of brush */

The FillRect function fills the specified rectangle by using the given brush. This function includes the left and top borders, but excludes the right and bottom borders of the rectangle.

Parameters

hdc

Identifies the device context.

lprc

Points to a RECT structure that contains the logical coordinates of the rectangle to be filled. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hbr

Identifies the brush used to fill the rectangle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The brush identified by hbr must have been created by using the CreateHatchBrush, CreatePatternBrush, or CreateSolidBrush function, or retrieved by using the GetStockObject function.

When filling the specified rectangle, the FillRect function does not include the rectangle's right and bottom sides. GDI fills a rectangle up to, but does not include, the right column and bottom row, regardless of the current mapping mode.

See Also

»CreateHatchBrush«, »CreatePatternBrush«, »CreateSolidBrush«, »GetStockObject«


  FillRgn

BOOL FillRgn(hdc, hrgn, hbr)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region to be filled */
HBRUSH  hbr;   /* handle of brush used to fill the region */

The FillRgn function fills the given region by using the given brush.

Parameters

hdc

Identifies the device context.

hrgn

Identifies the region to be filled. The region's coordinates are presumed to be in logical units.

hbr

Identifies the brush to be used to fill the region.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»CreateBrushIndirect«, »CreateDIBPatternBrush«, »CreateHatchBrush«, »CreatePatternBrush«, »CreateSolidBrush«, »PaintRgn«


  FindAtom

ATOM FindAtom(lpszString)
LPCTSTR  lpszString;   /* address of string to find */

The FindAtom function searches the local atom table for the specified character string and retrieves the atom associated with that string.

Parameters

lpszString

Points to the null-terminated character string to search for.

Return Value

If the function succeeds, the return value is the atom associated with the given string. Otherwise, the return value is zero. To get extended error information, use the GetLastError function.

Comments

Even though Windows preserves the case of a string in an atom table, the search performed by the FindAtom function is not case sensitive.

See Also

»AddAtom«, »DeleteAtom«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«


  FindClose

BOOL FindClose(hFindFile)
HANDLE  hFindFile;   /* file search handle */

The FindClose function closes the specified search handle. The FindFirstFile and FindNextFile functions use the search handle to locate files with names that match a given name.

Parameters

hFindFile

Identifies the search handle. This handle must have been previously opened by the FindFirstFile function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

After the FindClose function is called, the handle specified by the hFindFile parameter cannot be used in subsequent calls to either the FindNextFile or FindClose function.

See Also

»FindFirstFile«, »FindNextFile«


  FindCloseChangeNotification

BOOL FindCloseChangeNotification(hChange)
HANDLE  hChange;   /* handle of change notification to close */

The FindCloseChangeNotification function stops notification handle change monitoring.

Parameters

hChange

Identifies a change notification handle created by the FindFirstChangeNotification function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

After the FindCloseChangeNotification function is called, the handle specified by the hChange parameter cannot be used in subsequent calls to either the FindNextChangeNotification or FindCloseChangeNotification function.

See Also

»FindFirstChangeNotification«, »FindNextChangeNotification«, »WaitForMultipleObjects«, »WaitForSingleObject«


  FindExecutable

HINSTANCE FindExecutable(lpszFile, lpszDir, lpszResult)
LPCTSTR  lpszFile;   /* address of string for filename */
LPCTSTR  lpszDir;   /* address of string for default directory */
LPTSTR  lpszResult;   /* address of buffer for string for executable file on return */

The FindExecutable function retrieves the name and handle of the executable (.EXE) file associated with the given filename.

Parameters

lpszFile

Points to a null-terminated string specifying a filename. This can be a document or executable file.

lpszDir

Points to a null-terminated string specifying the default directory.

lpszResult

Points to a buffer to receive the filename when the function returns. This filename is a null-terminated string specifying the executable file started when an "open" association is run on the file specified in the lpszFile parameter.

Return Value

If the function succeeds, the return value is the instance handle of the executable file associated with the specified filename. (This handle could also be the handle of a dynamic data exchange [DDE] server application.) If there is an error, the return value is less than or equal to 32. The possible error values are listed in the following Comments section.

Comments

When FindExecutable returns, the lpszResult parameter may contain the path to the DDE server started if no server responds to a request to initiate a DDE conversation.

The FindExecutable function returns 31 if there is no association for the specified file type. Following are the other possible error values:

Value	Meaning
0	The system is out of memory or resources.
ERROR_FILE_NOT_FOUND	The specified file was not found.
ERROR_PATH_NOT_FOUND	The specified path was not found.
ERROR_BAD_FORMAT	The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
See Also

»ShellExecute«


  FindFirstChangeNotification

HANDLE FindFirstChangeNotification(lpszPath, fWatchSubTree, fdwFilter)
LPTSTR  lpszPath;   /* address of the name of the directory to watch */
BOOL  fWatchSubTree;   /* flag for monitoring directory or directory tree */
DWORD  fdwFilter;   /* filter conditions to watch for */

The FindFirstChangeNotification function creates a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree.

Parameters

lpszPath

Points to a null-terminated string that specifies the path of the directory to watch.

fWatchSubTree

Specifies whether the function will monitor the directory or the directory tree. If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory; if FALSE, it monitors only the specified directory.

fdwFilter

Specifies the filter conditions that satisfy a change notification wait. This parameter can be one or more of the following values:

Value	Meaning
FILE_NOTIFY_CHANGE_FILE_NAME
	Any filename change in the watched directory or subtree satisfies a change notification wait. This includes renames, creations, and deletes.
FILE_NOTIFY_CHANGE_DIR_NAME
	Any directory-name change in the watched directory or subtree satisfies a change notification wait. This includes directory creations and deletions.
FILE_NOTIFY_CHANGE_ATTRIBUTES
	Any attribute change in the watched directory or subtree satisfies a change notification wait.
FILE_NOTIFY_CHANGE_SIZE
	Any file-size change in the watched directory or subtree satisfies a change notification wait. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, this occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_WRITE
	Any change to the last write-time of files in the watched directory or subtree satisfies a change notification wait. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, this occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_SECURITY
	Any security-descriptor change in the watched directory or subtree satisfies a change notification wait.
Return Value

If the function succeeds, the return value is a handle of a find change notification object; otherwise, it is INVALID_HANDLE_VALUE. To get extended error information, use the GetLastError function.

Comments

The WaitForSingleObject and WaitForMultipleObjects functions monitor the specified directory or subtree by using the handle returned by the FindFirstChangeNotification function. A wait is satisfied when one of the filter conditions occurs in the monitored directory or subtree.

After the wait has been satisfied, the application can respond to this condition and continue monitoring the directory by calling the FindNextChangeNotification function and the appropriate wait function. When the handle is no longer needed, close it by using the FindCloseChangeNotification function.

See Also

»FindCloseChangeNotification«, »FindNextChangeNotification«, »WaitForMultipleObjects«, »WaitForSingleObject«


  FindFirstFile

HANDLE FindFirstFile(lpszSearchFile, lpffd)
LPTSTR  lpszSearchFile;   /* address of name of the file to search for */
LPWIN32_FIND_DATA  lpffd;   /* address of returned information */

The FindFirstFile function searches a directory for a file whose name matches the specified filename. FindFirstFile examines subdirectory names as well as filenames.

Parameters

lpszSearchFile

Points to a null-terminated string that specifies a valid directory or path and filename, which can contain wildcard characters (* and ?).

lpffd

Points to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. The structure can be used in subsequent calls to the FindNextFile or FindClose functions to refer to the file or subdirectory.

The WIN32_FIND_DATA structure has the following form:

typedef struct _WIN32_FIND_DATA { /* wfd */

    DWORD dwFileAttributes;

    FILETIME ftCreationTime;

    FILETIME ftLastAccessTime;

    FILETIME ftLastWriteTime;

    DWORD    nFileSizeHigh;

    DWORD    nFileSizeLow;

    DWORD    dwReserved0;

    DWORD    dwReserved1;

    CHAR     cFileName[ MAX_PATH ];

    CHAR     cAlternateFileName[ 14 ];

} WIN32_FIND_DATA;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose; otherwise, it is INVALID_HANDLE_VALUE. To get extended error information, use the GetLastError function.

Comments

The FindFirstFile function opens a search handle and returns information about the first file whose name matches the specified pattern. Once the search handle is established, you can use the FindNextFile function to search for other files that match the same pattern. When the search handle is no longer needed, close it by using the FindClose function.

This function searches for files by name only; it cannot be used for attribute-based searches.

See Also

»FindClose«, »FindNextFile«, »GetFileAttributes«, »SetFileAttributes«, »WIN32_FIND_DATA«


  FindFirstFreeAce

BOOL FindFirstFreeAce(pAcl, lplpvAce)
PACL  pAcl;   /* address of access-control list */
LPVOID  *lplpvAce;   /* address of pointer to first free byte */

The FindFirstFreeAce function retrieves a pointer to the first free byte in an access-control list (ACL).

Parameters

pAcl

Points to an ACL structure.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lplpvAce

Points to a pointer to the first free position in the ACL created when the function returns. If the ACL is invalid, this parameter is NULL. If the ACL is full, this parameter points to the byte immediately following the ACL.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetAce«, »GetAclInformation«


  FindNextChangeNotification

BOOL FindNextChangeNotification(hChange)
HANDLE  hChange;   /* handle of change notification to signal */

The FindNextChangeNotification function requests that the operating system signal a change notification handle the next time it detects an appropriate change.

Parameters

hChange

Specifies a change notification handle created by the FindFirstChangeNotification function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

After the FindNextChangeNotification function returns successfully, the application can wait for notification that a change has occurred by using the WaitForSingleObject or WaitForMultipleObjects function.

If a change occurs after a call to FindFirstChangeNotification but before a call to FindNextChangeNotification, the operating system records the change. When FindNextChangeNotification is executed, the recorded change immediately satisfies a wait for the change notification.

Do not use FindNextChangeNotification more than once on the same handle without using either WaitForSingleObject or WaitForMultipleObjects. An application may miss a change notification if it uses FindNextChangeNotification when there is a change request outstanding.

When hChange is no longer needed, close it by using the FindCloseChangeNotification function.

See Also

»FindCloseChangeNotification«, »FindFirstChangeNotification«, »WaitForMultipleObjects«, »WaitForSingleObject«


  FindNextFile

BOOL FindNextFile(hFindFile, lpffd)
HANDLE  hFindFile;   /* handle of search returned by FindFirstFile */
LPWIN32_FIND_DATA  lpffd;   /* address of structure for data on found file */

The FindNextFile function continues a file search from a previous call to the FindFirstFile function.

Parameters

hFindFile

Specifies a search handle returned by a previous call to the FindFirstFile function.

lpffd

Points to the WIN32_FIND_DATA structure to receive information about the found file or subdirectory. The structure can be used in subsequent calls to FindNextFile to refer to the found file or directory.

The WIN32_FIND_DATA structure has the following form:

typedef struct _WIN32_FIND_DATA { /* wfd */

    DWORD dwFileAttributes;

    FILETIME ftCreationTime;

    FILETIME ftLastAccessTime;

    FILETIME ftLastWriteTime;

    DWORD    nFileSizeHigh;

    DWORD    nFileSizeLow;

    DWORD    dwReserved0;

    DWORD    dwReserved1;

    CHAR     cFileName[ MAX_PATH ];

    CHAR     cAlternateFileName[ 14 ];

} WIN32_FIND_DATA;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function. If no matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES.

Comments

The FindNextFile function searches for files by name only; it cannot be used for attribute-based searches.

See Also

»FindClose«, »FindFirstFile«, »GetFileAttributes«, »SetFileAttributes«, »WIN32_FIND_DATA«


  FindResource

HRSRC FindResource(hModule, lpszName, lpszType)
HINSTANCE  hModule;   /* resource-module handle */
LPCTSTR  lpszName;   /* address of resource name */
LPCTSTR  lpszType;   /* address of resource type */

The FindResource function determines the location of a resource with the given type and name in the given module.

Parameters

hModule

Identifies the module whose executable file contains the resource.

lpszName

Specifies the name of the resource. For more details, see the Comments section.

lpszType

Specifies the resource type. For more details, see the Comments section. For standard resource types, this parameter can be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
Return Value

If the function succeeds, the return value is a handle to the specified resource's info block. To obtain a handle to the resource, pass this handle to the LoadResource function.

If the function fails, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

If the high-order word of the lpszName or lpszType parameter is zero, the low-order word specifies the integer identifier of the name or type of the given resource. Otherwise, those parameters are long pointers to null-terminated strings. If the first character of the string is a pound sign (#), the remaining characters represent a decimal number that specifies the integer identifier of the resource's name or type. For example, the string "#258" represents the integer identifier 258.

An application should reduce the amount of memory required for the resources by referring to them by integer identifier instead of by name.

An application can use FindResource to find any type of resource, but this function should be used only if the application must access the binary resource data when making subsequent calls to LoadLibrary and LockResource.

To use a resource immediately, an application should use one of the following resource-specific functions to find and load the resources in one call:

Function	Action
FormatMessage	Loads and formats a message-table entry.
LoadAccelerators	Loads an accelerator table.
LoadBitmap	Loads a bitmap resource.
LoadCursor	Loads a cursor resource.
LoadIcon	Loads an icon resource.
LoadMenu	Loads a menu resource.
LoadString	Loads a string-table entry.
For example, an application can use the LoadIcon function to load an icon for display on the screen. However, the application should use FindResource and LoadResource if it is loading the icon to copy its data to another application.

See Also

»FindResourceEx«, »FormatMessage«, »LoadAccelerators«, »LoadBitmap«, »LoadCursor«, »LoadIcon«, »LoadMenu«, »LoadResource«, »LoadString«, »LockResource«, »SizeofResource«


  FindResourceEx

HRSRC FindResourceEx(hModule, lpszType, lpszName, wLanguage)
HINSTANCE  hModule;   /* resource-module handle */
LPCTSTR  lpszType;   /* address of resource type */
LPCTSTR  lpszName;   /* address of resource name */
WORD  wLanguage;   /* resource language */

The FindResourceEx function determines the location of the resource with the specified type, name, and language in the given module.

Parameters

hModule

Identifies the module whose executable file contains the resource. If this parameter is NULL, the function searches the module used to create the current process.

lpszType

Points to a null-terminated string specifying the type name of the resource. For standard resource types, this parameter can be one of the following values:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lpszName

Points to a null-terminated string specifying the name of the resource.

wLanguage

Specifies the language of the resource. If this parameter is MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), the current language associated with the calling thread is used.

To specify a language other than the current language, use the MAKELANGID macro to create this parameter. For more information, see the »MAKELANGID« macro in the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle to the specified resource's info block. To obtain a handle to the resource, pass this handle to the LoadResource function.

If the function fails, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

If the high-word of the lpszType or lpszName parameter is zero, the low-word specifies the integer identifier of the type or name of the given resource. Otherwise, those parameters are pointers to null-terminated strings. If the first character of the string is a pound sign (#), the remaining characters represent a decimal number that specifies the integer identifier of the resource's name or type. For example, the string "#258" represents the integer identifier 258.

Applications should reduce the amount of memory required for the resources by referring to them by integer identifier instead of by name.

An application can use FindResource to find any type of resource, but this function should be used only if the application must access the binary resource data when making subsequent calls to the LoadLibrary and LockResource functions.

To use a resource immediately, an application should use the following resource-specific functions to find and load the resources in one call:

Function	Action
FormatMessage	Loads and formats a message-table entry.
LoadAccelerators	Loads an accelerator table.
LoadBitmap	Loads a bitmap resource.
LoadCursor	Loads a cursor resource.
LoadIcon	Loads an icon resource.
LoadMenu	Loads a menu resource.
LoadString	Loads a string-table entry.
For example, an application can use the LoadIcon function to load an icon for display on the screen. However, the application should use FindResource and LoadResource if it is loading the icon to copy its data to another application.

See Also

»FindResource«, »LoadResource«, »MAKELANGID«


  FindText

HWND FindText(lpfr)
LPFINDREPLACE  lpfr;   /* pointer to structure with initialization data */

The FindText function creates a system-defined modeless dialog box that enables the user to find text within a document.

Parameters

lpfr

Points to a FINDREPLACE structure that contains information used to initialize the dialog box. When the user makes a selection in the dialog box, the system fills this structure with data that describes the user's selection and then sends a message to the application. This message contains a pointer to the FINDREPLACE structure.

The FINDREPLACE structure has the following form:

typedef struct {    /* fr */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HINSTANCE    hInstance;

    DWORD        Flags;

    LPSTR        lpstrFindWhat;

    LPSTR        lpstrReplaceWith;

    WORD         wFindWhatLen;

    WORD         wReplaceWithLen;

    DWORD        lCustData;

    LPFRHOOKPROC lpfnHook;

    LPCSTR       lpTemplateName;

} FINDREPLACE;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the window handle of the dialog box; otherwise, it is NULL. Use the CommDlgExtendedError function to retrieve the extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE
CDERR_INITIALIZATION
CDERR_LOCKRESFAILURE
CDERR_LOADRESFAILURE
CDERR_LOADSTRFAILURE
CDERR_MEMALLOCFAILURE
CDERR_MEMLOCKFAILURE
CDERR_NOHINSTANCE
CDERR_NOHOOK
CDERR_NOTEMPLATE
CDERR_STRUCTSIZE
FRERR_BUFFERLENGTHZERO

Comments

FindText does not perform a search operation, it simply returns a string typed by the user (as well as related data such as the direction in which the search should occur). An application must perform the search by using this string.

An application can use the window handle returned by this function to communicate with or to close the dialog box.

The dialog box procedure for the Find dialog box passes user requests to the application by sending special messages. The lParam parameter of each of these messages contains a pointer to a FINDREPLACE structure. The procedure sends the messages to the window identified by the hwndOwner member of the FINDREPLACE structure. An application can register the identifier for these messages by specifying the "commdlg_FindReplace" string in a call to the RegisterWindowMessage function.

For the TAB key to function correctly, any application that calls FindText must also call the IsDialogMessage function in its main message loop. IsDialogMessage returns a value that indicates whether messages are intended for the Find dialog box.

If the hook function (pointed to by the lpfnHook member of the FINDREPLACE structure) processes the WM_CTLCOLOR message, this function must return a handle of the brush that should be used to paint the control background.

See Also

»IsDialogMessage«, »RegisterWindowMessage«, »ReplaceText«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  FindWindow

HWND FindWindow(lpszClass, lpszWindow)
LPCTSTR  lpszClass;   /* address of class name */
LPCTSTR  lpszWindow;   /* address of window name */

The FindWindow function retrieves the handle of the top-level window whose class name and window name match the specified strings. This function does not search child windows.

Parameters

lpszClass

Points to a null-terminated string that specifies the class name, or is an atom that identifies the class-name string. If this parameter is an atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value, must be placed in the low-order word of lpszClass; the high-order word must be zero.

lpszWindow

Points to a null-terminated string that specifies the window name (the window's title). If this parameter is NULL, all window names match.

Return Value

If the function succeeds, the return value is the handle of the window that has the specified class name and window name; otherwise, it is NULL. To get extended error information, use the GetLastError function.

See Also

»EnumWindows«, »GetClassName«


  FlashWindow

BOOL FlashWindow(hwnd, fInvert)
HWND  hwnd;   /* handle of window to flash */
BOOL  fInvert;   /* flash status */

The FlashWindow function flashes the given window once.

Parameters

hwnd

Identifies the window to be flashed. The window can be either open or iconic.

fInvert

Specifies whether the window is to be flashed or returned to its original state. The window is flashed from one state to the other if the fInvert parameter is TRUE. If the fInvert parameter is FALSE, the window is returned to its original state (either active or inactive).

Return Value

The return value specifies the window's state before the call to the FlashWindow function. If the window was active before the call, it is TRUE; otherwise, it is FALSE.

Comments

Flashing a window means changing the appearance of its caption bar as if the window were changing from inactive to active status, or vice versa. (An inactive caption bar changes to an active caption bar; an active caption bar changes to an inactive caption bar.)

Typically, a window is flashed to inform the user that the window requires attention but that it does not currently have the keyboard focus.

The FlashWindow function flashes the window only once; for repeated flashing, the application should create a system timer.

This function always returns TRUE for iconic windows. If the window is iconic, FlashWindow simply flashes the icon; the fInvert parameter is ignored for iconic windows.


  FlattenPath

BOOL FlattenPath(hdc)
HDC  hdc;   /* handle of device context */

The FlattenPath function transforms any curves in the path that is selected into the current device context, turning each curve into a sequence of lines.

Parameters

hdc

Identifies a device context that contains a valid path.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get the error value, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

See Also

»WidenPath«


  FloodFill

BOOL FloodFill(hdc, nXStart, nYStart, crFill)
HDC  hdc;   /* handle of device context */
int  nXStart;   /* x-coord., where fill begins */
int  nYStart;   /* y-coord., where fill begins */
COLORREF  crFill;   /* fill color */

The FloodFill function fills an area of the display surface with the current brush. The area is assumed to be bounded as specified by the crFill parameter.

The FloodFill function is included only for compatibility with earlier versions of Windows. For Win32 applications, use the ExtFloodFill function with FLOODFILLBORDER specified.

Parameters

hdc

Identifies a device context.

nXStart

Specifies the logical x-coordinate of the point where filling is to begin.

nYStart

Specifies the logical y-coordinate of the point where filling is to begin.

crFill

Specifies the color of the boundary or of the area to be filled.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Following are reasons this function might fail:

•	The fill should not be completed.

•	The given point has the boundary color specified by the crFill parameter.

•	The given point lies outside the current clipping region — that is, it is not visible on the device.

See Also

»ExtFloodFill«


  FlushConsoleInputBuffer

BOOL FlushConsoleInputBuffer(hConsoleInput)
HANDLE  hConsoleInput;   /* handle of console input buffer */

The FlushConsoleInputBuffer function flushes the console input buffer. All input records currently in the input buffer are discarded.

Parameters

hConsoleInput

Identifies the console input buffer. The handle must have GENERIC_WRITE access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetNumberOfConsoleInputEvents«, »PeekConsoleInput«, »ReadConsoleInput«, »WriteConsoleInput«


  FlushFileBuffers

BOOL FlushFileBuffers(hFile)
HANDLE  hFile;   /* handle of file to which the function writes data */

The FlushFileBuffers function clears the buffers for the specified file and causes all buffered data to be written to the file.

Parameters

hFile

Specifies an open file handle. The file handle must have been created with GENERIC_WRITE access to the file.

If hFile specifies a communications device, this function flushes only the transmit buffer.

If hFile specifies the server end of a named pipe, this function does not return until the client has read all buffered data from the pipe.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The WriteFile and WriteFileEx functions typically write data to an internal buffer written to disk on a regular basis. The FlushFileBuffers function writes all of the buffered information for the specified file to disk.

See Also

»WriteFile«, »WriteFileEx«


  FlushInstructionCache

BOOL FlushInstructionCache(hProcess, lpvBase, cbFlush)
HANDLE  hProcess;   /* process with cache to flush */
LPVOID  lpvBase;   /* address of region to flush */
DWORD  cbFlush;   /* length of region to flush */

The FlushInstructionCache function flushes the instruction cache for the specified process.

Parameters

hProcess

Identifies the process that has an instruction cache to flush.

lpvBase

Points to the base of the region to be flushed. This parameter can be NULL.

cbFlush

Specifies the length of the region to be flushed if the lpvBase parameter is not NULL.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.


  FlushViewOfFile

BOOL FlushViewOfFile(lpvBase, cbFlush)
LPVOID  lpvBase;   /* start address of byte range to flush */
DWORD  cbFlush;   /* number of bytes in range */

The FlushViewOfFile function writes to the disk a byte range within a mapped view of a file.

Parameters

lpvBase

Specifies the base address of the byte range to be flushed to the disk representation of the mapped file.

cbFlush

Specifies the number of bytes to flush.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Flushing a range of a mapped view causes any dirty pages within that range to be written to the disk. Dirty pages are those whose contents have changed since the file view was mapped. This happens automatically whenever a view is unmapped, either explicitly, by using the UnmapViewOfFile function, or as a result of process termination.

See Also

»MapViewOfFile«, »UnmapViewOfFile«


  FMExtensionProc

LONG WINAPI FMExtensionProc(hwnd, wMsg, lParam)
HWND  hwnd;   /* handle of extension window */
WORD  wMsg;   /* menu-item identifier, or message */
LONG  lParam;   /* additional message information */

The FMExtensionProc function is an application-defined callback function that processes menu commands and messages sent to a File Manager extension dynamic-link library (DLL).

Parameters

hwnd

Identifies the File Manager window. An extension DLL should use this handle to specify the owner for any dialog box or message box that the DLL may display and to send request messages to File Manager.

wMsg

Specifies the message. This parameter can be one of the following values:

Value	Meaning
1−99	The user selected the menu item identified by this number.
FMEVENT_INITMENU	User selected the extension's menu.
FMEVENT_LOAD	File Manager is loading the extension DLL.
FMEVENT_SELCHANGE	Selection changed in File Manager's directory window or in Search Results window.
FMEVENT_UNLOAD	File Manager is unloading the extension DLL.
FMEVENT_USER_REFRESH	User chose the Refresh command from the Window menu.
lParam

Specifies 32 bits of additional message-dependent information.

Return Value

The callback function should return the result of the message processing. The actual return value depends on the message processed.

Comments

Whenever File Manager calls the FMExtensionProc function, it waits to refresh its directory windows (for changes in the file system) until after the function returns. This allows the extension to perform large numbers of file operations without excessive repainting by File Manager. It is not necessary for the extension to send the FM_REFRESH_WINDOWS message to notify File Manager to repaint its windows.


  FoldStringW

int FoldStringW(fdwMap, lpSrcStr, cchSrc, lpDestStr, cchDest)
DWORD  fdwMap;   /* mapping-type options */
LPCWSTR  lpSrcStr;   /* address of source string */
int  cchSrc;   /* number of characters in source string */
LPWSTR  lpDestStr;   /* address of destination buffer */
int  cchDest;   /* size of destination buffer */

The FoldStringW function maps one wide-character string to another, performing the specified translation.

Parameters

fdwMap

Specifies flags indicating the type of transformation to be used during mapping. This value can be a combination of the following values:

Option	Meaning
MAP_FOLDCZONE	Fold compatibility zone characters into standard Unicode™ equivalents. For information about compatibility zone characters, see the following Comments section.
MAP_FOLDDIGITS	Map all digits to Unicode ASCII 0 through 9.
MAP_PRECOMPOSED	Map accented characters to precomposed characters, in which the accent and base character are combined into a single character value. This value cannot be combined with MAP_COMPOSITE.
MAP_COMPOSITE	Map accented characters to composite characters, in which the accent and base character are represented by two character values. This value cannot be combined with MAP_PRECOMPOSED.
lpSrcStr

Points to the string to be mapped.

cchSrc

Specifies the number of characters in the string pointed to by the lpSrcStr parameter. If this value is −1, lpSrcStr is assumed to be null terminated and the length is calculated automatically.

lpDestStr

Points to the buffer to store the mapped string.

cchDest

Specifies the number of characters that can be contained by the buffer pointed to by the lpDestStr parameter. If this value is zero, the function returns the number of characters required to hold the mapped string. (The buffer pointed to by the lpDestStr parameter is not used in this case.)

Return Value

If the function succeeds, the return value is the number of characters written to the destination buffer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The mapped string is null terminated if the source string is null terminated.

The lpSrcStr and lpDestStr pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The compatibility zone in Unicode consists of characters in the range 0xF900 through 0xFFEF that are assigned to characters from other character-encoding standards but are actually variants of characters that are already in Unicode. The compatibility zone is used to support round-trip mapping to these standards. Applications can use the MAP_FOLDCZONE flag to avoid supporting the duplication of characters in the compatibility zone.

See Also

»LCMapStringW«, »CompareStringW«


  FormatMessage

DWORD FormatMessage(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer,
nSize, lpArguments)
DWORD  dwFlags;   /* source and processing options */
LPVOID  lpSource;   /* address of  message source */
DWORD  dwMessageId;   /* requested message identifier */
DWORD  dwLanguageId;   /* language identifier for requested message */
LPTSTR  lpBuffer;   /* address of message buffer */
DWORD  nSize;   /* maximum size of message buffer */
va_list*  lpArguments;   /* address of array of message inserts */

The FormatMessage function formats a message string. The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message ID and a language ID. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.

Parameters

dwFlags

Specifies various function options. The high order bits are a set of flags that specify aspects of the formatting process and how to interpret the lpSource parameter. If one of those flags, the FORMAT_MESSAGE_MAX_WIDTH_MASK, is set, then the low order 8 bits specify the maximum width, in characters, of a formatted line. The following constants may be used to set flags:

Value	Meaning
FORMAT_MESSAGE_ALLOCATE_BUFFER
	Specifies that the lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize parameter specifies the minimum number of bytes to allocate for an output message buffer. The function allocates a buffer large enough to hold the formatted message, and places a pointer to the allocated buffer at the address specified by lpBuffer. The caller should use the LocalFree function to free the buffer when it is no longer needed.
FORMAT_MESSAGE_IGNORE_INSERTS
	Specifies that insert sequences in the message definition are to be ignored and passed through to the output buffer unchanged. This flag is useful for fetching a message for later formatting. If this flag is set, the lpArguments parameter is ignored.
FORMAT_MESSAGE_FROM_STRING
	Specifies that lpSource is a pointer to a null-terminated message definition. The message definition may contain insert sequences, just as the message text in a message table resource may.
FORMAT_MESSAGE_FROM_HMODULE
	Specifies that lpSource is a module handle containing the message-table resource(s) to search. If this lpSource handle is NULL, the current process' application image file will be searched.
FORMAT_MESSAGE_FROM_SYSTEM
	Specifies that the function should search the system message-table resource(s) for the requested message if it is not found in lpSource, or if lpSource is not examined, which occurs when neither of the preceding two flags is specified.
FORMAT_MESSAGE_ARGUMENT_ARRAY
	Specifies that the Arguments parameter is NOT a va_list structure, but instead is just a pointer to an array of 32-bit values that represent the arguments.
FORMAT_MESSAGE_MAX_WIDTH_MASK
	Specifies that the low order 8 bits of dwFlags contain data that determines the maximum width, in characters, of each line formatted into the output buffer.
	A zero value in the low order 8 bits of dwFlags means that there are no width restrictions, and only the line breaks in the message definition will go into the output buffer.
	A non-zero value in the low order 8 bits of dwFlags means that line breaks in the message definition text are ignored; instead, that non-zero value determines the maximum output line width, with the proviso that strings delimited by white space are never split across a line break. Hard coded line breaks in the message definition text, identified by the %n escape sequence, are always output to the output buffer.
	A value of FORMAT_MESSAGE_MAX_WIDTH_MASK in the low order 8 bits of dwFlags means that line breaks in the message definition text are ignored, hard coded line breaks are kept, and no new line breaks are generated.
lpSource

Specifies the location of the message definition. The type of this parameter depends upon the settings in the dwFlags parameter.

dwFlags Setting	Parameter Type
FORMAT_MESSAGE_FROM_HMODULE	lpSource is an hModule of the module that contains the message table to search.
FORMAT_MESSAGE_FROM_STRING	lpSource is an LPTSTR that points to unformatted message text. It will be scanned for inserts and formatted accordingly.
If neither of these flags is set in dwFlags, then lpSource is ignored.

dwMessageId

Specifies the 32-bit message identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.

dwLanguageId

Specifies the 32-bit language identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.

lpBuffer

Points to a buffer for the formatted (and null-terminated) message. If dwFlags includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer via LocalAlloc,  and places the address of the buffer at the address specified in lpBuffer.

nSize

If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of bytes that can be stored in the output buffer. If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is set, this parameter specifies the minimum number of bytes to allocate for an output buffer.

lpArguments

Points to an array of 32-bit values that are used as insert values in the formatted message. %1 in the format string indicates the first value in the lpArguments array; %2 indicates the second argument; and so on.

The interpretation of each 32-bit value depends on the formatting information associated with the insert in the message definition. The default is to treat each value as a pointer to a null-terminated string.

By default, the lpArguments parameter is of type va_list*, which is a language- and implementation-specific data type for describing a variable number of arguments. If you do not have a pointer of type va_list*, then specify the FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array of 32-bit values; those values are input to the message formatted as the insert values.

Return Value

If the function succeeds, the return value is the number of bytes stored in the output buffer, excluding the terminating null character; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

An application can use the FORMAT_MESSAGE_MAX_WIDTH_MASK constant to mask the low 8 bits of dwFlags to retrieve the maximum line length.

Each insert must have a corresponding element in the array pointed to by the lpArguments parameter.

Within the message text, several escape sequences are supported for dynamically formatting the message. These escape sequences and their meanings are shown in the following table. All escape sequences start with the percent character (%).

Escape Sequence	Meaning
%0	Terminates a message text line without a trailing newline character. This escape sequence can be used to build up long lines or to terminate the message itself without a trailing newline character. It is useful for prompt messages.
%n!printf format string!	Identifies an insert. The value of n can be in the range 1 through 99. The printf format string (which must be bracketed by exclamation marks) is optional and defaults to !s! if not specified.
	The printf format string can contain the * specifier for either the precision or the width component. If * is specified for one component, the FormatMessage function uses insert %n+1; it uses %n+2 if * is specified for both components.
	Floating point printf format specifiers  —  e, E, f, and g  —  are not supported. The workaround is to to use the sprintf function to format the floating point number into a temporary buffer, then use that buffer as the insert string.
Any other nondigit character following a percent character is formatted in the output message without the percent character. Following are some examples:

Format string	Resulting output
%%	A single percent sign in the formatted message text.
%n	A hard line break when the format string occurs at the end of a line. This format string is useful when FormatMessage is supplying regular line breaks so the message fits in a certain width.
%space	A space in the formatted message text. This format string can be used to ensure the appropriate number of trailing spaces in a message text line.
%.	A single period in the formatted message text. This format string can be used to include a single period at the beginning of a line without terminating the message text definition.
%!	A single exclamation point in the formatted message text. This format string can be used to include an exclamation point immediately after an insert without its being mistaken for the beginning of a printf format string.
See Also

»LoadString«


  FrameRect

int FrameRect(hdc, lprc, hbr)
HDC  hdc;   /* handle of device context */
CONST RECT  *lprc;   /* address of rectangle coordinates */
HBRUSH  hbr;   /* handle of brush */

The FrameRect function draws a border around the specified rectangle by using the given brush. The width and height of the border are always one logical unit.

Parameters

hdc

Identifies the device context in which the border is drawn.

lprc

Points to a RECT structure that contains the logical coordinates of the upper-left and lower-right corners of the rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hbr

Identifies the brush used to draw the border.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The brush identified by the hbr parameter must have been created by using the CreateHatchBrush, CreatePatternBrush, or CreateSolidBrush function, or retrieved by using the GetStockObject function.

If the bottom member of the RECT structure is less than or equal to the top member, or if the right member is less than or equal to the left member, the function does not draw the rectangle.

See Also

»CreateHatchBrush«, »CreatePatternBrush«, »CreateSolidBrush«


  FrameRgn

BOOL FrameRgn(hdc, hrgn, hbr, nWidth, nHeight)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region to be framed */
HBRUSH  hbr;   /* handle of brush used to draw border */
int  nWidth;   /* width of region frame */
int  nHeight;   /* height of region frame */

The FrameRgn function draws a border around the given region by using the given brush.

Parameters

hdc

Identifies the device context.

hrgn

Identifies the region to be enclosed in a border. The region's coordinates are presumed to be in logical units.

hbr

Identifies the brush to be used to draw the border.

nWidth

Specifies the width, in logical units, of vertical brush strokes.

nHeight

Specifies the height, in logical units, of horizontal brush strokes.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»FillRgn«, »PaintRgn«


  FreeConsole

BOOL FreeConsole(VOID)

The FreeConsole function detaches the calling process from its console.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If other processes share the console, the console is not destroyed, but the calling process cannot reference it.

A process can use FreeConsole to detach itself from its current console, and then it can call the AllocConsole function to create a new console.

See Also

»AllocConsole«


  FreeDDElParam

BOOL FreeDDElParam(uMsg, lParam)
UINT  uMsg;   /* posted DDE message */
LONG  lParam;   /* lParam of message */

The FreeDDElParam function frees the memory specified by the lParam parameter of a posted dynamic data exchange (DDE) message. An application receiving a posted DDE message should call this function after it has used the UnpackDDElParam function to unpack the lParam value.

Parameters

uMsg

Specifies the posted DDE message.

lParam

Specifies the lParam parameter of the posted DDE message.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

An application should call this function only for posted DDE messages.

This function frees the memory specified by the lParam parameter. It does not free the contents of lParam.

See Also

»PackDDElParam«, »ReuseDDElParam«


  FreeLibrary

BOOL FreeLibrary(hLibModule)
HMODULE  hLibModule;   /* handle of loaded library module */

The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL) module. When the reference count reaches zero, the module is unmapped from the address space of the calling process, and the handle is no longer valid.

Parameters

hLibModule

Identifies the loaded library module. The LoadLibrary or GetModuleHandle function returns this handle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Each process maintains a reference count for each loaded library module. This reference count is incremented each time LoadLibrary is called, and decremented each time FreeLibrary is called. A DLL library module loaded at process initialization due to load-time dynamic linking has a reference count of one. This count incremented if the same module is loaded by a call to LoadLibrary.

Before unmapping a DLL library module, the system enables the DLL to detach from the process by calling the DLL's DllEntryPoint function, if it has one, with the DLL_PROCESS_DETACH flag. This gives the DLL an opportunity to clean up resources allocated on behalf of the current process. After the entrypoint function returns, the library module is removed from the address space of the current process.

Calling FreeLibrary does not affect other processes using the same library module.

See Also

»LoadLibrary«


  FreeModule

The FreeModule function is obsolete.

This function is provided only for compatibility with earlier versions of Windows. Win32 functions should not use this function.

See Also

»FreeLibrary«


  FreeProcInstance

The FreeProcInstance function is obsolete.

This function is provided only for compatibility with earlier versions of Windows. Win32 applications should not use this function.


  FreeResource

The FreeResource function is obsolete. It is not necessary for Win32 applications to free resources loaded by using the LoadResource function.

See Also

»LoadResource«, »LockResource«


  FreeSelector

The FreeSelector function has been deleted.


  FreeSid

PVOID FreeSid(psid)
PSID  psid;   /* address of SID to free */

The FreeSid function frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function.

Parameters

psid

Points to the SID structure to free.

Return Value

This function does not return a value.

See Also

»AllocateAndInitializeSid«


  GdiComment

BOOL GdiComment(hdc, cbSize, lpData)
HDC  hdc;   /* handle of a device context */
UINT  cbSize;   /* size of text buffer */
LPBYTE  lpData;   /* address of text buffer */

The GdiComment function copies the comment from a buffer into a specified enhanced-format metafile.

Parameters

hdc

Identifies a device context.

cbSize

Specifies the length of the comment buffer, in bytes.

lpData

Points to the buffer that contains the comment.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

A comment may include any private information — for example, the source of the picture and the date it was created. A comment should begin with an application signature, followed by the data.

Comments should not contain application-specific or position-specific data. Position-specific data specifies the location of a record, and it should not be included because one metafile may be embedded within another metafile.

See Also

»CreateEnhMetaFile«


  GdiFlush

BOOL GdiFlush(VOID)

The GdiFlush function flushes the calling thread's current batch.

Parameters

This function has no parameters.

Return Value

If all functions in the current batch succeed, the return value is TRUE; otherwise, it is FALSE, indicating that at least one function returned an error.

Comments

Batching enhances drawing performance by minimizing the amount of time needed to call GDI drawing functions that return Boolean values. The system accumulates the parameters for calls to these functions in the current batch and then calls the functions when the batch is flushed by any of the following means:

•	Calling the GdiFlush function

•	Reaching or exceeding the batch limit set by the GdiSetBatchLimit function

•	Filling the batching buffers

•	Calling any GDI function that does not return a Boolean value

The return value for GdiFlush applies only to the functions in the batch at the time GdiFlush is called. Errors that occur when the batch is flushed by any other means are never reported.

The GdiGetBatchLimit function returns the batch limit.

Note that the batch limit is maintained for each thread separately. In order to completely disable batching, call GdiSetBatchLimit(1) during the initialization of each thread.

A multi-threaded application that serializes access to GDI objects with a mutex must be sure to flush the GDI batch queue by calling GdiFlush as each thread releases ownership of the GDI object. This prevents collisions on the GDI objects (device contexts, metafiles, etc.).

See Also

»GdiGetBatchLimit«, »GdiSetBatchLimit«


  GdiGetBatchLimit

DWORD GdiGetBatchLimit(VOID)

The GdiGetBatchLimit function returns the maximum number of function calls that can be accumulated in the calling thread's current batch. The system flushes the current batch whenever this limit is exceeded.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the batch limit; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The batch limit is set by using the GdiSetBatchLimit function. Setting the limit to 1 effectively disables batching.

Only GDI drawing functions that return Boolean values can be batched; calls to any other GDI functions immediately flush the current batch. Exceeding the batch limit or calling the GdiFlush function also flushes the current batch.

When the system batches a function call, the function returns TRUE. The actual return value for the function is reported only if GdiFlush is used to flush the batch.

Note that the batch limit is maintained for each thread separately. In order to completely disable batching, call GdiSetBatchLimit(1) during the initialization of each thread.

See Also

»GdiFlush«, »GdiSetBatchLimit«


  GdiSetBatchLimit

DWORD GdiSetBatchLimit(dwLimit)
DWORD  dwLimit;   /* batch limit */

The GdiSetBatchLimit function sets the maximum number of functions that can be accumulated in the calling thread's current batch. The system flushes the current batch whenever this limit is exceeded.

Parameters

dwLimit

Specifies the batch limit to be set. A value of 0 sets the default limit. A value of 1 disables batching.

Return Value

If the function succeeds, the return value is the previous batch limit; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Only GDI drawing functions that return Boolean values can be accumulated in the current batch; calls to any other GDI functions immediately flush the current batch. Exceeding the batch limit or calling the GdiFlush function also flushes the current batch.

When the system accumulates a function, the function returns TRUE to indicate it is in the batch. When the system flushes the current batch and executes the function for the second time, the return value is either TRUE or FALSE, depending on whether the function succeeds. This second return value is reported only if GdiFlush is used to flush the batch.

Note that the batch limit is maintained for each thread separately. In order to completely disable batching, call GdiSetBatchLimit(1) during the initialization of each thread.

See Also

»GdiFlush«, »GdiGetBatchLimit«


  GenerateConsoleCtrlEvent

BOOL GenerateConsoleCtrlEvent(fdwEvent, IDProcessGroup)
DWORD  fdwEvent;   /* signal to generate */
DWORD  IDProcessGroup;  /* process group to get signal */

The GenerateConsoleCtrlEvent function sends a specified signal to a console process group that shares the console associated with the calling process.

Parameters

fdwEvent

Specifies the type of signal to generate. One of the following values is specified:

Value	Meaning
CTRL_C_EVENT	Generates CTRL+C signal.
CTRL_BREAK_EVENT	Generates CTRL+BREAK signal.
IDProcessGroup

Identifies the process group that receives the signal. A process group is created when the CREATE_NEW_PROCESS_GROUP flag is specified in a call to the CreateProcess function. The process identifier of the new process is also the process group identifier of the new process group. The process group includes all processes that are descendants of this root process. Only those processes in the group that share the same console as the calling process receive the signal. In other words, if a process in the group creates a new console, that process does not receive the signal, nor do its descendants.

If this parameter is zero, the signal is generated in all processes that share the console of the calling process.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

GenerateConsoleCtrlEvent causes the control handler functions of processes in the target group to be called. All console processes have a default handler function that calls the ExitProcess function. A console process can use the SetConsoleCtrlHandler function to install or remove other handler functions.

SetConsoleCtrlHandler can also enable an inheritable attribute that causes the calling process to ignore CTRL+C signals. If GenerateConsoleCtrlEvent sends a CTRL+C signal to a process for which this attribute is enabled, the handler functions for that process are not called. CTRL+BREAK signals always cause the handler functions to be called.

See Also

»CreateProcess«, »SetConsoleCtrlHandler«


  GetAce

BOOL GetAce(pAcl, dwAceIndex, lplpvAce)
PACL  pAcl;   /* address of access-control list */
DWORD  dwAceIndex;   /* index of ACE to retrieve */
LPVOID  *lplpvAce;   /* address of pointer to ACE */

The GetAce function obtains a pointer to an ACE in an ACL.

An ACE is an access control entry. An ACL is an access control list.

Parameters

pAcl

Points to an ACL structure containing the ACE to be retrieved.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwAceIndex

Specifies the ACE to which a pointer is retrieved. A value of 0 corresponds to the first ACE in the ACL, 1 to the second ACE, and so on.

lplpvAce

Points to a pointer the function sets to the address of the ACE.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddAccessAllowedAce«, »AddAccessDeniedAce«, »AddAce«, »AddAuditAccessAce«, »GetAclInformation«, »InitializeAcl«


  GetAclInformation

BOOL GetAclInformation(pAcl, lpvAclInfo, cbAclInfo, aclic)
PACL  pAcl;   /* address of access-control list */
LPVOID  lpvAclInfo;   /* address of ACL information */
DWORD  cbAclInfo;   /* size of ACL information */
ACL_INFORMATION_CLASS  aclic;   /* class of requested information */

The GetAclInformation function retrieves information about an access-control list (ACL).

Parameters

pAcl

Points to an ACL structure. The function retrieves information about this ACL.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpvAclInfo

Points to a buffer receiving the requested information. The structure put into the buffer depends on the information class requested in the aclic parameter.

cbAclInfo

Specifies the size, in bytes, of the buffer pointed to by the lpvAclInfo parameter.

aclic

Specifies an ACL_INFORMATION_CLASS enumerated type that gives the class of information requested. This parameter can be one of two values from this enumerated type. If the value is AclRevisionInformation, the function fills the buffer pointed to by the lpvAclInfo parameter with an ACL_REVISION_INFORMATION structure.

The ACL_REVISION_INFORMATION structure has the following form:

typedef struct _ACL_REVISION_INFORMATION {

    DWORD   AclRevision;

} ACL_REVISION_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If the value is AclSizeInformation, the function fills the buffer pointed to by the lpvAclInfo parameter with an ACL_SIZE_INFORMATION structure.

This structure has the following form:

typedef struct _ACL_SIZE_INFORMATION {

    DWORD   AceCount;

    DWORD   AclBytesInUse;

    DWORD   AclBytesFree;

} ACL_SIZE_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetAce«, »InitializeAcl«, »IsValidAcl«, »SetAclInformation«


  GetACP

UINT GetACP(VOID)

The GetACP function retrieves the identifier of the ANSI system code page.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the ANSI code-page identifier, or it is the default identifier if no identifier is found in the registry.

Comments

Following are the ANSI code-page identifiers:

Identifier	Meaning
1250	Windows 3.1 Eastern European
1251	Windows 3.1 Cyrillic
1252	Windows 3.1 Latin 1 (US, Western Europe)
1253	Windows 3.1 Greek
1254	Windows 3.1 Turkish
See Also

»GetCPInfo«, »GetOEMCP«


  GetActiveWindow

HWND GetActiveWindow(void)

The GetActiveWindow function retrieves the window handle of the active window associated with the thread that calls the function.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the active window associated with the thread that calls the function. If the calling thread does not have an active window, the return value is NULL.

See Also

»SetActiveWindow«


  GetArcDirection

int GetArcDirection(hdc)
HDC  hdc;   /* handle of device context */

The GetArcDirection function returns the current arc direction for the given device context. Arc and rectangle functions use the arc direction.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value specifies the current arc direction. Following are the valid return values:

Value	Meaning
AD_COUNTERCLOCKWISE	Arcs and rectangles drawn counterclockwise.
AD_CLOCKWISE	Arcs and rectangles drawn clockwise.
If an error occurs, the return value is zero.

See Also

»SetArcDirection«


  GetAspectRatioFilter

The GetAspectRatioFilter function has been deleted. For Win32 applications, use the GetAspectRatioFilterEx function.

See Also

»GetAspectRatioFilterEx«


  GetAspectRatioFilterEx

BOOL GetAspectRatioFilterEx(hdc, lpAspectRatio)
HDC  hdc;   /* handle of device context */
LPSIZE  lpAspectRatio;   /* address of aspect-ratio filter */

The GetAspectRatioFilterEx function retrieves the setting for the current aspect-ratio filter.

Parameters

hdc

Identifies a device context.

lpAspectRatio

Points to a SIZE structure that receives the current aspect-ratio filter. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The aspect ratio is the ratio formed by the width and height of a pixel on a given device.

Windows provides a special filter, the aspect-ratio filter, to select fonts that were designed for a particular device. An application can specify that Windows should only retrieve fonts matching the specified aspect ratio by calling the SetMapperFlags function.

See Also

»SetMapperFlags«


  GetAsyncKeyState

SHORT GetAsyncKeyState(nVirtKey)
int  nVirtKey;   /* virtual-key code */

The GetAsyncKeyState function determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to the GetAsyncKeyState function.

Parameters

nVirtKey

Specifies one of 256 possible virtual-key codes.

Return Value

If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous GetAsyncKeyState call. The return value is zero if a window in another thread or process currently has the keyboard focus.

Comments

An application can use the virtual-key code constants VK_SHIFT, VK_CONTROL, and VK_MENU as values for the nVirtKey parameter. This gives the state of the SHIFT, CTRL, or ALT keys without distinguishing between left and right. An application can also use the following virtual-key code constants as values for nVirtKey in order to distinguish between the left and right instances of those keys:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU
These left- and right-distinguishing constants are available to an application only when using the GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions.

For a complete table of virtual key codes, see Appendix B, "Virtual-Key Codes," in Microsoft Win32 Programmer's Reference, Volume 2

See Also

»GetKeyState«, »GetKeyboardState«, »SetKeyboardState«, »MapVirtualKey«


  GetAtomHandle

The GetAtomHandle function is obsolete and cannot be used by Win32 applications.


  GetAtomName

UINT GetAtomName(atm, lpszBuffer, cchBuffer)
ATOM  atm;   /* atom identifying character string */
LPTSTR  lpszBuffer;   /* address of buffer for atom string */
int  cchBuffer;   /* size of buffer */

The GetAtomName function retrieves a copy of the character string associated with the specified local atom.

Parameters

atm

Specifies the local atom that identifies the character string to be retrieved.

lpszBuffer

Points to the buffer for the character string.

cchBuffer

Specifies the size, in characters, of the buffer.

Return Value

If the function succeeds, the return value is the length of the string copied to the buffer, in characters, not including the terminating null character. Otherwise, the return value is zero. To get extended error information, use the GetLastError function.

Comments

The string returned for an integer atom (an atom created by the MAKEINTATOM macro) is a null-terminated string in which the first character is a pound sign (#) and the remaining characters represent the unsigned integer originally passed to MAKEINTATOM.

See Also

»AddAtom«, »DeleteAtom«, »FindAtom«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«, »GlobalGetAtomName«


  GetBitmapBits

LONG GetBitmapBits(hbmp, cbBuffer, lpvBits)
HBITMAP  hbmp;   /* handle of bitmap */
LONG  cbBuffer;   /* number of bytes to copy to buffer */
LPVOID  lpvBits;   /* address of buffer for bitmap bits */

The GetBitmapBits function copies the bits of the specified bitmap into a buffer.

The GetBitmapBits function is included only for compatibility with earlier versions of Windows. For Win32 applications, use the GetDIBits function.

Parameters

hbmp

Identifies the bitmap.

cbBuffer

Specifies the number of bytes to be copied.

lpvBits

Points to the buffer to receive the bitmap. (The bitmap is an array of bytes.)

Return Value

If the function succeeds, the return value is the actual number of bytes in the bitmap; otherwise, it is zero.

Comments

The bits in the destination buffer must be WORD aligned.

See Also

»GetDIBits«


  GetBitmapDimension

The GetBitmapDimension function has been deleted. For Win32 applications, use the GetBitmapDimensionEx function.

See Also

»GetBitmapDimensionEx«


  GetBitmapDimensionEx

BOOL GetBitmapDimensionEx(hBitmap, lpDimension)
HBITMAP  hBitmap;   /* handle of bitmap */
LPSIZE  lpDimension;   /* address of structure receiving dimensions */

The GetBitmapDimensionEx function retrieves the dimensions of a bitmap. The retrieved dimensions must have been set previously by the SetBitmapDimensionEx function.

Parameters

hBitmap

Identifies the bitmap.

lpDimension

Points to a SIZE structure to receive the bitmap dimensions. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function was successful, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If no dimensions have been set, a default width and height of zero are returned.

See Also

»SetBitmapDimensionEx«


  GetBkColor

COLORREF GetBkColor(hdc)
HDC  hdc;   /* handle of device context */

The GetBkColor function returns the current background color of the given device.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is a COLORREF value for the current background color; otherwise, it is CLR_INVALID.

See Also

»SetBkColor«


  GetBkMode

int GetBkMode(hdc)
HDC  hdc;   /* handle of device context */

The GetBkMode function returns the background mix mode of the given device context (DC). The background mix mode is used with text, hatched brushes, and pen styles that are not solid lines.

Parameters

hdc

Identifies the DC.

Return Value

If the function succeeds, the return value specifies the current background mix mode; otherwise, it is zero.

See Also

»SetBkMode«


  GetBoundsRect

UINT GetBoundsRect(hdc, lprcBounds, flags)
HDC  hdc;   /* handle of device context */
LPRECT  lprcBounds;   /* address of structure for bounding rectangle */
UINT  flags;   /* information to return */

The GetBoundsRect function returns the current accumulated bounding rectangle for a given device context (DC).

Windows maintains an accumulated bounding rectangle for each application. An application can retrieve and set this rectangle.

Parameters

hdc

Identifies the device context (DC) whose bounding rectangle the function will return.

lprcBounds

Points to the RECT structure that will receive the current bounding rectangle. The application's rectangle is returned in logical coordinates, and the Windows rectangle is returned in screen coordinates. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

flags

Specifies aspects of how the GetBoundsRect function will operate on a given call. The following value has meaning:

Value	Meaning
DCB_RESET	Clears the bounding rectangle after returning it. If this flag is not set, the bounding rectangle will not be cleared.
Return Value

The return value specifies the state of the accumulated bounding rectangle; it can be one of the following values:

Value	Meaning
0	An error occurred. The given device context (DC) handle is invalid.
DCB_RESET	The bounding rectangle is empty.
DCB_SET	The bounding rectangle is not empty.
DCB_ENABLE	Boundary accumulation is on.
DCB_DISABLE	Boundary accumulation is off.
Comments

The DCB_SET value is a combination of the bit values DCB_ACCUMULATE and DCB_RESET. Applications that check the DCB_RESET bit to determine whether the bounding rectangle is empty must also check the DCB_ACCUMULATE bit. The bounding rectangle is empty only if the DCB_RESET bit is 1 and the DCB_ACCUMULATE bit is 0.

See Also

»SetBoundsRect«


  GetBrushOrg

The GetBrushOrg function has been deleted. For Win32 applications, use the GetBrushOrgEx function.

See Also

»GetBrushOrgEx«


  GetBrushOrgEx

BOOL GetBrushOrgEx(hdc, lppt)
HDC  hdc;   /* handle of device context */
LPPOINT  lppt;   /* address of structure of coordinates */

The GetBrushOrgEx function retrieves the current brush origin for the given device context (DC).

Parameters

hdc

Identifies the DC.

lppt

Points to a POINT structure that receives the brush origin, in device coordinates. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A brush is a bitmap that Windows uses to paint the interiors of filled shapes.

The brush origin is a set of coordinates with values between 0 and 7, specifying the location of one pixel in the bitmap. The default brush origin coordinates are (0,0). For horizontal coordinates, the value 0 corresponds to the leftmost column of pixels; the value 7 corresponds to the rightmost column. For vertical coordinates, the value 0 corresponds to the uppermost row of pixels; value 7 corresponds to the lowermost row. When Windows positions the brush at the start of any painting operation, it maps the pixel at the brush's origin to the upper-left corner of the client area.

If an application uses a brush to fill the backgrounds of both a parent and a child window with matching colors, it may be necessary to set the brush origin after painting the parent window but before painting the child window.

See Also

»SetBrushOrgEx«


  GetCapture

HWND GetCapture(VOID)

The GetCapture function retrieves the handle of the window (if any) that has captured the mouse. Only one window at any given time can capture the mouse; this window receives mouse input whether or not the cursor is within its borders.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the capture window associated with the current thread. If no window in the thread has captured the mouse, the return value is NULL.

Comments

A NULL return value does not mean no other thread or process in the system has captured the mouse; it just means the current thread has not captured the mouse.

See Also

»ReleaseCapture«, »SetCapture«


  GetCaretBlinkTime

UINT GetCaretBlinkTime(VOID)

The GetCaretBlinkTime function returns the elapsed time, in milliseconds, required to invert the caret's pixels.

Parameters

This function has no parameters.

Return Value

The return value is the blink time, in milliseconds.

See Also

»SetCaretBlinkTime«


  GetCaretPos

BOOL GetCaretPos(lpPoint)
LPPOINT  lpPoint;   /* address of structure to receive coordinates */

The GetCaretPos function copies the caret's position, in client coordinates, to the specified POINT structure.

Parameters

lpPoint

Points to the POINT structure that is to receive the client coordinates of the caret. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The caret position is always given in the client coordinates of the window that contains the caret.

See Also

»SetCaretPos«


  GetCharABCWidths

BOOL GetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc)
HDC  hdc;   /* handle of device context */
UINT  uFirstChar;   /* first character in range to query */
UINT  uLastChar;   /* last character in range to query */
LPABC  lpabc;   /* address of character-width structure */

The GetCharABCWidths function retrieves the widths, in logical units, of consecutive characters in a given range from the current TrueType® font. This function succeeds only with TrueType fonts.

Parameters

hdc

Identifies the device context.

uFirstChar

Specifies the first character in the group of consecutive characters from the current font.

uLastChar

Specifies the last character in the group of consecutive characters from the current font.

lpabc

Points to an array of ABC structures that receive the character widths when the function returns. This array must contain at least as many ABC structures as there are characters in the range specified by the uFirstChar and uLastChar parameters. The ABC structure has the following form:

typedef struct _ABC { /* abc */

    int     abcA;

    UINT    abcB;

    int     abcC;

} ABC;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The TrueType rasterizer provides ABC character spacing after a specific point size has been selected. "A" spacing is the distance added to the current position before placing the glyph. "B" spacing is the width of the black part of the glyph. "C" spacing is the distance added to the current position to account to provide white space to the right of the glyph. The total advanced width is given by A+B+C.

When the GetCharABCWidths function retrieves negative "A" or "C" widths for a character, that character includes underhangs or overhangs.

To convert the ABC widths to font design units, an application should use the value stored in the otmEMSquare member of a OUTLINETEXTMETRIC structure. This value can be retrieved by calling the GetOutlineTextMetrics function.

The ABC widths of the default character are used for characters outside the range of the currently selected font.

To retrieve the widths of characters in non-TrueType fonts, applications should use the GetCharWidth function.

See Also

»ABC«, »GetCharWidth«, »GetOutlineTextMetrics«, »OUTLINETEXTMETRIC«


  GetCharABCWidthsFloat

BOOL GetCharABCWidthsFloat(hdc, iFirstChar, iLastChar, lpABCF)
HDC  hdc;   /* handle of device context */
UINT  iFirstChar;   /* first character in range to query */
UINT  iLastChar;   /* last character in range to query */
LPABCFLOAT  lpABCF;   /* address of character-width structure */

The GetCharABCWidthsFloat function retrieves the widths, in logical units, of consecutive characters in a given range from the current font.

Parameters

hdc

Identifies the device context.

iFirstChar

Specifies the code point of the first character in the group of consecutive characters where the ABC widths are sought.

iLastChar

Specifies the code point of the last character in the group of consecutive characters where the "ABC" widths are sought. This range is inclusive. An error is returned if the specified last character precedes the specified first character.

lpABCF

Points to an application-supplied buffer with an array of ABCFLOAT structures to receive the character widths when the function returns. The ABCFLOAT structure has the following form:

typedef struct _ABCFLOAT { /* abcf */

    FLOAT   abcfA;

    FLOAT   abcfB;

    FLOAT   abcfC;

} ABCFLOAT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Unlike the GetCharABCWidths function that returns widths only for TrueType® fonts, the GetCharABCWidthsFloat function retrieves widths for any font. The widths returned by this function are in the IEEE floating-point format.

If the current world to device transformation is not identified, the returned widths may be noninteger values, even if the corresponding values in the device space are integer.

"A" spacing is the distance added to the current position before placing the glyph. "B" spacing is the width of the black part of the glyph. "C" spacing is the distance added to the current position provide white space to the right of the glyph. The total advanced width is given by A+B+C.

The ABC spaces are measured along the character base line of the selected font.

The ABC widths of the default character are used for characters outside the range of the currently selected font.

See Also

»GetCharABCWidths«, »GetCharWidth«, »GetCharWidthFloat«


  GetCharWidth

BOOL GetCharWidth(hdc, iFirstChar, iLastChar, lpBuffer)
HDC  hdc;   /* handle of device context */
UINT  iFirstChar;   /* first character in range to query */
INT  iLastChar;   /* last character in range to query */
LPINT  lpBuffer;   /* address of buffer for widths */

The GetCharWidth function retrieves the widths, in logical coordinates, of consecutive characters in a given range from the current font.

Parameters

hdc

Identifies the device context.

iFirstChar

Specifies the first character in the group of consecutive characters.

iLastChar

Specifies the last character in the group of consecutive characters, which must not precede the specified first character.

lpBuffer

Points to a buffer to receive the widths.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The range is inclusive; that is, the returned widths include the widths of the characters specified by the iFirstChar and iLastChar parameters.

If a character does not exist in the current font, it is assigned the width of the default character.

See Also

»GetCharABCWidths«, »GetCharABCWidthsFloat«, »GetCharWidthFloat«


  GetCharWidthFloat

BOOL GetCharWidthFloat(hdc, iFirstChar, iLastChar, pxBuffer)
HDC  hdc;   /* handle of device context */
UINT  iFirstChar;   /* first-character code point */
UINT  iLastChar;   /* last-character code point */
PFLOAT  pxBuffer;   /* address of buffer that receives width-values */

The GetCharWidthFloat function retrieves the fractional widths of consecutive characters in a given range from the current font.

Parameters

hdc

Identifies the device context.

iFirstChar

Specifies the code point of the first character in the group of consecutive characters.

iLastChar

Specifies the code point of the last character in the group of consecutive characters.

pxBuffer

Points to a buffer to receive the character widths.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The returned widths are in the 32-bit IEEE floating-point format. (The widths are measured along the base line of the characters.)

If the iFirstChar parameter identifies the letter a and the iLastChar parameter identifies the letter z, GetCharWidthFloat retrieves the widths of all lowercase characters.

If a character does not exist in the current font, it is assigned the width of the default character.

See Also

»GetCharABCWidths«, »GetCharABCWidthsFloat«, »GetCharWidth«


  GetClassInfo

BOOL GetClassInfo(hinst, lpszClass, lpwc)
HINSTANCE  hinst;   /* handle of application instance */
LPCTSTR  lpszClass;   /* address of class name string */
LPWNDCLASS  lpwc;   /* address of structure for class data */

The GetClassInfo function retrieves information about a window class.

Parameters

hinst

Identifies the instance of the application that created the class. To retrieve information about classes defined by Windows (such as buttons or list boxes), set this parameter to NULL.

lpszClass

Points to a null-terminated string containing the class name. The name must be that of a preregistered class or a class registered by a previous call to the RegisterClass function. Alternatively, this parameter can be an integer atom. If this parameter is an integer atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value less than 0xC000, must be in the low-order word of lpszClass; the high-order word must be zero.

lpwc

Points to a WNDCLASS structure that receives the information about the class. The WNDCLASS structure has the following form:

typedef struct tagWNDCLASS {    /* wc */

    UINT    style;

    WNDPROC lpfnWndProc;

    int     cbClsExtra;

    int     cbWndExtra;

    HANDLE  hInstance;

    HICON   hIcon;

    HCURSOR hCursor;

    HBRUSH  hbrBackground;

    LPCTSTR lpszMenuName;

    LPCTSTR lpszClassName;

} WNDCLASS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function finds a matching class and successfully copies the data, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetClassLong«, »GetClassName«, »GetClassWord«, »GlobalAddAtom«, »RegisterClass«


  GetClassLong

DWORD GetClassLong(hwnd, nIndex)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* offset of value to retrieve */

The GetClassLong function retrieves the specified 32-bit (long) value from the WNDCLASS structure associated with the given window.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the 32-bit value to retrieve. To retrieve a 32-bit value from the extra class memory, specify the positive, zero-based byte offset of the value to be retrieved. Valid values are in the range zero through the number of bytes of extra class memory, minus four; for example, if you specified 12 or more bytes of extra class memory, a value of 8 would be an index to the third long integer. To retrieve any other value from the WNDCLASS structure, specify one of the following values:

Value	Action
GCL_CBCLSEXTRA	Retrieves the size, in bytes, of the extra memory associated with the class.
GCL_CBWNDEXTRA	Retrieves the size, in bytes, of the extra window memory associated with each window in the class. For information on how to access this memory, see the descriptions of the »GetWindowLong« and »GetWindowWord« functions.
GCL_HBRBACKGROUND	Retrieves the handle of the background brush associated with the class.
GCL_HCURSOR	Retrieves the handle of the cursor associated with the class.
GCL_HICON	Retrieves the handle of the icon associated with the class.
GCL_HMODULE	Retrieves the handle of the module that registered the class.
GCL_MENUNAME	Retrieves the address of the menu name string. The string identifies the menu resource associated with the class.
GCL_STYLE	Retrieves the window-class style bits.
GCL_WNDPROC	Retrieves the address of the window procedure associated with the class.
Return Value

If the function succeeds, the return value is the requested 32-bit value; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Reserve extra class memory by specifying a nonzero value in the cbClsExtra member of the WNDCLASS structure used with the RegisterClass function.

See Also

»GetClassWord«, »GetWindowLong«, »GetWindowWord«, »SetClassLong«, »SetClassWord«


  GetClassName

int GetClassName(hwnd, lpClassName, cchClassName)
HWND  hwnd;   /* handle of window */
LPTSTR  lpClassName;   /* address of buffer for class name */
int  cchClassName;   /* size of buffer, in characters */

The GetClassName function retrieves the name of the class to which the given window belongs.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

lpClassName

Points to the buffer that is to receive the class name string.

cchClassName

Specifies the length, in characters, of the buffer pointed to by the lpClassName parameter. The class name string is truncated if it is longer than the buffer.

Return Value

If the function succeeds, the return value is the number of characters copied to the specified buffer; otherwise, it is zero. To get extended error information, use the GetLastError function.

See Also

»FindWindow«, »GetClassInfo«, »GetClassLong«, »GetClassWord«


  GetClassWord

WORD GetClassWord(hwnd, nIndex)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* offset of value to retrieve */

The GetClassWord function retrieves the 16-bit (word) value at the specified offset into the extra class memory for the window class to which the given window belongs.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the zero-based byte offset of the value to be retrieved. Valid values are in the range zero through the number of bytes of class memory, minus two; for example, if you specified 10 or more bytes of extra class memory, a value of 8 would be an index to the fifth 16-bit integer.

Return Value

If the function succeeds, the return value is the requested 16-bit value; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Reserve extra class memory by specifying a nonzero value in the cbClsExtra member of the WNDCLASS structure used with the RegisterClass function.

The GCW_ values are obsolete in the Win32 application programming interface (API). You must use the GetClassLong function to retrieve the class values of a window.

See Also

»GetClassLong«, »RegisterClass«, »SetClassLong«, »SetClassWord«


  GetClientRect

BOOL GetClientRect(hwnd, lprc)
HWND  hwnd;   /* handle of window */
LPRECT  lprc;   /* address of structure for client coordinates */

The GetClientRect function retrieves the coordinates of a window's client area. The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).

Parameters

hwnd

Identifies the window whose client coordinates are to be retrieved.

lprc

Points to a RECT structure that receives the client coordinates. The left and top members are zero. The right and bottom members contain the width and height of the window. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetWindowRect«


  GetClipboardData

HANDLE GetClipboardData(uFormat)
UINT  uFormat;   /* clipboard format */

The GetClipboardData function retrieves data from the clipboard in the specified format. The clipboard must have been opened previously.

Parameters

uFormat

Specifies a clipboard format. For a description of the clipboard formats, see the »SetClipboardData« function.

Return Value

If the function succeeds, the return value is the handle of a clipboard object in the specified format. Otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

An application can enumerate the available formats in advance by using the EnumClipboardFormats function.

The handle GetClipboardData returns is controlled by the clipboard, not by the application. The application must copy the data immediately, instead of relying on its handle for long-term use. The application must not free the handle or leave it locked.

Windows supports three clipboard formats for text: CF_UNICODETEXT, CF_TEXT, and CF_OEMTEXT. Specify CF_TEXT for ANSI text, CF_UNICODETEXT for Unicode text, and CF_OEMTEXT for text in the OEM character set. If any of the three text formats is placed on the clipboard, all three can be retrieved by using the GetClipboardData function. If necessary, Windows automatically converts data in an available text format to the requested format.

Windows supports two clipboard formats for metafiles: CF_ENHMETAFILE and CF_METAFILEPICT. Specify CF_ENHMETAFILE for enhanced metafiles and CF_METAFILEPICT for Windows metafiles. If either of the two metafile formats is placed on the clipboard, both can be retrieved by GetClipboardData. If necessary, Windows automatically converts data in the available metafile format to the requested format.

If the clipboard contains data in the CF_PALETTE (logical color palette) format, the application should use the SelectPalette and RealizePalette functions to realize (compare) any other data in the clipboard against that logical palette.

See Also

»EnumClipboardFormats«, »SetClipboardData«


  GetClipboardFormatName

int GetClipboardFormatName(uFormat, lpszFormatName, cchFormatName)
UINT  uFormat;   /* clipboard format to retrieve */
LPTSTR  lpszFormatName;   /* address of buffer for name */
int  cchFormatName;   /* length of name string in characters */

The GetClipboardFormatName function retrieves from the clipboard the name of the specified registered format. The function copies the name to the specified buffer.

Parameters

uFormat

Specifies the type of format to be retrieved. This parameter must not specify any of the predefined clipboard formats.

lpszFormatName

Points to the buffer that is to receive the format name.

cchFormatName

Specifies the maximum length, in characters, of the string to be copied to the buffer. If the name exceeds this limit, it is truncated.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer. Otherwise, the return value is zero, indicating the requested format does not exist or is predefined. To get extended error information, use the GetLastError function.

See Also

»EnumClipboardFormats«, »RegisterClipboardFormat«


  GetClipboardOwner

HWND GetClipboardOwner(VOID)

The GetClipboardOwner function retrieves the window handle of the current owner of the clipboard.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the window that owns the clipboard. If the clipboard is not owned, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

The clipboard can still contain data even if the clipboard is not currently owned.

In general, the clipboard owner is the window that last placed data in clipboard. The EmptyClipboard function assigns clipboard ownership.

See Also

»EmptyClipboard«, »GetClipboardViewer«


  GetClipboardViewer

HWND GetClipboardViewer(VOID)

The GetClipboardViewer function retrieves the handle of the first window in the clipboard viewer chain.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the first window in the clipboard viewer chain. If there is no clipboard viewer, the return value is NULL. To get extended error information, use the GetLastError function.

See Also

»GetClipboardOwner«, »SetClipboardViewer«


  GetClipBox

int GetClipBox(hdc, lprc)
HDC  hdc;   /* handle of the device context */
LPRECT  lprc;   /* address of structure with rectangle */

The GetClipBox function retrieves the dimensions of the tightest bounding rectangle that can be drawn around the current visible area on the device. The visible area is defined by the current clipping region or clip path, as well as any overlapping windows.

Parameters

hdc

Identifies the device context.

lprc

Points to a RECT structure that is to receive the rectangle dimensions. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value specifies the clipping box's complexity. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred.


  GetClipCursor

BOOL GetClipCursor(lprc)
LPRECT  lprc;   /* address of structure for rectangle */

The GetClipCursor function retrieves the screen coordinates of the rectangular area to which the cursor is confined.

Parameters

lprc

Points to a RECT structure that receives the screen coordinates of the confining rectangle. The structure receives the dimensions of the screen if the cursor is not confined to a rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The cursor is a shared resource. If an application confines the cursor with the ClipCursor function, it must later release the cursor by using ClipCursor before relinquishing control to another application.

The calling process must have WINSTA_READATTRIBUTES access to the window station.

See Also

»ClipCursor«, »GetCursorPos«


  GetClipRgn

int GetClipRgn(hdc, hrgn)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region */

The GetClipRgn function retrieves a handle identifying the current application-defined clipping region for the given device context.

Parameters

hdc

Identifies the device context.

hrgn

Identifies an existing region before the function is called. After the function returns, this parameter identifies a copy of the current clipping region.

Return Value

If the function succeeds and there is no clipping region for the given device context, the return value is 0; if the function succeeds and there is a clipping region for the given device context, the return value is 1; if an error occurs, the return value is -1.

Comments

An application-defined clipping region is a clipping region identified by the SelectClipRgn function. It is not a clipping region created when the application calls the BeginPaint function.

If the function succeeds, the hrgn parameter identifies a copy of the current clipping region. Subsequent changes to this copy will not affect the current clipping region.

See Also

»SelectClipRgn«


  GetCodeHandle

The GetCodeHandle function has been deleted. Win32 modules are mapped and do not have handles associated with their code addresses.


  GetCodeInfo

The GetCodeInfo function has been deleted.


  GetColorAdjustment

BOOL GetColorAdjustment(hdc, lpca)
HDC  hdc;   /* handle of device context */
LPCOLORADJUSTMENT  lpca;   /* address of coloradjustment structure */

The GetColorAdjustment function retrieves the color adjustment values for the specified device context.

Parameters

hdc

Identifies the device context.

lpca

Points to a COLORADJUSTMENT structure to receive the color adjustment values. The COLORADJUSTMENT structure has the following form:

The COLORADJUSTMENT structure has the following format:

typedef struct  tagCOLORADJUSTMENT {    /* ca */

    WORD  caSize;

    WORD  caFlags;

    WORD  caIlluminantIndex;

    WORD  caRedGamma;

    WORD  caGreenGamma;

    WORD  caBlueGamma;

    WORD  caReferenceBlack;

    WORD  caReferenceWhite;

    SHORT caContrast;

    SHORT caBrightness;

    SHORT caColorfulness;

    SHORT caRedGreenTint;

} COLORADJUSTMENT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetColorAdjustment«


  GetCommandLine

LPTSTR GetCommandLine(VOID)

The GetCommandLine function returns the command line for the current process.

Parameters

This function has no parameters.

Return Value

The return value is the address of the command line for the current process.

Comments

Non-UNICODE console processes written in c can use the argc/argv mechanism to access the command line arguments. The parameters of the command line string, excluding the program name, are also available to such non-UNICODE applications as a parameter of the WinMain function. The reason for the UNICODE exclusion from these options is that WinMain, argc, and argv use LPSTRs for parameters, not LPTSTRs.

See Also

»CreateProcess«, »WinMain«


  GetCommMask

BOOL GetCommMask(hCommDev, lpfdwEvtMask)
HANDLE  hCommDev;   /* handle of the communications device */
LPDWORD  lpfdwEvtMask;   /* address of variable to get the event mask */

The GetCommMask function retrieves the value of the event mask for a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpfdwEvtMask

Points to the 32-bit variable to be filled in with a  mask of events that are currently enabled. This parameter can be one or more of the following values:

Value	Meaning
EV_BREAK	A break was detected on input.
EV_CTS	The CTS (clear-to-send) signal changed state.
EV_DSR	The DSR (data-set-ready) signal changed state.
EV_ERR	A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING	A ring indicator was detected.
EV_RLSD	The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR	Any character was received and placed in the input buffer.
EV_RXFLAG	The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY	The last character in the output buffer was sent.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetCommMask function sets the bits of a 32-bit mask variable to indicate the set of events that can be monitored for a particular communications resource. A handle to the communications resource can be specified in a call to the WaitCommEvent function to wait for one of the events to occur. To modify the event mask of a communications resource, use the SetCommMask function.

See Also

»SetCommMask«


  GetCommModemStatus

BOOL GetCommModemStatus(hCommDev, lpfdwModemStats)
HANDLE  hCommDev;   /* handle of the communications device */
LPDWORD  lpfdwModemStats;   /* address of control-register values */

The GetCommModemStatus function retrieves modem control-register values.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpfdwModemStats

Points to a 32-bit variable whose bits are set to indicate the current state of the modem control-register values. This parameter can be a combination of the following flags:

Value	Meaning
MS_CTS_ON	The CTS (clear-to-send) signal is on.
MS_DSR_ON	The DSR (data-set-ready) signal is on.
MS_RING_ON	The ring indicator signal is on.
MS_RLSD_ON	The RLSD (receive-line-signal-detect) signal is on.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetCommModemStatus function is useful when you are using the WaitCommEvent function to monitor the CTS, RLSD, DSR, or ring indicator signals. To detect when these signals change state, use WaitCommEvent and then use GetCommModemStatus to determine the state after a change occurs.

The function fails if the hardware does not support the control-register values.

See Also

»WaitCommEvent«


  GetCommProperties

BOOL GetCommProperties(hCommDev, lpcmmp)
HANDLE  hCommDev;   /* handle of the communications device */
LPCOMMPROP  lpcmmp;   /* address of communications properties structure */

The GetCommProperties function fills a buffer with information about the communications properties for a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpcmmp

Points to a COMMPROP structure in which the communications properties information is returned. The structure can be used in subsequent calls to the SetCommState, SetCommTimeouts, or SetupComm functions to configure the communications device. The COMMPROP structure has the following form:

typedef struct _COMMPROP { /* cmmp */

    WORD  wPacketLength;       /* packet size, in bytes    */

    WORD  wPacketVersion;      /* packet version           */

    DWORD dwServiceMask;       /* services implemented     */

    DWORD dwReserved1;         /* reserved                 */

    DWORD dwMaxTxQueue;        /* max Tx bufsize, in bytes */

    DWORD dwMaxRxQueue;        /* max Rx bufsize, in bytes */

    DWORD dwMaxBaud;           /* max baud rate, in bps    */

    DWORD dwProvSubType;       /* specific provider type   */

    DWORD dwProvCapabilities;  /* capabilities supported   */

    DWORD dwSettableParams;    /* changable parameters     */

    DWORD dwSettableBaud;      /* allowable baud rates     */

    WORD  wSettableData;       /* allowable byte sizes     */

    WORD  wSettableStopParity; /* stop bits/parity allowed */

    DWORD dwCurrentTxQueue;    /* Tx buffer size, in bytes */

    DWORD dwCurrentRxQueue;    /* Rx buffer size, in bytes */

    DWORD dwProvSpec1;         /* provider-specific data   */

    DWORD dwProvSpec2;         /* provider-specific data   */

    WCHAR wcProvChar[1];       /* provider-specific data   */

} COMMPROP;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetCommProperties function returns information from a device driver about the configuration settings that are supported by the driver.

See Also

»SetCommState«, »SetCommTimeouts« »SetupComm«,


  GetCommState

BOOL GetCommState(hCommDev, lpdcb)
HANDLE  hCommDev;   /* handle of the communications device */
LPDCB  lpdcb;   /* address of device-control block structure */

The GetCommState function fills in a device-control block (a DCB structure) with the current control settings for a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpdcb

Points to the DCB structure in which the control settings information is returned. The DCB structure has the following form:

typedef struct _DCB { /* dcb */

    DWORD DCBlength;           /* sizeof(DCB)                */

    DWORD BaudRate;            /* current baud rate          */

    DWORD fBinary: 1;          /* binary mode, no EOF check  */

    DWORD fParity: 1;          /* enable parity checking     */

    DWORD fOutxCtsFlow:1;      /* CTS output flow control    */

    DWORD fOutxDsrFlow:1;      /* DSR output flow control    */

    DWORD fDtrControl:2;       /* DTR flow control type      */

    DWORD fDsrSensitivity:1;   /* DSR sensitivity            */

    DWORD fTXContinueOnXoff:1; /* XOFF continues Tx          */

    DWORD fOutX: 1;        /* XON/XOFF out flow control      */

    DWORD fInX: 1;         /* XON/XOFF in flow control       */

    DWORD fErrorChar: 1;   /* enable error replacement       */

    DWORD fNull: 1;        /* enable null stripping          */

    DWORD fRtsControl:2;   /* RTS flow control               */

    DWORD fAbortOnError:1; /* abort reads/writes on error    */

    DWORD fDummy2:17;      /* reserved                       */

    WORD wReserved;        /* not currently used             */

    WORD XonLim;           /* transmit XON threshold         */

    WORD XoffLim;          /* transmit XOFF threshold        */

    BYTE ByteSize;         /* number of bits/byte, 4-8       */

    BYTE Parity;           /* 0-4=no,odd,even,mark,space     */

    BYTE StopBits;         /* 0,1,2 = 1, 1.5, 2              */

    char XonChar;          /* Tx and Rx XON character        */

    char XoffChar;         /* Tx and Rx XOFF character       */

    char ErrorChar;        /* error replacement character    */

    char EofChar;          /* end of input character         */

    char EvtChar;          /* received event character       */

} DCB;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetCommState«


  GetCommTimeouts

BOOL GetCommTimeouts(hCommDev, lpct)
HANDLE  hCommDev;   /* handle of the communications device */
LPCOMMTIMEOUTS  lpct;   /* address of comm timeouts structure */

The GetCommTimeouts function retrieves the timeout parameters for all read and write operations on a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpct

Points to a COMMTIMEOUTS structure in which the timeout information is returned. The COMMTIMEOUTS structure has the following form:

typedef struct _COMMTIMEOUTS { /* ctmo */

    DWORD ReadIntervalTimeout;

    DWORD ReadTotalTimeoutMultiplier;

    DWORD ReadTotalTimeoutConstant;

    DWORD WriteTotalTimeoutMultiplier;

    DWORD WriteTotalTimeoutConstant;

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

For more information about timeout values for communications devices, see the »SetCommTimeouts« function.

See Also

»SetCommTimeouts«


  GetComputerName

BOOL GetComputerName(lpszName, lpcchBuffer)
LPTSTR  lpszName;   /* address of name buffer */
LPDWORD  lpcchBuffer;   /* address of size of name buffer */

The GetComputerName function retrieves the computer name of the current system. This name is established at system startup, when it is initialized from the registry.

Parameters

lpszName

Points to a buffer to receive the null-terminated character string containing the computer name.

lpcchBuffer

Points to a variable that specifies the maximum size, in characters, of the buffer. This value should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1 characters.

Return Value

If the function succeeds, the return value is TRUE and the variable at lpcchBuffer contains the number of characters copied to the destination buffer, not including the terminating null character. If the function fails, the return value is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetComputerName«


  GetConsoleCP

UINT GetConsoleCP(VOID)

The GetConsoleCP function returns the identity of the input code page used by the console associated with the calling process. A console uses its input code page to translate keyboard input into the corresponding character value.

Parameters

This function has no parameters.

Return Value

The return value is a code that identifies the code page.

Comments

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To set a console's input code page, use the SetConsoleCP function. To set and query a console's output code page, use the SetConsoleOutputCP and GetConsoleOutputCP functions.

See Also

»GetConsoleOutputCP«, »SetConsoleCP«, »SetConsoleOutputCP«


  GetConsoleCursorInfo

BOOL GetConsoleCursorInfo(hConsoleOutput, pcci)
HANDLE  hConsoleOutput;   /* handle of console screen buffer */
PCONSOLE_CURSOR_INFO  pcci;   /* address of cursor information */

The GetConsoleCursorInfo function retrieves the size and visibility of the cursor for the specified console screen buffer.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_READ access.

pcci

Points to a CONSOLE_CURSOR_INFO structure in which information about the console's cursor is returned. The CONSOLE_CURSOR_INFO structure has the following form:

typedef struct _CONSOLE_CURSOR_INFO { /* cci */

    DWORD  dwSize;

    BOOL   bVisible;

} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetConsoleCursorInfo«


  GetConsoleMode

BOOL GetConsoleMode(hConsole, lpfdwMode)
HANDLE  hConsole;   /* handle of console input or screen buffer */
LPDWORD  lpfdwMode;   /* current mode flags */

The GetConsoleMode function reports the current input mode of a console's input buffer or the current output mode of a console screen buffer.

Parameters

hConsole

Identifies a console input buffer or a screen buffer. The handle must have GENERIC_READ access.

lpfdwMode

Points to a 32-bit variable whose bits are set to indicate the current mode of the specified buffer.

If the hConsole parameter is an input handle, the mode can be a combination of the following values. When a console is created, all input modes except ENABLE_WINDOW_INPUT are enabled by default.

Value	Meaning
ENABLE_LINE_INPUT	The ReadFile or ReadConsole function returns only when a carriage return character is read. If this mode is disabled, the functions return when one or more characters are available.
ENABLE_ECHO_INPUT	Characters read by the ReadFile or ReadConsole function are written to the active screen buffer as they are read. This mode can be used only if the ENABLE_LINE_INPUT mode is also enabled.
ENABLE_PROCESSED_INPUT	CTRL+C is processed by the system and is not placed in the input buffer. If the input buffer is being read by ReadFile or ReadConsole, other control keys are processed by the system and are not returned in the ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is also enabled, backspace, carriage return, and linefeed characters are handled by the system.
ENABLE_WINDOW_INPUT	User interactions that change the size of the console screen buffer are reported in the console's input buffer. Information about these events can be read from the input buffer by applications using the ReadConsoleInput function, but not by those using ReadFile or ReadConsole.
ENABLE_MOUSE_INPUT	If the mouse pointer is within the borders of the console window and the window has the keyboard focus, mouse events generated by mouse movement and button presses are placed in the input buffer. These events are discarded by ReadFile or ReadConsole, even when the ENABLE_MOUSE_INPUT mode is enabled.
If the hConsole parameter is a screen buffer handle, the mode can be a combination of the following values. When a screen buffer is created, both output modes are enabled by default.

Value	Meaning
ENABLE_PROCESSED_OUTPUT
	Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or ReadConsole function are parsed for ASCII control sequences and the correct action is performed. Backspace, tab, bell, carriage return, and linefeed characters are processed.
ENABLE_WRAP_AT_EOL_OUTPUT
	When writing with WriteFile or WriteConsole or echoing with ReadFile or ReadConsole, the cursor moves to the beginning of the next line when it reaches the end of the current row. This causes the lines displayed in the console window to scroll up automatically when the cursor advances beyond the last line in the window. It also causes the contents of the screen buffer to scroll up (discarding the top line of the screen buffer) when the cursor advances beyond the last line in the screen buffer. If this mode is disabled, the last character in the row is overwritten.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A console consists of an input buffer and one or more screen buffers. The mode of a console buffer determines how the console behaves during input or output (I/O) operations. One set of flag constants is used with input handles, and another set is used with screen buffer (output) handles. Setting the output modes of one screen buffer does not affect the output modes of other screen buffers.

The ENABLE_LINE_INPUT and ENABLE_ECHO_INPUT modes only affect processes that use ReadFile or ReadConsole to read from the console's input buffer. Similarly, the ENABLE_PROCESSED_INPUT mode primarily affects ReadFile and ReadConsole users, except that it also determines whether CTRL+C input is reported in the input buffer (to be read by the ReadConsoleInput function) or is passed to a function defined by the application.

The ENABLE_WINDOW_INPUT and ENABLE_MOUSE_INPUT modes determine whether user interactions involving window resizing and mouse actions are reported in the input buffer or discarded. These events can be read by ReadConsoleInput, but they are always filtered by ReadFile and ReadConsole.

The ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT modes only affect processes using ReadFile or ReadConsole and WriteFile or WriteConsole.

To change a console's (I/O) modes, use the SetConsoleMode function.

See Also

»ReadConsole«, »ReadConsoleInput«, »ReadFile«, »SetConsoleMode«, »WriteConsole«, »WriteFile«


  GetConsoleOutputCP

UINT GetConsoleOutputCP(VOID)

The GetConsoleOutputCP function returns the identity of the output code page used by the console associated with the calling process. A console uses its output code page to translate the character values written by the various output functions into the images displayed in the console window.

Parameters

This function has no parameters.

Return Value

The return value is a code that identifies the code page.

Comments

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To set a console's output code page, use the SetConsoleOutputCP function. To set and query a console's input code page, use the SetConsoleCP and GetConsoleCP functions.

See Also

»GetConsoleCP«, »SetConsoleCP«, »SetConsoleOutputCP«


  GetConsoleScreenBufferInfo

BOOL GetConsoleScreenBufferInfo(hConsoleOutput, pcsbi)
HANDLE  hConsoleOutput;   /* handle of console screen buffer */
PCONSOLE_SCREEN_BUFFER_INFO  pcsbi;   /* address of screen info. buffer */

The GetConsoleScreenBufferInfo function retrieves information about the specified console screen buffer.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_READ access.

pcsbi

Points to a CONSOLE_SCREEN_BUFFER_INFO structure in which the screen buffer information is returned. The CONSOLE_SCREEN_BUFFER_INFO structure has the following form:

typedef struct _CONSOLE_SCREEN_BUFFER_INFO { /* csbi */

    COORD      dwSize;

    COORD      dwCursorPosition;

    WORD       wAttributes;

    SMALL_RECT srWindow;

    COORD      dwMaximumWindowSize;

} CONSOLE_SCREEN_BUFFER_INFO ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The rectangle returned in the srWindow member of the CONSOLE_SCREEN_BUFFER_INFO structure can be modified and then passed to the SetConsoleWindowInfo function to scroll the screen buffer in the window, to change the size of the window, or both.

All coordinates returned in the CONSOLE_SCREEN_BUFFER_INFO structure are in character cell coordinates, where the origin (0, 0) is at the upper left corner of the screen buffer.

See Also

»GetLargestConsoleWindowSize«, »SetConsoleCursorPosition«, »SetConsoleScreenBufferSize«, »SetConsoleWindowInfo«


  GetConsoleTitle

DWORD GetConsoleTitle(lpszTitle, cchTitle)
LPTSTR  lpszTitle;   /* address of buffer for title */
DWORD  cchTitle;   /* size of the buffer */

The GetConsoleTitle function retrieves the title bar string for the current console window.

Parameters

lpszTitle

Points to a buffer that receives a null-terminated string containing the string that appears in the title bar of the console window.

cchTitle

Specifies the size, in characters, of the buffer pointed to by the lpszTitle parameter.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

To set the title bar string for a console window, use the SetConsoleTitle function.

See Also

»SetConsoleTitle«


  GetCPInfo

BOOL GetCPInfo(uCodePage, lpCPInfo)
UINT  uCodePage;   /* code page */
LPCPINFO  lpCPInfo;   /* address of structure for information */

The GetCPInfo function retrieves information about any valid installed or available code page.

Parameters

uCodePage

Specifies the code page about which information is to be retrieved. You can use any valid installed or available code page value. The following predefined values are among those that may be used:

Value	Meaning
CP_ACP	ANSI code page
CP_OEMCP	OEM code page
lpCPInfo

Points to a CPINFO structure that receives information about the code page. The CPINFO structure has the following form:

struct tagCPINFO {

    UINT MaxCharSize;

    BYTE DefaultChar[MAX_DEFAULTCHAR];

    BYTE LeadByte[MAX_LEADBYTES];

} CPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetACP«, »GetOEMCP«


  GetCurrentDirectory

DWORD GetCurrentDirectory(cchCurDir, lpszCurDir)
DWORD  cchCurDir;   /* size, in characters, of directory buffer */
LPTSTR  lpszCurDir;   /* address of buffer for current directory */

The GetCurrentDirectory function retrieves the current directory for the current process.

Parameters

cchCurDir

Specifies the length, in characters, of the buffer for the current directory string. The buffer length must include room for a terminating null character.

lpszCurDir

Points to the buffer for the current directory string. This null-terminated string specifies the absolute path to the current directory.

Return Value

If the function succeeds, the return value specifies the number of characters written to the buffer, not including the terminating null character; otherwise, it is zero. To get extended error information, use the GetLastError function.

If the lpszCurDir buffer is not large enough, the return value specifies the required size of the buffer, not including the number of bytes necessary for a terminating null character.

See Also

»CreateDirectory«, »GetSystemDirectory«, »GetWindowsDirectory«, »RemoveDirectory«, »SetCurrentDirectory«


  GetCurrentObject

HGDIOBJ GetCurrentObject(hdc, uObjectType)
HDC  hdc;   /* handle of device context */
UINT  uObjectType;   /* object-type identifier */

The GetCurrentObject function returns the currently selected object of the specified type.

Parameters

hdc

Identifies the device context (DC).

uObjectType

Specifies the object type to be queried. This parameter can be one of the following values:

Value	Meaning
OBJ_PEN	Returns the current selected pen.
OBJ_BRUSH	Returns the current selected brush.
OBJ_PAL	Returns the current selected palette.
OBJ_FONT	Returns the current selected font.
OBJ_BITMAP	Returns the current selected bitmap if hdc is a memory DC.
Return Value

If the function succeeds, the return value is the handle of the specified object. Otherwise, it is NULL.

Comments

An application can use the GetCurrentObject and GetObject functions to retrieve descriptions of the graphic objects currently selected into the given device context.

See Also

»DeleteObject«, »GetObject«, »SelectObject«


  GetCurrentPDB

The GetCurrentPDB function has been deleted. For Win32 applications, use the GetCommandLine and GetEnvironmentStrings functions.

See Also

»GetCommandLine«, »GetEnvironmentStrings«


  GetCurrentPosition

The GetCurrentPosition function has been deleted. Win32 should use the GetCurrentPositionEx function.

See Also

»GetCurrentPositionEx«


  GetCurrentPositionEx

BOOL GetCurrentPositionEx(hdc, lpPoint)
HDC  hdc;   /* handle of device context */
LPPOINT  lpPoint;   /* address of structure receiving current position */

The GetCurrentPositionEx function retrieves the current position in logical coordinates.

Parameters

hdc

Identifies the device context.

lpPoint

Points to a POINT structure that receives the coordinates of the current position. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»MoveToEx«


  GetCurrentProcess

HANDLE GetCurrentProcess(VOID)

The GetCurrentProcess function returns a pseudohandle for the current process.

Parameters

This function has no parameters.

Return Value

The return value is a pseudohandle to the current process.

Comments

A pseudohandle is a special constant that is interpreted as the current process handle. The calling process can use this handle to specify its own process whenever a process handle is required. Pseudohandles are not inherited by child processes.

This handle has the maximum possible access to the process object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is PROCESS_ALL_ACCESS.

A process can create a "real" handle to itself that is valid in the context of other processes, or that can be inherited by other processes, by specifying the pseudohandle as the source handle in a call to the DuplicateHandle function. A process can also use the OpenProcess function to open a real handle to itself.

The pseudohandle need not be closed when it is no longer needed. Calling the CloseHandle function with a pseudohandle has no effect. If the pseudohandle is duplicated by DuplicateHandle, the duplicate handle must be closed.

See Also

»CloseHandle«, »DuplicateHandle«, »GetCurrentProcessId«, »GetCurrentThread«, »OpenProcess«


  GetCurrentProcessId

DWORD GetCurrentProcessId(VOID)

The GetCurrentProcessId function returns the process identifier of the calling process.

Parameters

This function has no parameters.

Return Value

The return value is the process identifier of the calling process.

Comments

Until the process terminates, the process identifier uniquely identifies the process throughout the system.

See Also

»GetCurrentProcess«, »OpenProcess«


  GetCurrentTask

The GetCurrentTask function has been deleted. For Win32 applications, use the GetCurrentThread or GetCurrentProcess function.


  GetCurrentThread

HANDLE GetCurrentThread(VOID)

The GetCurrentThread function returns a pseudohandle for the current thread.

Parameters

This function has no parameters.

Return Value

The return value is a pseudohandle for the current thread.

Comments

A pseudohandle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudohandles are not inherited by child processes.

This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS.

The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle of itself that can be used by other threads, or inherited by other processes, by specifying the pseudohandle as the source handle in a call to the DuplicateHandle function.

The pseudohandle need not be closed when it is no longer needed. Calling the CloseHandle function with this handle has no effect. If the pseudohandle is duplicated by DuplicateHandle, the duplicate handle must be closed.

See Also

»CloseHandle«, »DuplicateHandle«, »GetCurrentProcess«, »GetCurrentThreadId«


  GetCurrentThreadId

DWORD GetCurrentThreadId(VOID)

The GetCurrentThreadId function returns the thread identifier of the calling thread.

Parameters

This function has no parameters.

Return Value

The return value is the thread identifier of the calling thread.

Comments

Until the thread terminates, the thread identifier uniquely identifies the thread throughout the system

See Also

»GetCurrentThread«


  GetCurrentTime

DWORD GetCurrentTime(VOID)

The GetCurrentTime function retrieves the number of milliseconds that have elapsed since Windows was started.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of milliseconds that have elapsed since Windows was started.

Comments

The GetCurrentTime function is identical to the GetTickCount function. Applications should use the GetTickCount function because its name matches more closely what the function does.

The GetCurrentTime and GetMessageTime functions return different times. GetMessageTime returns the Windows time when the given message was created, not the current Windows time.

The internal timer wraps around to zero if Windows is run continuously for approximately 49.7 days.

See Also

»GetMessageTime«, »GetSystemTime«, »GetTickCount«, »SetSystemTime«


  GetCursor

HCURSOR GetCursor(VOID)

The GetCursor function retrieves the handle of the current cursor.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the current cursor; if there is no cursor, the return value is NULL.

See Also

»SetCursor«


  GetCursorPos

BOOL GetCursorPos(lpPoint)
LPPOINT  lpPoint;   /* address of structure for cursor position */

The GetCursorPos function retrieves the cursor's position, in screen coordinates.

Parameters

lpPoint

Points to the POINT structure that is to receive the screen coordinates of the cursor. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The cursor position is always given in screen coordinates and is not affected by the mapping mode of the window that contains the cursor.

The calling process must have WINSTA_READATTRIBUTES access to the window station.

See Also

»ClipCursor«, »SetCursor«, »SetCursorPos«, »ShowCursor«


  GetDC

HDC GetDC(hwnd)
HWND  hwnd;   /* handle of window */

The GetDC function retrieves a handle of a display device context (DC) for the client area of the given window. The display DC can be used in subsequent GDI functions to draw in the client area of the window.

This function retrieves a common, class, or private DC depending on the class style specified for the given window. For common DC, GetDC assigns default attributes to the DC each time it is retrieved. For class and private DCs, GetDC leaves the previously assigned attributes unchanged.

Parameters

hwnd

Identifies the window whose DC is to be retrieved.

Return Value

If the function succeeds, the return value identifies the DC for the given window's client area. Otherwise, it is NULL.

Comments

After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. The number of DCs is limited only by available memory.

See Also

»ReleaseDC«, »GetWindowDC«


  GetDCEx

HDC GetDCEx(hwnd, hrgnClip, flags)
HWND  hwnd;   /* handle of window */
HRGN  hrgnClip;   /* handle of clip region */
DWORD  flags;   /* DC creation flags */

The GetDCEx function retrieves the handle of a display device (DC) context for the given window. The display DC can be used in subsequent GDI functions to draw in the client area.

This function is an extension to the GetDC function that gives an application more control over how and whether clipping occurs in the client area.

Parameters

hwnd

Identifies the window where drawing will occur.

hrgnClip

Specifies a clipping region that may be combined with the visible region of the client window.

flags

Specifies how the DC is created. This parameter can be some combination of the following values:

Value	Meaning
DCX_WINDOW	Returns a DC corresponding to the window rectangle rather than the client rectangle.
DCX_CACHE	Returns a DC from the cache, rather than the OWNDC or CLASSDC window. Essentially, overrides CS_OWNDC and CS_CLASSDC.
DCX_DEFAULTCLIP	Returns a DC by using the default clipping flags specified by WS_CLIPCHILDREN, WS_CLIPSIBLINGS, and WS_PARENTDC.
DCX_PARENTCLIP	Uses the visible region of the parent window. The parent's WS_CLIPCHILDREN and WS_PARENTDC style bits are ignored. The DC origin is set to the upper left corner of the window identified by hwnd.
DCX_CLIPSIBLINGS	Excludes the visible regions of all sibling windows above the window identified by hwnd.
DCX_CLIPCHILDREN	Excludes the visible regions of all child windows below the window identified by hwnd.
DCX_NORESETATTRS	Does not reset the attributes of this DC to the default attributes when this DC is released.
DCX_NORECOMPUTE	If an exact match in the cache is not found, returns NULL rather than creating a new DC. When used with DCX_NORESETATTRS, this gives applications a way to determine whether they must reselect any special attributes.
DCX_LOCKWINDOWUPDATE	Allows drawing even if there is a LockWindowUpdate call in effect that would otherwise exclude this window. Used for drawing during tracking.
DCX_EXCLUDERGN	The clipping region identified by hrgnClip is excluded from the visible region of the returned DC.
DCX_INTERSECTRGN	The clipping region identified by hrgnClip is intersected with the visible region of the returned DC.
DCX_VALIDATE	When specified with DCX_INTERSECTUPDATE, causes the DC to be completely validated. Using this function with both DCX_INTERSECTUPDATE and DCX_VALIDATE is identical to using the BeginPaint function.
Return Value

If the function succeeds, the return value is the handle of the DC for the given window. Otherwise, the return value is NULL, indicating the hwnd parameter is invalid.

Comments

Unless the display DC belongs to a window class, the ReleaseDC function must be called to release the DC after painting. Because only five common DCs are available at any given time, failure to release a DC can prevent other applications from accessing a DC.

A DC belonging to the window's class is returned by the GetDC function if CS_CLASSDC, CS_OWNDC or CS_PARENTDC was specified as a style in the WNDCLASS structure when the class was registered.

See Also

»BeginPaint«, »GetDC«, »GetWindowDC«, »ReleaseDC«


  GetDCOrg

DWORD GetDCOrg(hdc)
HDC  hdc;   /* device context handle */

The GetDCOrg function obtains the final translation origin for the given device context. The final translation origin specifies an offset Windows uses to translate device coordinates into client coordinates (for coordinate in an application's window).

Parameters

hdc

Identifies the device context whose origin is to be retrieved.

Return Value

If the function succeeds, the return value specifies the final translation origin, in device coordinates. The y-coordinate is in the high-order word; the x-coordinate is in the low-order word.

Comments

The final translation origin is relative to the physical origin of the screen.

See Also

»CreateIC«


  GetDesktopWindow

HWND GetDesktopWindow(VOID)

The GetDesktopWindow function returns the handle of the Windows desktop window. The desktop window covers the entire screen; it is the area on top of which all icons and other windows are painted.

Parameters

This function has no parameters.

Return Value

The return value is the handle of the desktop window.

See Also

»GetWindow«


  GetDeviceCaps

int GetDeviceCaps(hdc, nIndex)
HDC  hdc;   /* device context handle */
int  nIndex;   /* index of capability to query */

The GetDeviceCaps function retrieves device-specific information about a given device.

Parameters

hdc

Identifies the device context.

nIndex

Specifies the item to return. This parameter can be one of the following values:

Index	Meaning
DRIVERVERSION	The device driver version.
TECHNOLOGY	Device technology. It can be any one of the following values:
Value	Meaning
DT_PLOTTER	Vector plotter
DT_RASDISPLAY	Raster display
DT_RASPRINTER	Raster printer
DT_RASCAMERA	Raster camera
DT_CHARSTREAM	Character stream
DT_METAFILE	Metafile
DT_DISPFILE	Display file
	If the hdc parameter identifies the device context of an enhanced metafile, the device technology is that of the referenced device as given to the CreateEnhMetaFile function. To determine whether it is an enhanced metafile device context, use the GetObjectType function.
HORZSIZE	Width, in millimeters, of the physical screen.
VERTSIZE	Height, in millimeters, of the physical screen.
HORZRES	Width, in pixels, of the screen.
VERTRES	Height, in raster lines, of the screen.
LOGPIXELSX	Number of pixels per logical inch along the screen width.
LOGPIXELSY	Number of pixels per logical inch along the screen height.
BITSPIXEL	Number of adjacent color bits for each pixel.
PLANES	Number of color planes.
NUMBRUSHES	Number of device-specific brushes.
NUMPENS	Number of device-specific pens.
NUMFONTS	Number of device-specific fonts.
NUMCOLORS	Number of entries in the device's color table.
ASPECTX	Relative width of a device pixel used for line drawing.
ASPECTY	Relative height of a device pixel used for line drawing.
ASPECTXY	Diagonal width of the device pixel used for line drawing.
PDEVICESIZE	Reserved.
CLIPCAPS	Flag that indicates the clipping capabilities of the device. If the device can clip to a rectangle, it is 1. Otherwise, it is 0.
SIZEPALETTE	Number of entries in the system palette. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index and is available only if the driver is compatible with Windows version 3.0 or later.
NUMRESERVED	Number of reserved entries in the system palette. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index and is available only if the driver is compatible with Windows version 3.0 or later.
COLORRES	Actual color resolution of the device, in bits per pixel. This index is valid only if the device driver sets the RC_PALETTE bit in the RASTERCAPS index and is available only if the driver is compatible with Windows version 3.0 or later.
RASTERCAPS	Value that indicates the raster capabilities of the device, as shown in the following table:
Capability	Meaning
RC_BANDING	Requires banding support.
RC_BITBLT	Capable of transferring bitmaps.
RC_BITMAP64	Capable of supporting bitmaps larger than 64K.
RC_DI_BITMAP	Capable of supporting the SetDIBits and GetDIBits functions.
RC_DIBTODEV	Capable of supporting the SetDIBitsToDevice function.
RC_FLOODFILL	Capable of performing flood fills.
RC_GDI20_OUTPUT	Capable of supporting features of Windows 2.0.
RC_PALETTE	Specifies a palette-based device.
RC_SCALING	Capable of scaling.
RC_STRETCHBLT	Capable of performing the StretchBlt function.
RC_STRETCHDIB	Capable of performing the StretchDIBits function.
CURVECAPS	Value that indicates the curve capabilities of the device, as shown in the following table:
Value	Meaning
CC_NONE	Device does not support curves.
CC_CIRCLES	Device can draw circles.
CC_PIE	Device can draw pie wedges.
CC_CHORD	Device can draw chord arcs.
CC_ELLIPSES	Device can draw ellipses.
CC_WIDE	Device can draw wide borders.
CC_STYLED	Device can draw styled borders.
CC_WIDESTYLED	Device can draw borders that are wide and styled.
CC_INTERIORS	Device can draw interiors.
CC_ROUNDRECT	Device can draw rounded rectangles.
LINECAPS	Value that indicates the line capabilities of the device, as shown in the following table:
Value	Meaning
LC_NONE	Device does not support lines.
LC_POLYLINE	Device can draw a polyline.
LC_MARKER	Device can draw a marker.
LC_POLYMARKER	Device can draw multiple markers.
LC_WIDE	Device can draw wide lines.
LC_STYLED	Device can draw styled lines.
LC_WIDESTYLED	Device can draw lines that are wide and styled.
LC_INTERIORS	Device can draw interiors.
POLYGONALCAPS	Value that indicates the polygon capabilities of the device, as shown in the following table:
Value	Meaning
PC_NONE	Device does not support polygons.
PC_POLYGON	Device can draw alternate-fill polygons.
PC_RECTANGLE	Device can draw rectangles.
PC_WINDPOLYGON	Device can draw winding-fill polygons.
PC_SCANLINE	Device can draw a single scanline.
PC_WIDE	Device can draw wide borders.
PC_STYLED	Device can draw styled borders.
PC_WIDESTYLED	Device can draw borders that are wide and styled.
PC_INTERIORS	Device can draw interiors.
TEXTCAPS	Value that indicates the polygon capabilities of the device, as shown in the following table:
Bit	Meaning
TC_OP_CHARACTER	Device is capable of character output precision.
TC_OP_STROKE	Device is capable of stroke output precision.
TC_CP_STROKE	Device is capable of stroke clip precision.
TC_CR_90	Device is capable of 90-degree character rotation.
TC_CR_ANY	Device is capable of any character rotation.
TC_SF_X_YINDEP	Device can scale independently in the x- and y-directions.
TC_SA_DOUBLE	Device is capable of doubled character for scaling.
TC_SA_INTEGER	Device uses integer multiples only for character scaling.
TC_SA_CONTIN	Device uses any multiples for exact character scaling.
TC_EA_DOUBLE	Device can draw double-weight characters.
TC_IA_ABLE	Device can italicize.
TC_UA_ABLE	Device can underline.
TC_SO_ABLE	Device can draw strikeouts.
TC_RA_ABLE	Device can draw raster fonts.
TC_VA_ABLE	Device can draw vector fonts.
TC_RESERVED	Reserved; must be zero.
TC_SCROLLBLT	Device can scroll text using a bit-block transfer.
Return Value

The return value specifies the value of the desired item.

See Also

»CreateEnhMetaFile«, »CreateIC«, »DeviceCapabilitiesEx«, »GetObjectType«


  GetDialogBaseUnits

LONG GetDialogBaseUnits(VOID)

The GetDialogBaseUnits function returns the dialog box base units used by Windows to create dialog boxes. Both Windows and applications use these units to convert the width and height of dialog boxes and controls from dialog units, as given in dialog box templates, to pixels, and vice versa.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the low-order word of the return value contains the horizontal dialog box base unit, and the high-order word contains the vertical dialog box base unit.

Comments

The horizontal base unit is equal to the average width, in pixels, of the characters in the system font; the vertical base unit is equal to the height, in pixels, of the font. Furthermore, each horizontal base unit is equal to 4 horizontal dialog units; each vertical base units is equal to 8 vertical dialog units. Therefore, to convert dialog units to pixels, an application applies the following formulas:

pixelX = (dialogunitX * baseunitX) / 4

pixelY = (dialogunitY * baseunitY) / 8

Similarly, to convert from pixels to dialog units, an application applies the following formulas:

dialogunitX = (pixelX * 4) / baseunitX

dialogunitY = (pixelY * 8) / baseunitY

The multiplication is performed before the division to avoid rounding problems if base units are not divisible by 4 or 8.

See Also

»MapDialogRect«


  GetDIBits

int GetDIBits(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbi, uUsage)
HDC  hdc;   /* handle of device context */
HBITMAP  hbmp;   /* handle of bitmap */
UINT  uStartScan;   /* first scan line to set in destination bitmap */
UINT  cScanLines;   /* number of scan lines to copy */
LPVOID  lpvBits;   /* address of array for bitmap bits */
LPBITMAPINFO  lpbi;   /* address of structure with bitmap data */
UINT  uUsage;   /* RGB or palette index */

The GetDIBits function retrieves the bits of the specified bitmap and copies them into the given buffer using the specified format.

Parameters

hdc

Identifies the device context.

hbmp

Identifies the bitmap.

uStartScan

Specifies the first scan line to retrieve.

cScanLines

Specifies the number of scan lines to retrieve.

lpvBits

Points to a buffer to receive the bitmap data. If this parameter is NULL, the function passes the dimensions and format of the bitmap to the BITMAPINFO structure pointed to by the lpbi parameter.

lpbi

Points to a BITMAPINFO structure that specifies the desired format for the device-independent bitmap (DIB) data. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

uUsage

Specifies the format of the bmiColors member of the BITMAPINFO structure. It must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	The color table should consist of an array of 16-bit indices into the current logical palette.
DIB_RGB_COLORS	The color table should consist of literal red, green, blue (RGB) values.
DIB_PAL_INDICES	There is no color table for the bitmap. Only the BITMAPINFOHEADER portion of the BITMAPINFO structure is filled in.
Return Value

If the function succeeds, the return value is the number of scan lines copied from the bitmap; otherwise, it is zero.

Comments

If the requested format for the DIB matches its internal format, the RGB values for the bitmap are copied. If the requested format doesn't match the internal format, a color table is synthesized. The following table describes the color table synthesized for each format.

Value	Meaning
1_BPP	The color table consists of a black and a white entry.
4_BPP	The color table consists of a mix of colors identical to the standard VGA palette.
8_BPP	The color table consists of a general mix of 256 colors defined by graphics device interface (GDI). (Included in these 256 colors are the 20 colors found in the default logical palette.)
24_BPP	No color table is returned.
If the lpvBits parameter is a valid pointer, the first six members of the BITMAPINFOHEADER must be initialized to specify the size and format of the DIB. The bitmap's color table will be appended to the BITMAPINFO structure.

If lpvBits is NULL, GetDIBits fills in the BITMAPINFO structure, but does not retrieve the bits from the bitmap.

If lpvBits is NULL and the bit count member of the BITMAPINFO structure is initialized to zero, GetDIBits fills in the BITMAPINFOHEADER structure without the color table. This technique can be used to query the attributes of a bitmap.

The bitmap identified by the hbmp parameter must not be selected into a device context when the application calls this function.

The origin for the DIB is the bottom left corner of the bitmap, not the top left corner.

See Also

»SetDIBits«


  GetDiskFreeSpace

BOOL GetDiskFreeSpace(lpszRootPathName, lpSectorsPerCluster, lpBytesPerSector,
lpFreeClusters, lpClusters)
LPTSTR  lpszRootPathName;   /* address of root path name */
LPDWORD  lpSectorsPerCluster;   /* address of sectors per cluster */
LPDWORD  lpBytesPerSector;   /* address of bytes per sector */
LPDWORD  lpFreeClusters;   /* address of number of free clusters */
LPDWORD  lpClusters;   /* address of total number of clusters */

The GetDiskFreeSpace function retrieves information about the specified disk, including the amount of free space on the disk.

Parameters

lpszRootPathName

Points to a null-terminated string that specifies the root directory of the disk to return information about. If lpszRootPathName is NULL, the function uses the root of the current directory.

lpSectorsPerCluster

Points to a variable for the number of sectors per cluster.

lpBytesPerSector

Points to a variable for the number of bytes per sector.

lpFreeClusters

Points to a variable for the total number of free clusters on the disk.

lpClusters

Points to a variable for the total number of clusters on the disk.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetDriveType«


  GetDlgCtrlID

int GetDlgCtrlID(hwndCtl)
HWND  hwndCtl;   /* handle of control */

The GetDlgCtrlID function returns the identifier of the given control.

Parameters

hwndCtl

Identifies the control.

Return Value

If the function succeeds, the return value is the identifier of the control; otherwise, it is NULL, indicating, for example, that hwndCtl is not a valid window handle.

Comments

GetDlgCtrlID accepts child window handles as well as handles of controls in a dialog boxes. An application sets the identifier for a child window when it creates the window by assigning the identifier value to the hmenu parameter when calling the CreateWindow or CreateWindowEx function.

Although GetDlgCtrlID may return a value if hwndCtl identifies a top-level window, top-level windows cannot have identifiers and such a return value is never valid.

See Also

»CreateWindow«, »CreateWindowEx«, »GetDlgItem«


  GetDlgItem

HWND GetDlgItem(hwndDlg, idControl)
HWND  hwndDlg;   /* handle of dialog box */
int  idControl;   /* identifier of control */

The GetDlgItem function retrieves the handle of a control in the given dialog box.

Parameters

hwndDlg

Identifies the dialog box that contains the control.

idControl

Specifies the identifier of the control to be retrieved.

Return Value

If the function succeeds, the return value is the window handle of the given control; otherwise, it is NULL, indicating an invalid dialog box handle or a nonexistent control.

Comments

You can use the GetDlgItem function with any parent-child window pair, not just with dialog boxes. As long as the hwndDlg parameter specifies a parent window and the child window has a unique identifier (as specified by the hMenu parameter in the CreateWindow or CreateWindowEx function that created the child window), GetDlgItem returns a valid handle to the child window.

See Also

»CreateWindow«, »CreateWindowEx«, »GetDlgItemInt«, »GetDlgItemText«


  GetDlgItemInt

UINT GetDlgItemInt(hDlg, nIDDlgItem, lpTranslated, bSigned)
HWND  hDlg;   /* handle of dialog box */
int  nIDDlgItem;   /* identifier of control */
BOOL*  lpTranslated;   /* address of variable for error flag */
BOOL  bSigned;   /* signed or unsigned indicator */

The GetDlgItemInt function translates the text of a control in the given dialog box into an integer value.

Parameters

hDlg

Identifies the dialog box.

nIDDlgItem

Specifies the identifier of the control to be translated.

lpTranslated

Points to the Boolean variable that is to receive the translated flag.

bSigned

Specifies whether the value to be retrieved is signed.

Return Value

If the function succeeds, the return value is the translated value of the control text. Because zero is a valid return value, you must use the lpTranslated parameter to detect errors. If your application requires a signed return value, it should cast the return value as an int type.

Comments

The function retrieves the text of the given control by sending the control a WM_GETTEXT message. The function then translates the text by stripping any extra spaces at the beginning of the text and converting decimal digits. The function stops translating when it reaches the end of the text or encounters a nonnumeric character. If the bSigned parameter is TRUE, the GetDlgItemInt function checks for a minus sign (−) at the beginning of the text and translates the text into a signed number. Otherwise, it creates an unsigned value.

GetDlgItemInt returns zero if the translated number is greater than INT_MAX (for signed numbers) or UINT_MAX (for unsigned numbers). When errors occur, such as encountering nonnumeric characters or exceeding the given maximum, GetDlgItemInt copies zero to the location pointed to by the lpTranslated parameter. If there are no errors, lpTranslated receives a nonzero value. If lpTranslated is NULL, GetDlgItemInt does not warn about errors.

GetDlgItemInt sends a WM_GETTEXT message to the control.

See Also

»GetDlgCtrlID«, »GetDlgItem«, »GetDlgItemText«, »SetDlgItemInt«


  GetDlgItemText

UINT GetDlgItemText(hwndDlg, idControl, lpsz, cchMax)
HWND  hwndDlg;   /* handle of dialog box */
int  idControl;   /* identifier of control */
LPTSTR  lpsz;   /* address of buffer for text */
int  cchMax;   /* maximum size of string */

The GetDlgItemText function retrieves the title or text associated with a control in a dialog box.

Parameters

hwndDlg

Identifies the dialog box that contains the control.

idControl

Specifies the identifier of the control whose title or text is to be retrieved.

lpsz

Points to the buffer to receive the title or text.

cchMax

Specifies the maximum length, in characters, of the string to be copied to the buffer pointed to by lpsz. If the length of the string exceeds the limit, the string is truncated.

Return Value

If the function succeeds, the return value specifies the number of characters copied to the buffer, not including the terminating null character; otherwise, it is zero.

Comments

The GetDlgItemText function sends a WM_GETTEXT message to the control.

See Also

»GetDlgItemInt«, »SetDlgItemInt«, »SetDlgItemText«


  GetDOSEnvironment

The GetDOSEnvironment function has been deleted. For Win32 applications, use the GetEnvironmentStrings function.

See Also

»GetEnvironmentStrings«


GetDoubleClickTime

UINT GetDoubleClickTime(VOID)

The GetDoubleClickTime function retrieves the current double-click time for the mouse. A double-click is a series of two clicks of the mouse button, the second occurring within a specified time after the first. The double-click time is the maximum number of milliseconds that may occur between the first and second click of a double-click.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value specifies the current double-click time, in milliseconds.

See Also

»SetDoubleClickTime«


GetDriveType

UINT GetDriveType(lpszRootPathName)
LPTSTR  lpszRootPathName;   /* address of root path name */

The GetDriveType function determines whether a disk drive is removable, fixed, CD-ROM, RAM disk, or a network drive.

Parameters

lpszRootPathName

Points to a null-terminated string that specifies the root directory of the disk to return information about. If lpszRootPathName is NULL, the function uses the root of the current directory.

Return Value

The return value specifies the type of drive. It can be one of the following values:

Value	Meaning
0	Drive type cannot be determined.
1	Root directory does not exist.
DRIVE_REMOVABLE	Disk can be removed from the drive.
DRIVE_FIXED	Disk cannot be removed from the drive.
DRIVE_REMOTE	Drive is a remote (network) drive.
DRIVE_CDROM	Drive is a CD-ROM drive.
DRIVE_RAMDISK	Drive is a RAM disk.
See Also

»GetDiskFreeSpace«


  GetEnhMetaFile

HENHMETAFILE GetEnhMetaFile(lpszMetaFile)
LPTSTR  lpszMetaFile;   /* address of metafile name */

The GetEnhMetaFile function creates a handle that identifies the enhanced-format metafile stored in the given file.

Parameters

lpszMetaFile

Points to the null-terminated string that specifies the name of an enhanced metafile.

Return Value

If the function succeeds, the return value is a handle of the enhanced metafile; otherwise, it is NULL.

Comments

When the application no longer needs an enhanced-metafile handle, it should delete the handle by calling the DeleteEnhMetaFile function.

A Windows-format metafile must be converted to the enhanced format before it can be processed by the GetEnhMetaFile function. To convert the file, use the SetWinMetaFileBits function.

Where text arguments must use Unicode™ characters, use this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

See Also

»DeleteEnhMetaFile«, »SetWinMetaFileBits«


  GetEnhMetaFileBits

UINT GetEnhMetaFileBits(hemf, cbBuffer, lpbBuffer)
HENHMETAFILE  hemf;   /* handle of metafile */
UINT  cbBuffer;   /* size of data buffer, in bytes */
LPBYTE  lpbBuffer;   /* address of data buffer */

The GetEnhMetaFileBits function retrieves the contents of the given enhanced-format metafile and copies them into a buffer.

Parameters

hemf

Identifies the enhanced metafile.

cbBuffer

Specifies the size, in bytes, of the buffer to receive the data.

lpbBuffer

Points to the buffer to receive the metafile data. The buffer must be sufficiently large to contain the data. If lpbBuffer is NULL, the function returns the size necessary to hold the data.

Return Value

If the function succeeds and the buffer pointer is NULL, the return value is the size of the enhanced metafile, in bytes; if the function succeeds and the buffer pointer is a valid pointer, the return value is the number of bytes copied. Otherwise, the return value is zero.

Comments

After the enhanced-metafile bits are retrieved, they can be used to create a memory-based metafile by calling the SetEnhMetaFileBits function.

The GetEnhMetaFileBits function does not invalidate the enhanced-metafile handle. The application must call the DeleteEnhMetaFile function to delete the handle when it is no longer needed.

The metafile contents retrieved by this function are in the enhanced format. To retrieve the metafile contents in the Windows format, use the GetWinMetaFileBits function.

See Also

»DeleteEnhMetaFile«, »GetWinMetaFileBits«, »SetEnhMetaFileBits«


  GetEnhMetaFileDescription

UINT GetEnhMetaFileDescription(hemf, cchBuffer, lpszDescription)
HENHMETAFILE  hemf;   /* handle of enhanced metafile */
UINT  cchBuffer;   /* size of text buffer, in characters */
LPTSTR  lpszDescription;   /* address of text buffer */

The GetEnhMetaFileDescription function retrieves an optional text description from an enhanced-format metafile and copies the string to the given buffer.

Parameters

hemf

Identifies the enhanced metafile.

cchBuffer

Specifies the size, in characters, of the buffer to receive the data. Only this many characters will be copied.

lpszDescription

Points to the buffer to receive the optional text description.

Return Value

If the text description exists but the buffer pointer is NULL, the return value is the length of the text string, in characters; if the text description exists and the buffer pointer is a valid pointer, the return value is the number of characters copied into the buffer; otherwise, it is GDI_ERROR. If the optional text description does not exist, the return value is zero.

Comments

The optional text description contains two strings, the first identifying the application that created the enhanced metafile and the second identifying the picture contained in the metafile. The strings are separated by a null character and terminated with two null characters — for example, "XYZ Graphics Editor\0Bald Eagle\0\0" where \0 represents the null character.

Where text arguments must use Unicode™ characters, use this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

See Also

»CreateEnhMetaFile«


  GetEnhMetaFileHeader

UINT GetEnhMetaFileHeader(hemf, cbBuffer, lpemh)
HENHMETAFILE  hemf;   /* handle of enhanced metafile */
UINT  cbBuffer;   /* size of buffer, in bytes */
LPENHMETAHEADER  lpemh;   /* address of buffer to receive data */

The GetEnhMetaFileHeader function retrieves the record containing the header for the given enhanced-format metafile.

Parameters

hemf

Identifies the enhanced metafile for which the header is to be retrieved.

cbBuffer

Specifies the size, in bytes, of the buffer to receive the data. Only this many bytes will be copied.

lpemh

Points to an ENHMETAHEADER structure to receive the header record. If this parameter is NULL, the function returns the size of the header record. The ENHMETAHEADER structure has the following format:

typedef struct tagENHMETAHEADER { /* enmh */

    DWORD iType;

    DWORD nSize;

    RECTL rclBounds;

    RECTL rclFrame;

    DWORD dSignature;

    DWORD nVersion;

    DWORD nBytes;

    DWORD nRecords;

    WORD  nHandles;

    WORD  sReserved;

    DWORD nDescription;

    DWORD offDescription;

    DWORD nPalEntries;

    SIZEL szlDevice;

    SIZEL szlMillimeters;

} ENHMETAHEADER;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds and the structure pointer is NULL, the return value is the size of the record that contains the header; if the structure pointer is a valid pointer, the return value is the number of bytes copied. Otherwise, it is zero.

Comments

An enhanced metafile header contains such information as the metafile's size, in bytes; the dimensions of the picture stored in the metafile; the number of records stored in the metafile; the offset to the optional text description; the size of the optional palette, and the resolution of the device on which the picture was created.

The record that contains the enhanced-metafile header is always the first record in the metafile.

See Also

»PlayEnhMetaFile«


  GetEnhMetaFilePaletteEntries

UINT GetEnhMetaFilePaletteEntries(hemf, cEntries, lppe)
HENHMETAFILE  hemf;   /* handle of enhanced metafile */
UINT  cEntries;   /* count of palette entries */
LPPALETTEENTRY  lppe;   /* address of palette-entry array */

The GetEnhMetaFilePaletteEntries function retrieves optional palette entries from the given enhanced-metafile.

Parameters

hemf

Identifies the enhanced metafile.

cEntries

Specifies the number of entries to be retrieved from the optional palette.

lppe

Points to an array of PALETTEENTRY structures to receive the palette colors. The array must contain at least as many structures as there are entries specified by the cEntries parameter. The PALETTEENTRY structure has the following form:

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the array pointer is NULL and the enhanced metafile contains an optional palette, the return value is the number of entries in the enhanced metafile's palette; if the array pointer is a valid pointer and the enhanced metafile contains an optional palette, the return value is the number of entries copied; if the metafile does not contain an optional palette, the return value is zero. Otherwise, the return value is GDI_ERROR.

Comments

An application can store an optional palette in an enhanced metafile by calling the CreatePalette and SetPaletteEntries functions before creating the picture and storing it in the metafile. By doing this, the application can achieve consistent colors when the picture is displayed on a variety of devices.

An application that displays a picture stored in an enhanced metafile can call the GetEnhMetaFilePaletteEntries function to determine whether the optional palette exists. If it does, the application can call the GetEnhMetaFilePaletteEntries function a second time to retrieve the palette entries and then create a logical palette (by using the CreatePalette function), select it into its device context (by using the SelectPalette function), and then realize it (by using the RealizePalette function). After the logical palette has been realized, calling the PlayEnhMetaFile function displays the picture using its original colors.

See Also

»CreatePalette«, »PlayEnhMetaFile«, »RealizePalette«, »SelectPalette«


  GetEnvironmentStrings

LPVOID GetEnvironmentStrings(VOID)

The GetEnvironmentStrings function returns the address of the environment block for the current process.

Parameters

This function has no parameters.

Return Value

The return value is the address of the environment block for the current process.

Comments

Do not use the return value of the GetEnvironmentStrings function to get or set environment variables. Instead, use the GetEnvironmentVariable and SetEnvironmentVariable functions to access the environment variables within this block.

A process can use the return value to specify the environment address used by the CreateProcess function.

See Also

»CreateProcess«, »GetEnvironmentVariable«, »SetEnvironmentVariable«


  GetEnvironmentVariable

DWORD GetEnvironmentVariable(lpszName, lpszValue, cchValue)
LPTSTR  lpszName;   /* address of environment variable name */
LPTSTR  lpszValue;   /* address of buffer for variable value */
DWORD  cchValue;   /* size of buffer in characters */

The GetEnvironmentVariable function retrieves the value of the specified variable from the environment block of the calling process.

Parameters

lpszName

Points to a null-terminated string that specifies the environment variable.

lpszValue

Points to a buffer to receive the value of the specified environment variable.

cchValue

Specifies the size in characters of the lpszValue buffer.

Return Value

If the function succeeds, the return value is the number of characters stored in lpszValue, not including the terminating null character. The return value is zero if the environment variable name was not found in the environment block for the current process. If the lpszValue buffer is not large enough, the return value is the size, in characters, of the buffer required to hold the value string including the terminating null character.

See Also

»GetEnvironmentStrings«, »SetEnvironmentVariable«


  GetExceptionCode

DWORD GetExceptionCode(VOID)

The GetExceptionCode function retrieves a code that identifies the type of exception that occurred. The function can be called only from within the filter expression or exception-handler block of a try-except exception handler.

Parameters

This function has no parameters.

Return Value

The return value identifies the type of exception. Following are the exception codes likely to occur due to common programming errors:

Value	Meaning
EXCEPTION_ACCESS_VIOLATION
	The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
EXCEPTION_BREAKPOINT
	A breakpoint was encountered.
EXCEPTION_DATATYPE_MISALIGNMENT
	The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on.
EXCEPTION_SINGLE_STEP
	A trace trap or other single-instruction mechanism signaled that one instruction has been executed.
EXCEPTION_ARRAY_BOUNDS_EXCEEDED
	The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking.
EXCEPTION_FLT_DENORMAL_OPERAND
	One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.
EXCEPTION_FLT_DIVIDE_BY_ZERO
	The thread tried to divide a floating-point value by a floating-point divisor of zero.
EXCEPTION_FLT_INEXACT_RESULT
	The result of a floating-point operation cannot be represented exactly as a decimal fraction.
EXCEPTION_FLT_INVALID_OPERATION
	This exception represents any floating-point exception not included in this list.
EXCEPTION_FLT_OVERFLOW
	The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.
EXCEPTION_FLT_STACK_CHECK
	The stack overflowed or underflowed as the result of a floating-point operation.
EXCEPTION_FLT_UNDERFLOW
	The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.
EXCEPTION_INT_DIVIDE_BY_ZERO
	The thread tried to divide an integer value by an integer divisor of zero.
EXCEPTION_INT_OVERFLOW
	The result of an integer operation caused a carry out of the most significant bit of the result.
EXCEPTION_PRIV_INSTRUCTION
	The thread tried to execute an instruction whose operation is not allowed in the current machine mode.
STATUS_NONCONTINUABLE_EXCEPTION
	The thread tried to continue execution after a noncontinuable exception occurred.
Comments

The GetExceptionCode function can be called only from within the filter expression or exception-handler block of a try-except statement. The filter expression is evaluated if an exception occurs during execution of the try block, and it determines whether the except block is executed. The following example shows the structure of a try-except statement.

try {

    /* try block */

}

except (filter-expression) {

    /* exception handler block */

}

The filter expression can invoke a filter function. The filter function cannot call GetExceptionCode. However, the return value of GetExceptionCode can be passed as a parameter to a filter function. The return value of the GetExceptionInformation function can also be passed as a parameter to a filter function. GetExceptionInformation returns a pointer to a structure that includes the exception-code information.

In the case of nested try-except statements, each statement's filter expression is evaluated until one is evaluated as EXCEPTION_EXECUTE_HANDLER or EXCEPTION_CONTINUE_EXECUTION. Each filter expression can invoke GetExceptionCode to get the exception code.

The exception code returned is the code generated by a hardware exception, or the code specified in the RaiseException function for a software-generated exception.

See Also

»GetExceptionInformation«, »RaiseException«


  GetExceptionInformation

LPEXCEPTION_POINTERS GetExceptionInformation(VOID)

The GetExceptionInformation function retrieves a machine-independent description of an exception, and information about the machine state that existed for the thread when the exception occurred. This function can be called only from within the filter expression of a try-except exception handler.

Parameters

This function has no parameters.

Return Value

The return value is a pointer to an EXCEPTION_POINTERS structure that contains pointers to two other structures: an EXCEPTION_RECORD structure containing a description of the exception, and a CONTEXT structure containing the machine-state information.

The EXCEPTION_POINTERS structure has the following form:

typedef struct _EXCEPTION_POINTERS { /* exp */

    PEXCEPTION_RECORD ExceptionRecord;

    PCONTEXT ContextRecord;

} EXCEPTION_POINTERS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Comments

The filter expression (from which the function is called) is evaluated if an exception occurs during execution of the try block, and it determines whether the except block is executed. The following example shows the structure of a try-except statement.

try {

    /* try block */

}

except (filter-expression) {

    /* exception handler block */

}

The filter expression can invoke a filter function. The filter function cannot call GetExceptionInformation. However, the return value of GetExceptionInformation can be passed as a parameter to a filter function.

To pass the EXCEPTION_POINTERS information to the exception-handler block, the filter expression or filter function must copy the pointer or the data to safe storage that the handler can later access.

In the case of nested try-except statements, each statement's filter expression is evaluated until one is evaluated as EXCEPTION_EXECUTE_HANDLER or EXCEPTION_CONTINUE_EXECUTION. Each filter expression can invoke GetExceptionInformation to get exception information.

See Also

»GetExceptionCode«


  GetExitCodeProcess

BOOL GetExitCodeProcess(hProcess, lpdwExitCode)
HANDLE  hProcess;   /* handle to the process */
LPDWORD  lpdwExitCode;   /* address to receive termination status */

The GetExitCodeProcess function retrieves the termination status of the specified process.

Parameters

hProcess

Identifies the process. The handle must have PROCESS_QUERY_INFORMATION access.

lpdwExitCode

Points to a 32-bit variable to receive the process termination status.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the specified process has not terminated, the termination status returned is STILL_ACTIVE. If the process has terminated, the termination status returned may be one of the following:

•	The exit code specified in the ExitProcess or TerminateProcess function.

•	The return value from the process's main or WinMain function.

•	The exception code for an unhandled exception that caused the process to terminate.

See Also

»ExitProcess«, »ExitThread«, »TerminateProcess«


  GetExitCodeThread

BOOL GetExitCodeThread(hThread, lpdwExitCode)
HANDLE  hThread;   /* handle to the thread */
LPDWORD  lpdwExitCode;   /* address to receive termination status */

The GetExitCodeThread function retrieves the termination status of the specified thread.

Parameters

hThread

Identifies the thread. The handle must have THREAD_QUERY_INFORMATION access.

lpdwExitCode

Points to a 32-bit variable to receive the thread termination status.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the specified thread has not terminated, the termination status returned is STILL_ACTIVE. If the thread has terminated, the termination status returned may be one of the following:

•	The exit code specified in the ExitThread or TerminateThread function.

•	The return value from the thread function.

•	The exit code of the thread's process.

See Also

»GetExitCodeProcess«, »ExitThread«, »TerminateThread«


  GetExpandedName

INT GetExpandedName(lpszSource, lpszBuffer)
LPTSTR  lpszSource;   /* address of name of compressed file */
LPTSTR  lpszBuffer;   /* address of buffer for original filename */

The GetExpandedName function retrieves the original name of a compressed file, if the file was compressed by using the Microsoft File Compression Utility (COMPRESS.EXE) and the /r option was specified.

Parameters

lpszSource

Points to a string that specifies the name of a compressed file.

lpszBuffer

Points to a buffer that receives the name of the compressed file.

Return Value

If the function succeeds, the return value is 1.

If the function fails, the return value is LZERROR_BADVALUE. Note that GetExpandedName calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Comments

The contents of the buffer pointed to by the lpszBuffer parameter is the original filename if the file was compressed by using the /r option. If the /r option was not used, this function duplicates the name in the lpszSource parameter into the lpszBuffer buffer.


  GetFileAttributes

DWORD GetFileAttributes(lpszFileName)
LPTSTR  lpszFileName;   /* address of the name of the file */

The GetFileAttributes function returns attributes for the specified file.

Parameters

lpszFileName

Points to a null-terminated string that specifies the name of the file.

Return Value

If the function succeeds, the return value contains the attributes of the specified file; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

The attributes can be one or more of the following values:

Value	Meaning
FILE_ATTRIBUTE_ARCHIVE
	The file is an archive file. Applications use this flag to mark files for backup or removal.
FILE_ATTRIBUTE_DIRECTORY
	The file is a directory.
FILE_ATTRIBUTE_HIDDEN
	The file is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL
	The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_READONLY
	The file is a read-only file. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM
	The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY
	The file is a temporary file. Applications can write to the file only if absolutely necessary. Most of the file's data remains in memory without being flushed to the media because the file will soon be deleted.
FILE_ATTRIBUTE_ATOMIC_WRITE
	The file is an atomic write file. Applications write to the file using atomic write semantics. If any write operation flushes data to the medium, all write operations up to that point are also flushed, as well as any file system structures. This ensures that the data is retrievable at a later time.
FILE_ATTRIBUTE_XACTION_WRITE
	Reserved for future use. Do not specify.
See Also

»FindFirstFile«, »FindNextFile«, »SetFileAttributes«


  GetFileInformationByHandle

BOOL GetFileInformationByHandle(hFile, lpFileInformation)
HANDLE  hFile;   /* handle of file */
LPBY_HANDLE_FILE_INFORMATION  lpFileInformation;   /* address of structure */

The GetFileInformationByHandle function retrieves information about the specified file.

Parameters

hFile

Identifies the file to return information about.

lpFileInformation

Points to a BY_HANDLE_FILE_INFORMATION structure that receives the file information. The structure can be used in subsequent calls to GetFileInformationByHandle to refer to the information about the file.

The BY_HANDLE_FILE_INFORMATION structure has the following form:

typedef struct _BY_HANDLE_FILE_INFORMATION { /* bhfi */

    DWORD    dwFileAttributes;

    FILETIME ftCreationTime;

    FILETIME ftLastAccessTime;

    FILETIME ftLastWriteTime;

    DWORD    dwVolumeSerialNumber;

    DWORD    nFileSizeHigh;

    DWORD    nFileSizeLow;

    DWORD    nNumberOfLinks;

    DWORD    nFileIndexHigh;

    DWORD    nFileIndexLow;

} BY_HANDLE_FILE_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»BY_HANDLE_FILE_INFORMATION«


  GetFileResource

The GetFileResource function is not supported in the Win32 API.


  GetFileResourceSize

The GetFileResourceSize function is not supported in the Win32 API.


  GetFileSecurity

BOOL GetFileSecurity(lpszFile, si, psd, cbsd, lpcbsdRequired)
LPTSTR  lpszFile;   /* address of string for file name */
SECURITY_INFORMATION  si;   /* requested information */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
DWORD  cbsd;   /* size of security descriptor buffer */
LPDWORD  lpcbsdRequired;   /* address of required size of buffer */

The GetFileSecurity function obtains specified information about the security of a file or directory. The information obtained is constrained by the caller's access rights and privileges.

Parameters

lpszFile

Points to a null-terminated string specifying the file or directory for which security information is retrieved.

si

Specifies a SECURITY_INFORMATION structure that identifies the security information being requested.

psd

Points to a buffer that receives a copy of the security descriptor of the object specified by the lpszFile parameter. The calling process must have the right to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.

cbsd

Specifies the size, in bytes, of the buffer pointed to by the psd parameter.

lpcbsdRequired

Points to a variable the function sets to zero if the file descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than that of the cbsd parameter when the function returns, none of the security descriptor is copied to the buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

In order to read the security descriptor of a file or directory, the calling process must have READ_CONTROL access or be the owner of the file or directory. Additionally, the caller must have the SE_SECURITY_NAME privilege to read the system access-control list.

See Also

»GetKernelObjectSecurity«, »GetPrivateObjectSecurity«, »GetUserObjectSecurity«, »SetFileSecurity«


  GetFileSize

DWORD GetFileSize(hFile, lpdwFileSizeHigh)
HANDLE  hFile;   /* handle of file to get size of */
LPDWORD  lpdwFileSizeHigh;   /* address of high-order word for file size */

The GetFileSize function retrieves the size, in bytes, of the specified file.

Parameters

hFile

Specifies an open handle of the file whose size is being returned. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.

lpdwFileSizeHigh

Points to the variable where the high-order word of the file size is returned. This parameter can be NULL if the application does not require the high-order word.

Return Value

If the function succeeds, the return value is the low-order doubleword of the file size, and, if lpdwFileSizeHigh is non-NULL, the function puts the high-order doubleword of the file size into the LONG pointed to by that parameter.

If the function fails, and lpdwFileSizeHigh is NULL, the return value is 0xFFFFFFFF. Call GetLastError for extended error information.

If the function fails, and lpdwFileSizeHigh is non-NULL, the return value is 0xFFFFFFFF and GetLastError will return a value other than NO_ERROR.

Comments

Using the GetFileSize function with a handle of a nonseeking device such as a pipe or a communications device has no meaning. Use the GetFileType function to determine the file type for hFile.

Note that, if the return value is 0xFFFFFFFF and lpdwFileSizeHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded or failed. Here is some sample code that illustrates the point:

//

// Case One: calling the function with

//           lpdwFileSizeHigh == NULL

// try to obtain hFile's size

dwSize = GetFileSize (hFile, NULL) ;

// if we failed ...

if (dwSize == 0xFFFFFFFF) {

    // obtain the error code

    dwError = GetLastError() ;

    // deal with that failure

    .

    .

    .

    } // end of error handler

//

// Case Two: calling the function with

//           lpdwFileSizeHigh != NULL

// try to obtain hFile's huge size

dwSizeLow = GetFileSize (hFile, & dwSizeHigh) ;

// if we failed ...

if (dwSizeLow == 0xFFFFFFFF

    &&

    (dwError = GetLastError()) != NO_ERROR ){

    // deal with that failure

    .

    .

    .

    } // end of error handler

See Also

»GetFileType«


  GetFileTime

BOOL GetFileTime(hFile, lpftCreation, lpftLastAccess, lpftLastWrite)
HANDLE  hFile;   /* identifies the file */
LPFILETIME  lpftCreation;   /* address of creation time */
LPFILETIME  lpftLastAccess;   /* address of last access time */
LPFILETIME  lpftLastWrite;   /* address of last write time */

The GetFileTime function retrieves the date and time that a file was created, last accessed, and last modified.

Parameters

hFile

Identifies the files for which to get dates and times. The file handle must have been created with GENERIC_READ access to the file.

lpftCreation

Points to a FILETIME structure to receive the date and time the file was created. The file allocation table (FAT) file system does not record this time. This parameter can be NULL if the application does not require this information.

The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpftLastAccess

Points to a FILETIME structure to receive the date and time the file was last accessed. The FAT file system does not record this time. The last access time includes the last time the file was written to, read from, or (in the case of executable files) run. This parameter can be NULL if the application does not require this information.

lpftLastWrite

Points to a FILETIME structure to receive the date and time the file was last written to. This parameter can be NULL if the application does not require this information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The FAT file system does not record the creation or last access times, but both the high-performance file system (HPFS) and the New Technology file system (NTFS) do.

See Also

»GetFileSize«, »GetFileType«, »SetFileTime«


  GetFileTitle

short GetFileTitle(lpszFile, lpszTitle, cbBuf)
LPCTSTR  lpszFile;   /* address of full path and file name for file */
LPTSTR  lpszTitle;   /* address of buffer that receives filename */
WORD  cbBuf;   /* length of buffer */

The GetFileTitle function returns the title of the file identified by the lpszFile parameter.

Parameters

lpszFile

Points to the name and location of a file.

lpszTitle

Points to a buffer into which the function is to copy the name of the file.

cbBuf

Specifies the length, in characters, of the buffer pointed to by the lpszTitle parameter.

Return Value

If the function succeeds, the return value is zero. If the filename is invalid, the return value is a negative number. If the buffer at lpszTitle is too small, the return value is a positive integer that specifies the required buffer size, in characters.

Comments

The function returns an error value if the buffer pointed to by the lpszFile parameter contains any of the following:

•	An empty string

•	A string containing a wildcard (*), opening bracket ([), or closing bracket (])

•	A string that ends with a colon (:), slash mark (/), or backslash (\)

•	A string whose length exceeded the length of the buffer

•	An invalid character (for example, a space or an unprintable character).

The required buffer size includes the terminating null character.

Note that sizes are specified and received as character counts, not bytes. That provides UNICODE intelligence; the counts are valid for both the _A and _W versions of this function.

To obtain the buffer size needed for the title of a file, call the GetFileTitle function with lpszTitle set to NULL and cbBuf set to zero. The function will return with the requisite value.

See Also

»GetOpenFileName«, »GetSaveFileName«


  GetFileType

DWORD GetFileType(hFile)
HANDLE  hFile;   /* file handle */

The GetFileType function returns the type of the specified file.

Parameters

hFile

Identifies an open file handle.

Return Value

The return value is one of the following values:

Value	Meaning
FILE_TYPE_UNKNOWN	The type of the specified file is unknown.
FILE_TYPE_DISK	The specified file is a disk file.
FILE_TYPE_CHAR	The specified file is a character file, typically, an LPT device or a console.
FILE_TYPE_PIPE	The specified file is either a named or anonymous pipe.
See Also

»GetFileSize«, »GetFileTime«


  GetFileVersionInfo

BOOL GetFileVersionInfo(lpszFile, dwHandle, cbBuf, lpvData)
LPTSTR  lpszFile;   /* address of filename */
DWORD  dwHandle;   /* ignored */
DWORD  cbBuf;   /* size of buffer */
LPVOID  lpvData;   /* address of buffer for file-version info. */

The GetFileVersionInfo function returns version information about the specified file.

As with the other file installation functions, GetFileVersionInfo will only work with Win32 file images. Sixteen-bit Windows file images are not supported.

Parameters

lpszFile

Points to the null-terminated string that specifies the filename.

dwHandle

This parameter is ignored.

cbBuf

Specifies the size of the buffer identified by lpvData. The GetFileVersionInfoSize function returns the buffer size required to hold the file-version information. If the buffer is not large enough, the file-version information is truncated to the size of the buffer.

lpvData

Points to the buffer that receives the file-version information. This parameter is used in a subsequent call to the VerQueryValue function. The data specified by this parameter is always in Unicode format.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetFileVersionInfoSize«, »VerQueryValue«, »VS_VERSION_INFO«


  GetFileVersionInfoSize

DWORD GetFileVersionInfoSize(lpszFile, lpdwHandle)
LPTSTR  lpszFile;   /* address of filename */
LPDWORD  lpdwHandle;   /* always set to zero */

The GetFileVersionInfoSize function determines whether it can retrieve version information from the specified file. If version information is available, GetFileVersionInfoSize returns the size of the buffer required to hold the information.

As with the other file installation functions, GetFileVersionInfoSize will only work with Win32 file images. Sixteen-bit Windows file images are not supported.

Parameters

lpszFile

Points to the null-terminated string that specifies the filename.

lpdwHandle

Points to a variable that this function sets to zero.

Return Value

If the function succeeds, the return value is the buffer size, in characters, required to hold the version information. If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

See Also

»GetFileVersionInfo«, »VerQueryValue«


GetFocus

HWND GetFocus(VOID)

The GetFocus function retrieves the handle of the keyboard focus window associated with the thread that called the function.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the keyboard focus window associated with the calling thread. If the calling thread does not contain a keyboard focus window, the return value is NULL.

Comments

Although a return value of NULL means the calling thread does not have a keyboard focus window, another thread may have a keyboard-focus window.

See Also

»GetActiveWindow«, »GetCapture«, »SetFocus«, »WM_KILLFOCUS«, »WM_SETFOCUS«


  GetFontData

DWORD GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData)
HDC  hdc;   /* handle of device context */
DWORD  dwTable;   /* metric table to query */
DWORD  dwOffset;   /* offset into table being queried */
LPVOID  lpvBuffer;   /* address of buffer for returned data */
DWORD  cbData;   /* length of data to query */

The GetFontData function retrieves font metric data for a TrueType® font.

Parameters

hdc

Identifies the device context.

dwTable

Specifies the name of a font metric table from which the font data is to be retrieved. This parameter can identify one of the metric tables documented in the TrueType Font Files specification, published by Microsoft Corporation. If this parameter is zero, the information is retrieved starting at the beginning of the font file.

dwOffset

Specifies the offset from the beginning of the font metric table to the location where the function should begin retrieving information. If this parameter is zero, the information is retrieved starting at the beginning of the table specified by the dwTable parameter. If this value is greater than or equal to the size of the table, an error occurs.

lpvBuffer

Points to a buffer to receive the font information. If this parameter is NULL, the function returns the size of the buffer required for the font data.

cbData

Specifies the length, in bytes, of the information to be retrieved. If this parameter is zero, GetFontData returns the size of the data specified in the dwTable parameter.

Return Value

If the function succeeds, the return value is the number of bytes returned; otherwise, it is GDI_ERROR.

Comments

An application can sometimes use the GetFontData function to save a TrueType font with a document. To do this, the application determines whether the font can be embedded by checking the otmfsType member of the OUTLINETEXTMETRIC structure. If bit 1 of otmfsType is set, embedding is not permitted for the font. If bit 1 is clear, the font can be embedded. If bit 2 is set, the embedding is read-only. If embedding is permitted, the application can retrieve the entire font file, specifying zero for the dwTable, dwOffset, and cbData parameters.

If an application attempts to use this function to retrieve information for a non-TrueType font, an error occurs.

See Also

»GetTextMetrics«, »OUTLINETEXTMETRIC«


  GetForegroundWindow

HWND GetForegroundWindow(VOID)

The GetForegroundWindow function returns the handle of the foreground window (the window with which the user is currently working). The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.

Parameters

This function has no parameters.

Return Value

The return value is the handle of the foreground window.

See Also

»SetForegroundWindow«


  GetForm

BOOL GetForm(hPrinter, lpszForm, dwLevel, lpbForm, cbBuf, lpdwNeeded)
HANDLE  hPrinter;   /* handle of printer */
LPTSTR  lpszForm;   /* address of form name */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbForm;  /* address of structure array */
DWORD  cbBuf;   /* count of bytes in array */
LPDWORD  lpdwNeeded;   /* addr. of variable with count of bytes retrieved (or required) */

The GetForm function initializes a FORM_INFO_1 structure with data describing the specified form for the given printer.

Parameters

hPrinter

Identifies the printer.

lpszForm

Points to a null-terminated string that specifies the name of the form.

dwLevel

Specifies the version of the structure to which lpbForm points. This value must be 1.

lpbForm

Points to an array of bytes that receives the initialized FORM_INFO_1 structure. The FORM_INFO_1 structure has the following form:

typedef struct _FORM_INFO_1 { /* fi1 */

    LPTSTR pName;

    SIZEL  Size;

    RECTL  ImageableArea;

} FORM_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the array.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The handle hPrinter is obtained by calling the OpenPrinter function.

See Also

»AddForm«, »DeleteForm«


  GetFreeSpace

The GetFreeSpace function is obsolete. Win32 applications should use the GlobalMemoryStatus function.

See Also

»GlobalMemoryStatus«


  GetFullPathName

DWORD GetFullPathName(lpszFile, cchPath, lpszPath, ppszFilePart)
LPCTSTR  lpszFile;   /* address of name of file to find path for */
DWORD  cchPath;   /* size, in characters, of path buffer */
LPTSTR  lpszPath;   /* address of path buffer */
LPTSTR  *ppszFilePart;   /* address of filename in path */

The GetFullPathName function retrieves the full path and filename of a specified file.

Parameters

lpszFile

Points to a null-terminated string that specifies a valid filename.

cchPath

Specifies the size, in characters, of the buffer for the drive and path.

lpszPath

Points to a buffer that contains the null-terminated name of the drive and path.

ppszFilePart

Points to a variable that receives the address (in lpszPath) of the final component in the path.

Return Value

If the GetFullPathName function succeeds, the return value is the length, in characters, of the string copied to lpszPath, not including the terminating null character.

If the lpszPath buffer is too small, the return value is the size of the buffer, in characters, required to hold the path.

If the function fails, the return value is zero. Use the GetLastError function to get extended error information.

Comments

The GetFullPathName function merges the name of the current drive and directory with the specified filename to determine the full path and filename of the specified file. It also calculates the address of the filename portion of the full path and filename. This function does not verify that the resulting path and filename are valid or that they refer to an existing file on the associated volume.

See Also

»GetTempPath«, »SearchPath«


  GetGlyphOutline

DWORD GetGlyphOutline(hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2)
HDC  hdc;   /* handle of device context */
UINT  uChar;   /* character to query */
UINT  uFormat;   /* format of data to return */
LPGLYPHMETRICS  lpgm;   /* address of structure for metrics */
DWORD  cbBuffer;   /* size of buffer for data */
LPVOID  lpvBuffer;   /* address of buffer for data */
CONST LPMAT2  lpmat2;   /* address of transformation matrix structure */

The GetGlyphOutline function retrieves the outline or bitmap for a character in the TrueType® font that is selected into the given device context.

Parameters

hdc

Identifies the device context.

uChar

Specifies the character for which data is to be returned.

uFormat

Specifies the format in which the function returns the data. It can be one of the following values:

Value	Meaning
GGO_BITMAP	Returns the glyph bitmap. For information about memory allocation, see the following "Comments" section.
GGO_NATIVE	Returns the curve data points in the rasterizer's native format and uses the font's design units. When this value is specified, any transformation specified in the lpMatrix parameter is ignored.
GGO_METRICS	Returns only the GLYPHMETRICS structure specified by lpgm. The other buffers are ignored. This value affects the meaning of the function's return value upon failure; see the Returns section below.
lpgm

Points to the GLYPHMETRICS structure describing the placement of the glyph in the character cell. The GLYPHMETRICS structure has the following form:

typedef struct _GLYPHMETRICS { /* glmt */

    UINT  gmBlackBoxX;

    UINT  gmBlackBoxY;

    POINT gmptGlyphOrigin;

    short gmCellIncX;

    short gmCellIncY;

} GLYPHMETRICS;

For more information about this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuffer

Specifies the size of the buffer where the function is to copy information about the outline character. If this value is zero, the function returns the required size of the buffer.

lpvBuffer

Points to the buffer where the function is to copy information about the outline character. If this value is NULL, the function returns the required size of the buffer.

lpmat2

Points to a MAT2 structure specifying a transformation matrix for the character. The MAT2 structure has the following form:

typedef struct _MAT2 { /* mt2 */

    FIXED eM11;

    FIXED eM12;

    FIXED eM21;

    FIXED eM22;

} MAT2;

For more information about this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, and GGO_BITMAP or GGO_NATIVE is specified, the return value is greater than zero.

If the function succeeds, and GGO_METRICS is specified, the return value is zero.

If GGO_BITMAP or GGO_NATIVE is specified, and the buffer size or address is zero, the return value specifies the required buffer size. If GGO_BITMAP or GGO_NATIVE is specified, and the function fails for other reasons, the return value is GDI_ERROR.

If GGO_METRICS is specified, and the function fails, the return value is GDI_ERROR.

Comments

The glyph outline returned by the GetGlyphOutline function is for a grid-fitted glyph. (A grid-fitted glyph has been modified so that its bitmapped image conforms as closely as possible to the original design of the glyph.) If an application needs an unmodified glyph outline, it should request the glyph outline for a character in a font whose size is equal to the font's em unit. The value for a font's em unit is stored in the otmEMSquare member of the OUTLINETEXTMETRIC structure.

An application can rotate characters retrieved in bitmap format by specifying a 2-by-2 transformation matrix in the lpMatrix parameter.

See Also

»GetOutlineTextMetrics«


  GetGraphicsMode

int GetGraphicsMode(hdc)
HDC  hdc;   /* handle of device context */

The GetGraphicsMode function retrieves the current graphics mode for the specified device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is the current graphics mode. It can be one of the following values:

Value	Meaning
GM_DEFAULT	Sets the default graphics mode that is compatible with Windows 3.1. If this value is specified, the application cannot set or modify the world transformation for the specified device context.
GM_ADVANCED	Sets the advanced graphics mode that allows world transformations. This value must be specified if the application will set or modify the world transformation for the specified device context.
Otherwise, the return value is zero.

Comments

An application can set the graphics mode for a device context by calling the SetGraphicsMode function.

See Also

»SetGraphicsMode«


  GetIconInfo

BOOL GetIconInfo(hicon, piconinfo)
HICON  hicon;   /* icon handle */
PICONINFO  piconinfo;   /* address of icon structure */

The GetIconInfo function retrieves information about the given icon or cursor.

Parameters

hicon

Identifies the icon or cursor.

piconinfo

Points to an ICONINFO structure. The function fills in the structure's members.

Return Value

If the function succeeds, the return value is TRUE and the function fills in the members of the specified ICONINFO structure; otherwise, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

GetIconInfo creates bitmaps for the hbmMask and hbmColor members of ICONINFO. The calling application must manage these bitmaps and delete them when they are no longer necessary.

See Also

»CreateIcon«, »CreateIconFromResource«, »CreateIconIndirect«, »DestroyIcon«, »DrawIcon«, »LoadIcon«, »LookupIconIdFromDirectory«


  GetInputState

BOOL GetInputState(VOID)

The GetInputState function determines whether there are mouse-button or keyboard messages in the calling thread's message queue.

Parameters

This function has no parameters.

Return Value

If the queue contains one or more new mouse-button or keyboard messages, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetQueueStatus«


  GetInstanceData

The GetInstanceData function has been deleted. Each Win32 application runs in its own address space.


  GetJob

BOOL GetJob(hPrinter, dwJobId, dwLevel, lpbJob, cbBuf, lpdwNeeded)
HANDLE  hPrinter;   /* handle of printer */
DWORD  dwJobId;   /* job identifier value */
DWORD  dwLevel;   /* data-structure level */
LPBYTE  lpbJob;   /* address of data-structure array */
DWORD  cbBuf;   /* count of bytes in array */
LPDWORD  lpdwNeeded;   /* address of value that contains count of bytes retrieved (or required) */

The GetJob function retrieves print-job data for the given printer.

Parameters

hPrinter

Identifies the printer for which the print-job data is retrieved.

dwJobId

Identifies the print job for which data should be retrieved.

dwLevel

Specifies the version of the structure to which lpbJob points. This value must be either 1 or 2.

lpbJob

Points to an array that contains either a JOB_INFO_1 or a JOB_INFO_2 structure. If dwLevel is 1, this function stores the data in a JOB_INFO_1 structure; if dwLevel is 2, this function stores the data in a JOB_INFO_2 structure.

The JOB_INFO_1 structure has the following form:

typedef struct _JOB_INFO_1 {    /* ji1 */

    DWORD  JobId;

    LPTSTR pPrinterName;

    LPTSTR pMachineName;

    LPTSTR pUserName;

    LPTSTR pDocument;

    LPTSTR pDatatype;

    LPTSTR pStatus;

    DWORD  Status;

    DWORD  Priority;

    DWORD  Position;

    DWORD  TotalPages;

    DWORD  PagesPrinted;

    SYSTEMTIME Submitted;

} JOB_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The JOB_INFO_2 structure has the following form:

typedef struct _JOB_INFO_2 { /* ji2 */

    DWORD      JobId;

    LPTSTR     pPrinterName;

    LPTSTR     pMachineName;

    LPTSTR     pUserName;

    LPTSTR     pDocument;

    LPTSTR     pNotifyName;

    LPTSTR     pDatatype;

    LPTSTR     pPrintProcessor;

    LPTSTR     pParameters;

    LPTSTR     pDriverName;

    LPDEVMODE  pDevMode;

    LPTSTR     pStatus;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD      Status;

    DWORD      Priority;

    DWORD      Position;

    DWORD      StartTime;

    DWORD      UntilTime;

    DWORD      TotalPages;

    DWORD      Size;

    SYSTEMTIME Submitted;

    DWORD      Time;

    DWORD      PagesPrinted ;

} JOB_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the array.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddJob«, »ScheduleJob«, »SetJob«


  GetKernelObjectSecurity

BOOL GetKernelObjectSecurity(hObject, si, psd, cbsd, lpcbsdRequired)
HANDLE  hObject;   /* handle of object to query */
SECURITY_INFORMATION  si;   /* requested information */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
DWORD  cbsd;   /* size of buffer for security descriptor */
LPDWORD  lpcbsdRequired;   /* address of required size of buffer */

The GetKernelObjectSecurity function retrieves a copy of the security descriptor protecting a kernel object.

Parameters

hObject

Identifies a kernel object.

si

Specifies a SECURITY_INFORMATION structure that identifies the security information being requested.

psd

Points to a buffer the function fills with a copy of the security descriptor of the specified object. The calling process must have the right to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.

cbsd

Specifies the size, in bytes, of the buffer pointed to by the psd parameter.

lpcbsdRequired

Points to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of the cbsd parameter when the function returns, none of the security descriptor is copied to the buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To read the kernel object's security descriptor, the calling process must be either granted READ_CONTROL access or be the object's owner. In addition, the calling process must have the SE_SECURITY_NAME privilege to read the system access-control list.

See Also

»GetFileSecurity«, »GetPrivateObjectSecurity«, »GetUserObjectSecurity«, »SetKernelObjectSecurity«


  GetKerningPairs

DWORD GetKerningPairs(hdc, nNumPairs, lpkrnpair)
HDC  hdc;   /* handle of device context */
DWORD  nNumPairs;   /* number of kerning-pairs to be retrieved */
LPKERNINGPAIR  lpkrnpair;   /* address of kerning-pair array */

The GetKerningPairs function retrieves the character-kerning pairs for the currently selected font for the given device context (DC).

Parameters

hdc

Identifies the device context.

nNumPairs

Specifies the number of pairs that fit in the lpkrnpair array. If the font has more than nNumPairs kerning pairs, an error is returned.

lpkrnpair

Points to an array of KERNINGPAIR structures to receive the kerning pairs. The array must contain at least as many structures as specified by the nNumPairs parameter. If this parameter is NULL, the function returns the total number of kerning pairs for the font. The KERNINGPAIR structure has the following form:

typedef struct tagKERNINGPAIR { /* kp */

    WORD wFirst;

    WORD wSecond;

    int  iKernAmount;

} KERNINGPAIR;

For more information about this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the number of kerning-pairs returned; otherwise, it is zero.


  GetKeyboardLayoutName

BOOL GetKeyboardLayoutName(lpszKLName)
LPTSTR  lpszKLName;   /* address of buffer for layout name */

The GetKeyboardLayoutName function retrieves the name of the active keyboard layout.

Parameters

lpszKLName

Points to the buffer of at least KL_NAMELENGTH characters that is to receive the name of the keyboard layout, including the NULL terminator. This will be a copy of the string provided to the LoadKeyboardLayout function, unless layout substitution took place.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»LoadKeyboardLayout«


  GetKeyboardState

BOOL GetKeyboardState(pbKeyState)
PBYTE  pbKeyState;   /* address of array to receive status data */

The GetKeyboardState function copies the status of the 256 virtual keys to the specified buffer.

Parameters

pbKeyState

Points to the 256-byte array that will receive the status data for each virtual key.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread removes keyboard messages from its message queue. The status does not change as keyboard messages are posted to the message queue.

When the function returns, each member of the array pointed to by the pbKeyState parameter contains status data for a virtual key. If the high-order bit is 1, the key is down; otherwise, it is up. If the low-order bit is 1, the key is toggled. A key such as the CAPS LOCK key is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.

To retrieve status information for an individual key, use the GetKeyState function.

An application can use the virtual-key code constants VK_SHIFT, VK_CONTROL and VK_MENU as indices into the array pointed to by pbKeyState. This gives the status of the SHIFT, CTRL, or ALT keys without distinguishing between left and right. An application can also use the following virtual-key code constants as indices to distinguish between the left and right instances of those keys:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU
These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions.

For a complete table of virtual key codes, see Appendix B, "Virtual-Key Codes," in Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetAsyncKeyState«, »GetKeyState«, »MapVirtualKey«, »SetKeyboardState«


  GetKeyboardType

int GetKeyboardType(fnKeybInfo)
int  fnKeybInfo;   /* type of information to retrieve */

The GetKeyboardType function retrieves information about the current keyboard.

Parameters

fnKeybInfo

Specifies the type of keyboard information to be retrieved. This parameter can be one of the following values:

Value	Meaning
0	Keyboard type
1	Keyboard subtype
2	Number of function keys on the keyboard
Return Value

If the function succeeds, the return value specifies the requested information. Otherwise, it is zero.

Comments

The subtype is an original equipment manufacturer (OEM)-dependent value. It may be one of the following values:

Value	Meaning
1	IBM® PC/XT™ or compatible (83-key) keyboard
2	Olivetti® "ICO" (102-key) keyboard
3	IBM AT® (84-key) or similar keyboard
4	IBM enhanced (101- or 102-key) keyboard
5	Nokia® 1050 and similar keyboards
6	Nokia 9140 and similar keyboards
7	Japanese keyboard
The application can also determine the number of function keys on a keyboard from the keyboard type. Following are the number of function keys for each keyboard type:

Type	Number of function keys
1	10
2	12 (sometimes 18)
3	10
4	12
5	10
6	24
7	Hardware dependent and specified by the OEM


  GetKeyNameText

int GetKeyNameText(lParam, lpszBuffer, cchMaxKey)
LONG  lParam;   /* second parameter of keyboard message */
LPTSTR  lpszBuffer;   /* address of buffer for key name */
int  cchMaxKey;   /* maximum length of key-name string length */

The GetKeyNameText function retrieves a string that represents the name of a key.

Parameters

lParam

Specifies the second parameter of the keyboard message (such as WM_KEYDOWN) to be processed. The function interprets the following portions of lParam:

Bits	Meaning
16−23	Scan code.
24	Extended-key flag. Distinguishes some keys on an enhanced keyboard.
25	"Don't care" bit. The application calling this function sets this bit to indicate that the function should not distinguish between left and right CTRL and SHIFT keys, for example.
lpszBuffer

Points to a buffer that will receive the key name.

cchMaxKey

Specifies the maximum length, in characters, of the key name, not including the terminating null character (this parameter should be one less than the size of the buffer pointed to by the lpszBuffer parameter).

Return Value

If the function succeeds a null-terminated string is copied into the specified buffer, and the return value is the length of the string, in characters, not counting the terminating null character.

Comments

The format of the key-name string depends on the current keyboard layout. The keyboard driver maintains a list of names in the form of character strings for keys with names longer than a single character. The key name is translated according to the layout of the currently installed keyboard. The name of a character key is the character itself. The names of dead keys are spelled out in full.


  GetKeyState

SHORT GetKeyState(nVirtKey)
int  nVirtKey;   /* virtual-key code */

The GetKeyState function retrieves the status of the specified virtual key. The status specifies whether the key is up, down, or toggled (on, off — alternating each time the key is pressed).

Parameters

nVirtKey

Specifies a virtual key. If the desired virtual key is a letter or digit (A through Z, a through z, or 0 through 9), nVirtKey must be set to the ASCII value of that character. For other keys, it must be a virtual-key code.

If a non-English keyboard layout is used, virtual keys with values in the range ASCII A through Z and 0 through 9 are used to specify most of the character keys. For example, for the German keyboard layout, the virtual key of value ASCII O (0x4F) refers to the 'o' key, whereas VK_OEM_1 refers to the 'o with umlaut' key.

Return Value

If the function succeeds, the return value specifies the status of the given virtual key. If the high-order bit is 1, the key is down; otherwise, it is up. If the low-order bit is 1, the key is toggled. A key such as the CAPS LOCK key is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.

Comments

The key status returned from this function changes as a given thread reads key messages from its message queue. The status does not reflect the interrupt-level state associated with the hardware. Use GetAsyncKeyState to retrieve that information.

An application calls the GetKeyState function in response to a keyboard-input message. This function retrieves the state of the key when the input message was generated.

To retrieve state information for all the virtual keys, use the GetKeyboardState function.

An application can use the virtual-key code constants VK_SHIFT, VK_CONTROL, and VK_MENU as values for the nVirtKey parameter. This gives the status of the SHIFT, CTRL, or ALT keys without distinguishing between left and right. An application can also use the following virtual-key code constants as values for nVirtKey to distinguish between the left and right instances of those keys:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU
These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions.

For a complete table of virtual key codes, see Appendix B, "Virtual-Key Codes" in Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetAsyncKeyState«, »GetKeyboardState«, »MapVirtualKey«, »SetKeyboardState«


  GetLargestConsoleWindowSize

COORD GetLargestConsoleWindowSize(hConsoleOutput)
HANDLE  hConsoleOutput;   /* handle of console screen buffer */

The GetLargestConsoleWindowSize function returns the size of the largest possible console window, based on the current font and the size of the display.

Parameters

hConsoleOutput

Identifies a console screen buffer.

Return Value

If the function succeeds, the return value is a COORD structure that specifies the number of character cell rows (X member) and columns (Y member) in the largest possible console window. Otherwise, the members of the structure are zero. To get extended error information, use the GetLastError function. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Comments

The function does not take into consideration the size of the screen buffer, which means that the window size returned may be larger than the size of the screen buffer. The GetConsoleScreenBufferInfo function can be used to determine the maximum size of the console window, given the current screen buffer size, the current font, and the display size.

See Also

»GetConsoleScreenBufferInfo«, »SetConsoleWindowInfo«


  GetLastActivePopup

HWND GetLastActivePopup(hwndOwner)
HWND  hwndOwner;   /* handle of owner window */

The GetLastActivePopup function determines which pop-up window owned by the given window was most recently active.

Parameters

hwndOwner

Identifies the owner window.

Return Value

The return value identifies the most recently active pop-up window. The return value is the same as the hwndOwner parameter, if any of the following conditions are met:

•	The window identified by hwndOwner was most recently active.

•	The window identified by hwndOwner does not own any pop-up windows.

•	The window identified by hwndOwner is not a top-level window, or it is owned by another window.

See Also

»AnyPopup«, »ShowOwnedPopups«


  GetLastError

DWORD GetLastError(VOID)

The GetLastError function returns the last-error code.

Parameters

This function has no parameters.

Return Value

The return value is the most recent last-error code code set by the SetLastError function. (Most of the functions in the Win32 API call SetLastError when they fail.)

Comments

An application should call this function immediately after a function call fails (typically indicated by returning FALSE, NULL, 0xFFFFFFFF, or −1) to determine the cause of the failure.

Win32 API functions that return indications of failure call SetLastError when they fail. With one exception, they do NOT call SetLastError when they succeed. So, if three Win32 API function calls are made, and the first one fails and the second two succeed, the error code stored by the first one is still available after the second two succeed. The exception to this no-write-on-success rule is the TlsGetValue function, which needs to clear the last error code when it succeeds to allow checking the error-free retrieval of NULL values.

The last-error code value is maintained on a per-thread basis, so multiple threads do not overwrite each other's last-error code value.

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no Win32 API error code has this bit set. If you are defining an error code for your application, set this bit to indicate that the error code has been defined by an application and to ensure that your error code does not conflict with any system-defined error codes.

See Also

»SetLastError«, »SetLastErrorEx«


  GetLengthSid

DWORD GetLengthSid(psid)
PSID  psid;   /* address of SID to query */

The GetLengthSid function returns the length, in bytes, of a valid SID structure. An SID is a security identifier.

Parameters

psid

Points to the SID structure whose length is returned. The structure is assumed to be valid.

Return Value

If the function succeeds, the return value is the length, in bytes, of the SID structure. If the SID structure is not valid, the return value is undefined. To get extended error information, use the GetLastError function.

See Also

»GetSidLengthRequired«, »GetSidSubAuthorityCount«, »IsValidSid«


  GetLocaleInfoW

int GetLocaleInfoW(lcid, LCType, lpLCData, cchData)
LCID  lcid;   /* locale identifier */
LCTYPE  LCType;   /* type of information */
LPWSTR  lpLCData;   /* address of buffer for information */
int  cchData;   /* size of buffer */

The GetLocaleInfoW function retrieves information about a locale by querying the registry. The function also indicates how much memory is necessary to contain the requested information.

Parameters

lcid

Specifies the identifier for a locale. An application can use the MAKELCID macro to create this identifier.

LCType

Specifies the type of information to be retrieved.

All LCTYPE values are mutually-exclusive, with the exception of LOCALE_NOUSEROVERRIDE. An application may use the binary-OR operator to combine  LOCALE_NOUSEROVERRIDE with any other LCTYPE value. If passed such an LCType value, the function bypasses user overrides, and returns the system default value for the requested LCID.

For a list of LCTYPE constants, see Appendix C, "Locale Identifiers," in Microsoft Win32 Programmer's Reference, Volume 2.

lpLCData

Points to a buffer to receive the requested data.

cchData

Specifies the number of characters that can be contained in the buffer pointed to by the lpLCData parameter. If this value is zero, the return value is the number of characters required to hold the information. (In this case, the buffer pointed to by lpLCData is not used.)

Return Value

If the function succeeds, the return value is the number of characters written to the buffer or, if the cchData parameter is zero, the number of characters required to hold the locale information. Otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The information retrieved is always a null-terminated Unicode™ string. No integers are retrieved by this function, and any numeric values are retrieved as Unicode text.

See Also

»GetStringTypeW«, »GetSystemDefaultLCID«, »GetUserDefaultLCID«


  GetLocalTime

VOID GetLocalTime(lpst)
LPSYSTEMTIME  lpst;   /* address of system time structure */

The GetLocalTime function retrieves the current local date and time.

Parameters

lpst

Points to a SYSTEMTIME structure to receive the current local date and time.

The SYSTEMTIME structure has the following form:

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function does not return a value.

See Also

»GetSystemTime«, »SetLocalTime«


  GetLogicalDrives

DWORD GetLogicalDrives(void)

The GetLogicalDrives function returns a bitmask representing the currently available disk drives.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is a bitmask representing the currently available disk drives. Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.

If the function fails, the return value is zero.

See Also

»GetLogicalDriveStrings«


  GetLogicalDriveStrings

DWORD GetLogicalDriveStrings(cchBuffer, lpszBuffer)
DWORD  cchBuffer;   /* size of the buffer */
LPTSTR  lpszBuffer;   /* address of the buffer for drive strings */

The GetLogicalDriveStrings function fills a buffer with strings that specify valid drives in the system.

Parameters

cchBuffer

Specifies the maximum size, in characters, of the buffer pointed to by lpszBuffer. This size does not include the terminating null character.

lpszBuffer

Points to a buffer that receives a series of null-terminated strings, one for each valid drive in the system, that end with a second null character. The following example shows the buffer contents with <null> representing the null terminator.

        c:\<null>d:\<null><null>

Return Value

If the function succeeds, the return value is the length, in characters, of the strings copied to the buffer, not including the terminating null character. Note that an ANSI-ASCII null character uses one byte, but a Unicode null character uses two bytes.

If the buffer is not large enough, the return value is greater than cchBuffer. It is the size of the buffer required to hold the drive strings.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Comments

Each string in the buffer may be used wherever a root directory is required, such as with the GetDriveType and GetDiskFreeSpace functions.

See Also

»GetLogicalDrives«


  GetMailslotInfo

BOOL GetMailslotInfo(hMailslot, lpcbMaxMsg, lpcbNextMsg, lpcMsg, lpdwReadTimeout)
HANDLE  hMailslot;   /* mailslot handle */
LPDWORD  lpcbMaxMsg;   /* address of maximum message size */
LPDWORD  lpcbNextMsg;   /* address of size of next message */
LPDWORD  lpcMsg;   /* address of number of messages */
LPDWORD  lpdwReadTimeout;   /* address of read time-out */

The GetMailslotInfo function retrieves information about the given mailslot.

Parameters

hMailslot

Identifies a mailslot. The CreateMailslot function must create this handle.

lpcbMaxMsg

Points to a buffer specifying the maximum message size, in bytes, allowed for this mailslot, when the function returns. This value can be greater than or equal to the value specified in the cbMaxMsg parameter of the CreateMailslot function that created the mailslot. An application can set this parameter to NULL.

lpcbNextMsg

Points to a buffer specifying the size, in bytes, of the next message, when the function returns. The following value has special meaning:

Value	Meaning
MAILSLOT_NO_MESSAGE	There is no next message.
An application can set this parameter to NULL.

lpcMsg

Points to a buffer specifying the total number of messages waiting to be read, when the function returns. An application can set this parameter to NULL.

lpdwReadTimeout

Points to a buffer specifying the amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. This parameter is filled in when the function returns. An application can set this parameter to NULL.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreateMailslot«, »SetMailslotInfo«


  GetMapMode

int GetMapMode(hdc)
HDC  hdc;   /* handle of device context */

The GetMapMode function retrieves the current mapping mode.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value specifies the mapping mode; otherwise, it is zero.

Comments

The following list describes the various mapping modes:

Value	Description
MM_ANISOTROPIC	Logical units are mapped to arbitrary units with arbitrarily scaled axes. Use the SetWindowExtEx and SetViewportExtEx functions to specify the units, orientation, and scaling that you want.
MM_HIENGLISH	Each logical unit is mapped to 0.001 inch. Positive x is to the right; positive y is up.
MM_HIMETRIC	Each logical unit is mapped to 0.01 millimeter. Positive x is to the right; positive y is up.
MM_ISOTROPIC	Logical units are mapped to arbitrary units with equally scaled axes; that is, one unit along the x-axis is equal to one unit along the y-axis. Use the SetWindowExtEx and SetViewportExtEx functions to specify the units and the orientation of the axes that you want. Graphics device interface makes adjustments as necessary to ensure the x and y units remain the same size (for example, if you set the window extent, the viewport will be adjusted to keep the units isotropic).
MM_LOENGLISH	Each logical unit is mapped to 0.01 inch. Positive x is to the right; positive y is up.
MM_LOMETRIC	Each logical unit is mapped to 0.1 millimeter. Positive x is to the right; positive y is up.
MM_TEXT	Each logical unit is mapped to one device pixel. Positive x is to the right; positive y is down.
MM_TWIPS	Each logical unit is mapped to one twentieth of a printer's point (1/1440 inch, also called a "twip"). Positive x is to the right; positive y is up.
See Also

»SetMapMode«


  GetMenu

HMENU GetMenu(hwnd)
HWND  hwnd;   /* handle of window */

The GetMenu function retrieves the handle of the menu assigned to the given window.

Parameters

hwnd

Identifies the window whose menu handle is retrieved.

Return Value

If the function succeeds, the return value is the handle of the menu. If the given window has no menu, the return value is NULL. If the window is a child window, the return value is undefined.

See Also

»GetSubMenu«, »SetMenu«


  GetMenuCheckMarkDimensions

LONG GetMenuCheckMarkDimensions(VOID)

The GetMenuCheckMarkDimensions function returns the dimensions of the default check mark bitmap. Windows displays this bitmap next to checked menu items. Before calling the SetMenuItemBitmaps function to replace the default check mark bitmap for a menu item, an application must determine the correct bitmap size by calling GetMenuCheckMarkDimensions.

Parameters

This function has no parameters.

Return Value

The return value specifies the height and width, in pixels, of the default check mark bitmap. The high-order word contains the height; the low-order word contains the width.

See Also

»SetMenuItemBitmaps«


  GetMenuItemCount

int GetMenuItemCount(hmenu)
HMENU  hmenu;   /* handle of menu */

The GetMenuItemCount function determines the number of items in the given menu bar or pop-up menu.

Parameters

hmenu

Identifies the handle of the menu to be examined.

Return Value

If the function succeeds, the return value specifies the number of items in the menu; otherwise, it is −1. To get extended error information, use the GetLastError function.

See Also

»GetMenuItemID«


  GetMenuItemID

UINT GetMenuItemID(hmenu, nPos)
HMENU  hmenu;   /* handle of menu */
int  nPos;   /* position of menu item */

The GetMenuItemID function retrieves the menu item identifier of a menu item located at the specified position in the given menu bar or pop-up menu.

Parameters

hmenu

Identifies the menu bar or pop-up menu that contains the item whose identifier is to be retrieved.

nPos

Specifies the zero-based relative position of the menu item whose identifier is to be retrieved.

Return Value

If the function succeeds, the return value specifies the identifier of the given menu item. If the menu item identifier is NULL or if the specified item invokes a pop-up menu, the return value is 0xFFFFFFFF.

See Also

»GetMenuItemCount«, »GetMenuString«


  GetMenuState

UINT GetMenuState(hmenu, uItem, fuFlags)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item to query */
UINT  fuFlags;   /* menu flags */

The GetMenuState function retrieves the menu flags associated with the specified menu item. If the menu item activates a pop-up menu, this function also returns the number of items in the pop-up menu.

Parameters

hmenu

Identifies the menu that contains the menu item whose flags are to be retrieved.

uItem

Specifies the menu item for which the menu flags are to be retrieved, as determined by the fuFlags parameter.

fuFlags

Specifies how the uItem parameter is interpreted. This parameter can be one of the following values:

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the menu item.
Return Value

If the specified item does not exist, the return value is 0xFFFFFFFF. If the menu item activates a pop-up menu, the low-order byte of the return value contains the menu flags associated with the item (for more information, see the Comments section), and the high-order byte contains the number of items in the pop-up menu activated by the item. Otherwise, the return value is a mask (Boolean OR) of the menu flags. Following are the menu flags associated with the menu item.

Value	Meaning
MF_CHECKED	Places a check mark next to the item (pop-up menus only).
MF_DISABLED	Disables the item.
MF_GRAYED	Disables and grays the item.
MF_HILITE	Highlights the item.
MF_MENUBARBREAK	Functions the same as the MF_MENUBREAK flag, except for pop-up menus where the new column is separated from the old column by a vertical line.
MF_MENUBREAK	Places the item on a new line (for menu bars) or in a new column (for pop-up menus) without separating columns.
MF_SEPARATOR	Creates a horizontal dividing line (for pop-up menus only).
See Also

»GetMenu«, »GetMenuItemCount«, »GetMenuItemID«, »GetMenuString«


  GetMenuString

int GetMenuString(hmenu, idItem, lpsz, cchMax, fuFlags)
HMENU  hmenu;   /* handle of menu */
UINT  idItem;   /* menu item identifier */
LPTSTR  lpsz;   /* address of buffer for string */
int  cchMax;   /* maximum length of string */
UINT  fuFlags;   /* menu flags */

The GetMenuString function copies the text string of the specified menu item into the given buffer.

Parameters

hmenu

Identifies the menu.

idItem

Specifies the menu item to be changed, as determined by the fuFlags parameter.

lpsz

Points to the buffer that is to receive the null-terminated string.

cchMax

Specifies the maximum length, in characters, of the string to be copied. If the string is longer than the maximum specified in cchMax, the extra characters are truncated.

fuFlags

Specifies how the idItem parameter is interpreted. This parameter must be one of the following values:

Value	Meaning
MF_BYCOMMAND	Indicates that the idItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the idItem parameter gives the zero-based relative position of the menu item.
Return Value

If the function succeeds, the return value specifies the number of characters copied to the buffer, not including the terminating null character; otherwise, it is zero.

Comments

The cchMax parameter must be one larger than the number of characters in the text string to accommodate the terminating null character.

See Also

»GetMenuItemID«


  GetMessage

BOOL GetMessage(lpmsg, hwnd, uMsgFilterMin, uMsgFilterMax)
LPMSG  lpmsg;   /* address of structure with message */
HWND  hwnd;   /* handle of window */
UINT  uMsgFilterMin;   /* first message */
UINT  uMsgFilterMax;   /* last message */

The GetMessage function retrieves a message from a thread's message queue and places it in the specified structure. This function only retrieves messages associated with the given window and within the given range of message values. GetMessage does not retrieve messages for windows that belong to other threads or applications.

Parameters

lpmsg

Points to an MSG structure that receives message information from the thread's message queue. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hwnd

Identifies the window whose messages are to be retrieved. If this parameter is NULL, GetMessage retrieves messages for any window that belongs to the thread making the call.

uMsgFilterMin

Specifies the integer value of the lowest message value to be retrieved.

uMsgFilterMax

Specifies the integer value of the highest message value to be retrieved.

Return Value

If a message other than WM_QUIT is retrieved, the return value is TRUE. If the WM_QUIT message is retrieved, the return value is FALSE.

Comments

An application typically uses the return value to determine whether to end the main message loop and exit the program.

The GetMessage function only retrieves messages associated with the window identified by the hwnd parameter or any of its children as specified by the IsChild function, and within the range of message values given by the uMsgFilterMin and uMsgFilterMax parameters. If hwnd is NULL, GetMessage retrieves messages for any window that belongs to the current thread making the call. (GetMessage does not retrieve messages for windows that belong to other threads.) If hwnd is −1, GetMessage only returns messages with a hwnd value of NULL, as posted by the PostAppMessage function. If uMsgFilterMin and uMsgFilterMax are both zero, GetMessage returns all available messages (no range filtering is performed).

The WM_KEYFIRST and WM_KEYLAST constants can be used as filter values to retrieve all messages related to keyboard input; the WM_MOUSEFIRST and WM_MOUSELAST constants can be used to retrieve all mouse messages. If the uMsgFilterMin and uMsgFilterMax parameters are both zero, the GetMessage function returns all available messages (without performing any filtering).

GetMessage does not remove WM_PAINT messages from the queue. The messages remain in the queue until processed.

See Also

»PeekMessage«, »WaitMessage«


  GetMessageExtraInfo

LONG GetMessageExtraInfo(VOID)

The GetMessageExtraInfo function retrieves extra information associated with the last message retrieved by the GetMessage or PeekMessage function. This information may be added to a message by the driver for a pointing device or keyboard.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value specifies the extra information. The meaning of the extra information is device specific.

See Also

»GetMessage«, »PeekMessage«


  GetMessagePos

DWORD GetMessagePos(VOID)

The GetMessagePos function returns a long value that gives the cursor position in screen coordinates. This position is the point occupied by the cursor when the last message retrieved by the GetMessage function occurred.

Parameters

This function has no parameters.

Return Value

The return value specifies the x- and y-coordinates of the cursor position.

Comments

The x-coordinate is in the low-order word of the return value; the y-coordinate is in the high-order word. If the return value is assigned to a variable, you can use the MAKEPOINTS macro to obtain a POINTS structure from the return value. You can also use the LOWORD or HIWORD macro to extract the x- or y-coordinate.

To determine the current position of the cursor instead of the position when the last message occurred, use the GetCursorPos function.

See Also

»GetCursorPos«, »GetMessage«, »GetMessageTime«


  GetMessageTime

LONG GetMessageTime(VOID)

The GetMessageTime function returns the message time for the last message retrieved by the GetMessage function from the current thread's message queue. The time is a long integer that specifies the elapsed time, in milliseconds, from the time the system was started to the time the message was created (placed in the thread's message queue).

Parameters

This function has no parameters.

Return Value

The return value specifies the message time.

Comments

The return value from the GetMessageTime function does not necessarily increase between subsequent messages, because the value wraps to zero if the timer count exceeds the maximum value for a long integer.

To calculate time delays between messages, verify that the time of the second message is greater than the time of the first message and then subtract the time of the first message from the time of the second message.

See Also

»GetMessage«, »GetMessagePos«


  GetMetaFile

HMETAFILE GetMetaFile(lpszFile)
LPCTSTR  lpszFile;   /* address of metafile name */

The GetMetaFile function creates a handle that identifies the given Windows-format metafile.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the GetEnhMetaFile function.

Parameters

lpszFile

Points to the null-terminated string that specifies the name of a Windows-format metafile. (The metafile must already exist.)

Return Value

If the function succeeds, the return value is a handle of the Windows-format metafile; otherwise, it is NULL.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions, such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should use the enhanced-format metafile functions.

An application can call to convert a Windows-format metafile into an enhanced-format metafile, by calling the SetWinMetaFileBits function.

When the application no longer needs the handle returned by GetMetaFile, it should delete the handle by using the DeleteMetaFile function.

Where text arguments must use Unicode™ characters, use the this function as a wide-character function. Where text arguments must use characters from the Windows 3.x character set, use this function as an ANSI function.

See Also

»DeleteMetaFile«, »SetWinMetaFileBits«


  GetMetaFileBits

The GetMetaFileBits function has been deleted. For Win32 applications, use the GetMetaFileBitsEx function.

See Also

»GetMetaFileBitsEx«


  GetMetaFileBitsEx

UINT GetMetaFileBitsEx(hmf, nSize, lpvData)
HMETAFILE  hmf;   /* handle of metafile */
UINT  nSize;   /* size of metafile, in bytes */
LPVOID  lpvData;   /* address of metafile data */

The GetMetaFileBitsEx function retrieves the contents of a Windows-format metafile and copies them into the given buffer.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the GetEnhMetaFileBits function.

Parameters

hmf

Identifies a Windows-format metafile.

nSize

Specifies the size, in bytes, of the buffer to receive the data.

lpvData

Points to the buffer to receive the metafile data. The buffer must be sufficiently large to contain the data. If lpvData is NULL, the function returns the number of bytes required to hold the data.

Return Value

If the function succeeds and the buffer pointer is NULL, the return value is the number of bytes required for the buffer; if the function succeeds and the buffer pointer is a valid pointer, the return value is the number of bytes copied. Otherwise, it is zero.

Comments

After the Windows-metafile bits are retrieved, they can be used to create a memory-based metafile by calling the SetMetaFileBitsEx function.

The GetMetaFileBitsEx function does not invalidate the metafile handle. An application must delete this handle by calling the DeleteMetaFile function.

A Windows-format metafile does not support the new curve, path, and transformation functions, such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should use the enhanced format metafile functions.

To convert a Windows-format metafile into an enhanced-format metafile, use the SetWinMetaFileBits function.

See Also

»BeginPath«, »PolyBezier«, »SetMetaFileBitsEx«, »SetWinMetaFileBits«, »SetWorldTransform«


  GetMetaRgn

int GetMetaRgn(hdc, hrgn)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region */

The GetMetaRgn function retrieves the current metaregion for the given device context.

Parameters

hdc

Identifies the device context.

hrgn

Identifies an existing region before the function is called. After the function returns, this parameter identifies a copy of the current metaregion.

Return Value

If the function succeeds, the return value is 1; otherwise, it is 0.

Comments

If the function succeeds, hrgn identifies a copy of the current metaregion. Subsequent changes to this copy will not affect the current metaregion.

The current clipping region of a device context is defined by the intersection of its clipping region and its metaregion.

See Also

»SetMetaRgn«


  GetMiterLimit

BOOL GetMiterLimit(hdc, peLimit)
HDC  hdc;   /* handle of device context */
PFLOAT  peLimit;   /* address of variable receiving miter limit */

The GetMiterLimit function returns the miter limit for the given device context.

Parameters

hdc

Identifies the device context.

peLimit

Points to a floating-point value where the current miter limit will be returned.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The miter limit is used when drawing geometric lines that have miter joins.

See Also

»ExtCreatePen«, »SetMiterLimit«


  GetModuleFileName

DWORD GetModuleFileName(hinstModule, lpszPath, cchPath)
HANDLE  hinstModule;   /* handle of module to find filename for */
LPTSTR  lpszPath;   /* address of buffer for module path */
DWORD  cchPath;   /* size of buffer in characters */

The GetModuleFileName function retrieves the full path and filename for the executable file containing the given module.

Parameters

hinstModule

Identifies the module whose executable filename is being requested. If the parameter is NULL, GetModuleFileName returns the path for the file used to create the calling process.

lpszPath

Points to a buffer that is filled in with the path and filename of the given module.

cchPath

Specifies the length, in characters, of the lpszPath buffer. If the length of the path and filename exceeds this limit, the string is truncated.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer; otherwise, it is zero. To get extended error information, use the GetLastError function.

See Also

»GetModuleHandle«, »LoadLibrary«


  GetModuleHandle

HANDLE GetModuleHandle(lpszModule)
LPCTSTR  lpszModule;   /* address of module name to return handle for */

The GetModuleHandle function returns a module handle for the specified module, if the file has been mapped into the address space of the calling process.

Parameters

lpszModule

Points to a null-terminated string that names a Win32 module (.DLL or .EXE). If the file extension is omitted, the default library file extension .DLL is appended. The filename string can include a trailing point character (.) to indicate that the module name has no extension. The string need not specify a path. The name is compared (case independently) to the names of modules currently mapped into the calling process.

If this parameter is NULL, GetModuleHandle returns a handle of the file used to create the calling process.

Return Value

If the function succeeds, the return value is a handle to the specified module; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The returned handle is not global, inheritable, or duplicatable, and cannot be used by another process.

The handles returned by GetModuleHandle and LoadLibrary can be used in the same functions, such as GetProcAddress, FreeLibrary, or LoadResource. The difference between the two functions is that LoadLibrary maps the module into the address space of the calling process, if necessary. If it is already mapped, LoadLibrary increments the module's reference count. GetModuleHandle returns the handle of a mapped module without incrementing its reference count.

Note that the reference count is used in FreeLibrary to determine whether to unmap the function from the address space of the process. For this reason, use care when using a handle returned by GetModuleHandle in a call to FreeLibrary. It can cause a dynamic-link library (DLL) module to be unmapped prematurely.

This function must also be used carefully in a multithreaded application. There is no guarantee that the module handle remains valid between the time this function returns the handle and the time it is used by another function. For example, another thread in the same process could free the module and another module could be loaded and given the same module handle, causing the one returned by GetModuleHandle to refer to a module other than the one intended.

See Also

»FreeLibrary«, »GetModuleFileName«, »GetProcAddress«, »LoadLibrary«, »LoadResource«


  GetModuleUsage

The GetModuleUsage function has been deleted. Each Win32 application runs in its own address space.


  GetMsgProc

LRESULT CALLBACK GetMsgProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* removal flag */
LPARAM  lParam;   /* address of structure with message */

The GetMsgProc hook procedure is an application-defined or library-defined callback function the system calls whenever the GetMessage function has retrieved a message from an application message queue. Before passing the retrieved message to the destination window procedure, the system passes the message to the hook procedure.

Parameters

nCode

Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies whether the message has been removed from the queue. This parameter can be one of the following values:

Value	Meaning
PM_NOREMOVE	Specifies that the message has not been removed from the queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
PM_REMOVE	Specifies that the message has been removed from the queue. (An application called GetMessage, or it called the PeekMessage function, specifying the PM_REMOVE flag.)
lParam

Points to an MSG structure that contains details about the message. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

The return value should be zero.

Comments

The GetMsgProc hook procedure can examine or modify the message. After the hook procedure returns control to the system, the GetMessage function returns the message, along with any modifications, to the application that originally called it.

An application installs this hook procedure by specifying the WH_GETMESSAGE hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

GetMsgProc is a placeholder for the application-defined or library-defined function name.

See Also

»CallNextHookEx«, »GetMessage«, »SetWindowsHookEx«


  GetNamedPipeHandleState

BOOL GetNamedPipeHandleState(hNamedPipe, lpdwState, lpdwCurInstances,
lpcbMaxCollect, lpdwCollectTimeout, lpszUser, cchMaxUser)
HANDLE  hNamedPipe;   /* handle of named pipe */
LPDWORD  lpdwState;   /* address of flags indicating pipe state */
LPDWORD  lpdwCurInstances;   /* address of number of current pipe instances */
LPDWORD  lpcbMaxCollect;   /* address of max bytes before remote transmission */
LPDWORD  lpdwCollectTimeout;   /* address of max time before remote transmission */
LPTSTR  lpszUser;   /* address of user name of client process */
DWORD  cchMaxUser;   /* size in characters of user name buffer */

The GetNamedPipeHandleState function retrieves information about the given named pipe. The information returned can vary during the lifetime of an instance of a named pipe.

Parameters

hNamedPipe

Identifies the named pipe about which you want information. The handle must have GENERIC_READ access to the named pipe.

lpdwState

Points to a 32-bit variable that receives flags indicating the current state of the handle. Set the parameter to NULL if the information is not needed. Either or both of the following flags can be set:

Value	Meaning
PIPE_NOWAIT	The pipe handle is in nonblocking mode. If this flag is not set, the pipe handle is in blocking mode.
PIPE_READMODE_MESSAGE	The pipe handle is in message-read mode. If this flag is not set, the pipe handle is in byte-read mode.
lpdwCurInstances

Points to a 32-bit variable that will receive the number of current pipe instances. Set this parameter to NULL if the information is not required.

lpcbMaxCollect

Points to a 32-bit variable that will receive the maximum number of bytes to be collected on the client's computer before transmission to the server. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe, or if client and server processes are on the same computer. Set this parameter to NULL if the information is not required.

lpdwCollectTimeout

Points to a 32-bit variable that will receive the maximum time, in milliseconds, that can pass before a remote named pipe transfers information over the network. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe, or if client and server processes are on the same computer. Set this parameter to NULL if the information is not required.

lpszUser

Points to a buffer that will receive the null-terminated string containing the username string of the client application. This parameter must be NULL if the specified pipe handle is to the client end of a named pipe. Set this parameter to NULL if the information is not required.

cchMaxUser

Specifies the size, in characters, of the lpszUser buffer. This parameter is ignored if lpszUser is NULL.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetNamedPipeHandleState function returns successfully even if all of the pointers passed to it are NULL.

To set the pipe handle state, use the SetNamedPipeHandleState function.

See Also

»SetNamedPipeHandleState«


  GetNamedPipeInfo

BOOL GetNamedPipeInfo(hNamedPipe, lpdwType, lpcbOutBuf, lpcbInBuf, lpcMaxInstances)
HANDLE  hNamedPipe;   /* handle of named pipe */
LPDWORD  lpdwType;   /* address of flags indicating type of pipe */
LPDWORD  lpcbOutBuf;   /* address of size in bytes of pipe's output buffer */
LPDWORD  lpcbInBuf;   /* address of size in bytes of pipe's input buffer */
LPDWORD  lpcMaxInstances;   /* address of max number of pipe instances */

The GetNamedPipeInfo function retrieves information about the given named pipe.

Parameters

hNamedPipe

Identifies the named pipe instance. The handle must have GENERIC_READ access to the named pipe.

lpdwType

Points to a 32-bit variable that will receive flags indicating the type of the named pipe and whether the handle is to the server or client end of the pipe. Set this parameter to NULL if this information is not required. Either or both of the following flags can be set:

Value	Meaning
PIPE_SERVER_END
	The handle refers to the server end of a named pipe instance. If this flag is not set, the handle refers to the client end of a named pipe instance.
PIPE_TYPE_MESSAGE
	The named pipe is a message-type pipe. If this flag is not set, the pipe is a byte-type pipe.
lpcbOutBuf

Points to a 32-bit variable that will receive the size, in bytes, of the buffer for outgoing data. If the buffer size is zero, the buffer is allocated as needed. Set this parameter to NULL if this information is not required.

lpcbInBuf

Points to a 32-bit variable that will receive the size, in bytes, of the buffer for incoming data. If the buffer size is zero, the buffer is allocated as needed. Set this parameter to NULL if this information is not required.

lpcMaxInstances

Points to a 32-bit variable that will receive the maximum number of pipe instances that can be created. If the variable is set to PIPE_UNLIMITED_INSTANCES, the number of pipe instances that can be created is limited only by the availability of system resources. Set this parameter to NULL if this information is not required.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreateNamedPipe«, »GetNamedPipeHandleState«


  GetNearestColor

COLORREF GetNearestColor(hdc, crColor)
HDC  hdc;   /* handle of device context */
COLORREF  crColor;   /* color to be matched */

The GetNearestColor function returns a color value identifying a color from the system palette that will be displayed when the given color value is used.

Parameters

hdc

Identifies the device context.

crColor

Specifies a color value that identifies a requested color.

Return Value

If the function succeeds, the return value identifies a color from the system palette that corresponds to the given color value; otherwise, it is CLR_INVALID. To get extended error information, use the GetLastError function.

See Also

»GetDeviceCaps«, »GetNearestPaletteIndex«


  GetNearestPaletteIndex

UINT GetNearestPaletteIndex(hpal, crColor)
HPALETTE  hpal;   /* handle of logical color palette */
COLORREF  crColor;   /* color to be matched */

The GetNearestPaletteIndex function retrieves the index for the entry in the given logical palette most closely matching a given color value.

Parameters

hpal

Identifies a logical color palette.

crColor

Specifies a color to be matched.

Return Value

If the function succeeds, the return value is the index of an entry in a logical palette; otherwise, it is CLR_INVALID. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

If the given logical palette contains entries with the PC_EXPLICIT flag set, the return value is undefined.

See Also

»GetDeviceCaps«, »GetNearestColor«, »GetPaletteEntries«, »GetSystemPaletteEntries«


  GetNextDlgGroupItem

HWND GetNextDlgGroupItem(hwndDlg, hwndCtl, fPrevious)
HWND  hwndDlg;   /* handle of dialog box */
HWND  hwndCtl;   /* handle of control */
BOOL  fPrevious;   /* direction flag */

The GetNextDlgGroupItem function retrieves the handle of the first control in a group of controls that precedes (or follows) the given control in the given dialog box.

Parameters

hwndDlg

Identifies the dialog box being searched.

hwndCtl

Identifies the control to be used as the starting point for the search. If this parameter is NULL, the function uses the last (or first) control in the dialog box as the starting point for the search.

fPrevious

Specifies how the function is to search the group of controls in the dialog box. If this parameter is TRUE, the function searches for the previous control in the group. If it is FALSE, the function searches for the next control in the group.

Return Value

If this function succeeds, the return value is the handle of the previous (or next) control in the group of controls.

Comments

The GetNextDlgGroupItem function searches controls in the order (or reverse order) they were created in the dialog box template. The first control in the group must have the WS_GROUP style; all other controls in the group must have been consecutively created and must not have the WS_GROUP style.

When searching for the previous control, the function returns the first control it locates that is visible and not disabled. If the control given by hwndCtl has the WS_GROUP style, the function temporarily reverses the search to locate the first control having the WS_GROUP style, then resumes the search in the original direction, returning the first control it locates that is visible and not disabled, or returning hwndCtrl if no such control is found.

When searching for the next control, the function returns the first control it locates that is visible, not disabled, and does not have the WS_GROUP style. If it encounters a control having the WS_GROUP style, the function reverses the search, locates the first control having the WS_GROUP style, and returns this control if it is visible and not disabled. Otherwise, the function resumes the search in the original direction and returns the first control it locates that is visible and not disabled, or returns hwndCtl if no such control is found.

See Also

»GetNextDlgTabItem«


  GetNextDlgTabItem

HWND GetNextDlgTabItem(hwndDlg, hwndCtl, fPrevious)
HWND  hwndDlg;   /* handle of dialog box */
HWND  hwndCtl;   /* handle of known control */
BOOL  fPrevious;   /* direction flag */

The GetNextDlgTabItem function retrieves the handle of the first control that has the WS_TABSTOP style that precedes (or follows) the given control.

Parameters

hwndDlg

Identifies the dialog box to be searched.

hwndCtl

Identifies the control to be used as the starting point for the search. If this parameter is NULL, the function uses the last (or first) control in the dialog box as the starting point for the search.

fPrevious

Specifies how the function is to search the dialog box. If this parameter is TRUE, the function searches for the previous control in the dialog box. If this parameter is FALSE, the function searches for the next control in the dialog box.

Return Value

If the function succeeds, the return value is the window handle of the previous (or next) control that has the WS_TABSTOP style set.

Comments

The GetNextDlgTabItem function searches controls in the order (or reverse order) they were created in the dialog box template. The function returns the first control it locates that is visible, not disabled, and has the WS_TABSTOP style. If no such control exists, the function returns hwndCtl.

See Also

»GetDlgItem«, »GetNextDlgGroupItem«


  GetNextWindow

HWND GetNextWindow(hwnd, fuDirection)
HWND  hwnd;   /* handle of current window */
UINT  fuDirection;   /* direction flag */

The GetNextWindow function retrieves the handle of the next or previous window in the Z order. The next window is below the given window; the previous window is above. Windows maintains separate Z orders for topmost windows, top-level windows, and child windows. If the given window is a topmost window, the function retrieves the handle of the next (or previous) topmost window. If the given window is a top-level window, the function retrieves the handle of the next (or previous) top-level window. If the given window is a a child window, the function searches for a handle of the next (or previous) child window.

Parameters

hwnd

Identifies a window. The window handle retrieved is relative to this window, based on the value of the fuDirection parameter.

fuDirection

Specifies whether the function returns the handle of the next window or of the previous window. This parameter can be either of the following values:

Value	Meaning
GW_HWNDNEXT	Returns the handle of the window below the given window.
GW_HWNDPREV	Returns the handle of the window above the given window.
Return Value

If the function succeeds, the return value is the handle of the next (or previous) window. If there is no next (or previous) window, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

Using this function is the same as calling the GetWindow function with the GW_HWNDNEXT or GW_HWNDPREV flag set.

See Also

»GetTopWindow«, »GetWindow«


  GetNumberOfConsoleInputEvents

BOOL GetNumberOfConsoleInputEvents(hConsoleInput, lpcNumberOfEvents)
HANDLE  hConsoleInput;   /* handle of console input buffer */
LPDWORD  lpcNumberOfEvents;   /* address for number of events */

The GetNumberOfConsoleInputEvents function retrieves the number of unread input records in the console's input buffer.

Parameters

hConsoleInput

Identifies the console input buffer. The handle must have GENERIC_READ access.

lpcNumberOfEvents

Points to a 32-bit variable that receives the number of unread input records in the console's input buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetNumberOfConsoleInputEvents function reports the total number of unread input records in the input buffer, including keyboard, mouse, and window-resizing input records. Processes using the ReadFile or ReadConsole function can only read keyboard input. Processes using the ReadConsoleInput function can read all types of input records.

A process can specify a console input buffer handle in one of the wait functions (that is, the WaitForSingleObject or WaitForMultipleObjects function) to determine when there is unread console input. When the input buffer is not empty, the state of a console input buffer handle is signaled.

To read input records from a console input buffer without affecting the number of unread records, use the PeekConsoleInput function. To discard all unread records in a console's input buffer, use the FlushConsoleInputBuffer function.

See Also

»FlushConsoleInputBuffer«, »PeekConsoleInput«, »ReadConsole«, »ReadConsoleInput«, »ReadFile«, »WaitForMultipleObjects«, »WaitForSingleObject«


  GetNumberOfConsoleMouseButtons

BOOL GetNumberOfConsoleMouseButtons(lpcMouseButtons)
LPDWORD  lpcMouseButtons;   /* number of buttons */

The GetNumberOfConsoleMouseButtons function retrieves the number of buttons on the mouse used by the current console.

Parameters

lpcMouseButtons

Points to a 32-bit variable that receives the number of mouse buttons.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When a console receives mouse input, an INPUT_RECORD structure containing a MOUSE_EVENT_RECORD structure is placed in the console's input buffer. The dwButtonState member of MOUSE_EVENT_RECORD has a bit indicating the state of each mouse button. The bit is 1 if the button is down and 0 if the button is up. To determine the number of bits that are significant, use GetNumberOfConsoleMouseButtons.

See Also

»ReadConsoleInput«, »INPUT_RECORD«, »MOUSE_EVENT_RECORD«


  GetNumberOfEventLogRecords

BOOL GetNumberOfEventLogRecords(hEventLog, pcRecords)
HANDLE  hEventLog;   /* handle to event log */
PDWORD  pcRecords;   /* buffer for number of records */

The GetNumberOfEventLogRecords function retrieves the number of records in the given event log.

Parameters

hEventLog

Identifies the open event log. This handle is returned by the OpenEventLog or OpenBackupEventLog function.

pcRecords

Points to a variable that receives the number of records in the given event log.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetOldestEventLogRecord«


  GetObject

int GetObject(hgdiobj, cbBuffer, lpvObject)
HGDIOBJ  hgdiobj;   /* handle of object */
int  cbBuffer;   /* size of buffer for object information */
LPVOID  lpvObject;   /* address of buffer for object information */

The GetObject function fills a buffer with information defining a given object. The function retrieves a BITMAP, EXTLOGPEN, LOGPEN, LOGBRUSH, or LOGFONT structure, or an integer, depending on the given object.

Parameters

hgdiobj

Identifies a logical bitmap, brush, font, palette, or pen .

cbBuffer

Specifies the number of bytes to be copied to the buffer.

lpvObject

Points to the buffer that is to receive the information. If the parameter is NULL, the return value contains the number of bytes needed for the logical object.

Return Value

If lpvObject is a valid pointer and the function succeeds, the return value is the number of bytes returned; if lpvObject is NULL and the function succeeds, the return value is the number of bytes required to hold the object. Otherwise, the return value is zero.

Comments

The buffer pointed to by the lpvObject parameter must be sufficiently large to receive the information.

If the hgdiobj parameter identifies a bitmap, the GetObject function returns only the width, height, and color format information of the bitmap. The bits can be retrieved by using the GetBitmapBits function.

If hgdiobj identifies a logical palette, GetObject retrieves a 2-byte integer specifying the number of entries in the palette; the function does not retrieve the LOGPALETTE structure defining the palette. To retrieve information about palette entries, an application can call the GetPaletteEntries function.

See Also

»GetDIBits«, »GetPaletteEntries«


  GetObjectType

DWORD GetObjectType(hgdiobj)
HGDIOBJ  hgdiobj;   /* handle of graphic object */

The GetObjectType identifies the type of the given object.

Parameters

hgdiobj

Identifies the object.

Return Value

If the function succeeds, the return value identifies the object. This value can be one of the following:

Value	Meaning
OBJ_BITMAP	Bitmap
OBJ_BRUSH	Brush
OBJ_FONT	Font
OBJ_PAL	Palette
OBJ_PEN	Pen
OBJ_EXTPEN	Extended pen
OBJ_REGION	Region
OBJ_DC	Device context
OBJ_MEMDC	Memory device context
OBJ_METAFILE	Metafile
OBJ_METADC	Metafile device context
OBJ_ENHMETAFILE	Enhanced metafile
OBJ_ENHMETADC	Enhanced metafile device context
If the function fails, the return value is zero.

See Also

»GetObject«, »SelectObject«


  GetOEMCP

UINT GetOEMCP(VOID)

The GetOEMCP function retrieves the OEM code-page identifier for the system. (OEM stands for original equipment manufacturer.)

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the OEM code-page identifier, or it is the default identifier if the registry value is not readable.

Comments

Following are the OEM code-page identifiers:

Identifier	Meaning
437	MS-DOS United States
850	MS-DOS Multilingual (Latin I)
852	MS-DOS Slavic (Latin II)
855	IBM Cyrillic (primarily Russian)
857	IBM Turkish
860	MS-DOS Portuguese
861	MS-DOS Icelandic
863	MS-DOS Canadian-French
865	MS-DOS Nordic
866	MS-DOS Russian (former USSR)
869	IBM Modern Greek
See Also

»GetACP«


  GetOldestEventLogRecord

BOOL GetOldestEventLogRecord(hEventLog, pdwOldestRecord)
HANDLE  hEventLog;   /* handle to event log */
PDWORD  pdwOldestRecord;   /* buffer for number of oldest record */

The GetOldestEventLogRecord function retrieves the absolute record number of the oldest record in the given event log.

Parameters

hEventLog

Identifies the open event log. This handle is returned by the OpenEventLog or OpenBackupEventLog function.

pdwOldestRecord

Points to the variable that receives the absolute record number of the oldest record in the given event log.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetNumberOfEventLogRecords«


  GetOpenClipboardWindow

HWND GetOpenClipboardWindow(VOID)

The GetOpenClipboardWindow function retrieves the handle of the window that currently has the clipboard open.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the handle of the window that has the clipboard open. If no window has the clipboard open, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

If an application or dynamic-link library (DLL) specifies a NULL window handle when calling the OpenClipboard function, the clipboard is opened but is not associated with a window. In such a case, the GetOpenClipboardWindow function returns NULL.

See Also

»GetClipboardOwner«, »GetClipboardViewer«, »OpenClipboard«


  GetOpenFileName

BOOL GetOpenFileName(lpofn)
LPOPENFILENAME  lpofn;   /* address of structure with initialization data */

The GetOpenFileName function creates a system-defined dialog box that enables the user to select a file to open.

Parameters

lpofn

Points to an OPENFILENAME structure that contains information used to initialize the dialog box. When GetOpenFileName returns, this structure contains information about the user's file selection. The OPENFILENAME structure has the following form:

typedef struct tagOFN { /* ofn */

    DWORD     lStructSize;

    HWND      hwndOwner;

    HINSTANCE hInstance;

    LPCSTR    lpstrFilter;

    LPSTR     lpstrCustomFilter;

    DWORD     nMaxCustFilter;

    DWORD     nFilterIndex;

    LPSTR     lpstrFile;

    DWORD     nMaxFile;

    LPSTR     lpstrFileTitle;

    DWORD     nMaxFileTitle;

    LPSTR     lpstrInitialDir;

    LPCSTR    lpstrTitle;

    DWORD     Flags;

    WORD      nFileOffset;

    WORD      nFileExtension;

    LPCSTR    lpstrDefExt;

    DWORD     lCustData;

    LPOFNHOOKPROC lpfnHook;

    LPCSTR    lpTemplateName;

} OPENFILENAME;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the user selects a file to open, the return value is TRUE. It is FALSE if an error occurs, the user chooses the Cancel button, the user chooses the Close command on the System menu to close the dialog box, or the buffer identified by the lpstrFile member of the OPENFILENAME structure is too small to contain the string that specifies the selected file.

Use the CommDlgExtendedError function to retrieve extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE
CDERR_INITIALIZATION
CDERR_LOCKRESFAILURE
CDERR_LOADRESFAILURE
CDERR_LOADSTRFAILURE
CDERR_MEMALLOCFAILURE
CDERR_MEMLOCKFAILURE
CDERR_NOHINSTANCE
CDERR_NOHOOK
CDERR_NOTEMPLATE
CDERR_STRUCTSIZE
FNERR_BUFFERTOOSMALL
FNERR_INVALIDFILENAME
FNERR_SUBCLASSFAILURE

Comments

If the hook function (pointed to by the lpfnHook member of the OPENFILENAME structure) processes the WM_CTLCOLORBTN, WM_CTLCOLORDLG, WM_CTLCOLORLISTBOX, WM_CTLCOLORMSGBOX, WM_CTLCOLORSCROLLBAR, or WM_CTLCOLORSTATIC message, this function must return a handle of the brush that should be used to paint the control background.

Ending the dialog from within the hook function by calling the EndDialog function prevents the comdlg32 DLL from properly exiting its worker thread. For applications that dynamically load and/or unload the comdlg32 dll, this may result in an access violation during unload as the worker thread's address space is invalidated.

See Also

»CommDlgExtendedError«, »GetSaveFileName«


  GetOutlineTextMetrics

UINT GetOutlineTextMetrics(hdc, cbData, lpOTM)
HDC  hdc;   /* handle of device context */
UINT  cbData;   /* size of metric data array */
LPOUTLINETEXTMETRIC  lpOTM;   /* address of metric data array */

The GetOutlineTextMetrics function retrieves text metrics for TrueType® fonts.

Parameters

hdc

Identifies the device context.

cbData

Specifies the size, in bytes, of the array in which the text metrics are to be returned.

lpOTM

Points to an array of OUTLINETEXTMETRIC structures. If this parameter is NULL, the function returns the size of the buffer required for the retrieved metric data. The OUTLINETEXTMETRIC structure has the following form:

typedef struct _OUTLINETEXTMETRIC { /* otm */

    UINT   otmSize;

    TEXTMETRIC otmTextMetrics;

    BYTE   otmFiller;

    PANOSE otmPanoseNumber;

    UINT   otmfsSelection;

    UINT   otmfsType;

    int    otmsCharSlopeRise;

    int    otmsCharSlopeRun;

    int    otmItalicAngle;

    UINT   otmEMSquare;

    int    otmAscent;

    int    otmDescent;

    UINT   otmLineGap;

    UINT   otmsCapEmHeight;

    UINT   otmsXHeight;

    RECT   otmrcFontBox;

    int    otmMacAscent;

    int    otmMacDescent;

    UINT   otmMacLineGap;

    UINT   otmusMinimumPPEM;

    POINT  otmptSubscriptSize;

    POINT  otmptSubscriptOffset;

    POINT  otmptSuperscriptSize;

    POINT  otmptSuperscriptOffset;

    UINT   otmsStrikeoutSize;

    int    otmsStrikeoutPosition;

    int    otmsUnderscoreSize;

    int    otmsUnderscorePosition;

    PSTR   otmpFamilyName;

    PSTR   otmpFaceName;

    PSTR   otmpStyleName;

    PSTR   otmpFullName;

} OUTLINETEXTMETRIC;

For more information about this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE or the size of the required buffer; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The OUTLINETEXTMETRIC structure contains most of the text metric information provided for TrueType fonts (including a TEXTMETRIC structure). The sizes returned in the OUTLINETEXTMETRIC structures are in logical units; they depend on the current mapping mode.

See Also

»GetTextMetrics«, »OUTLINETEXTMETRIC«, »TEXTMETRIC«


  GetOverlappedResult

BOOL GetOverlappedResult(hFile, lpoOverlapped, lpcbTransfer, fWait)
HANDLE  hFile;   /* handle of file, pipe, or comm. device */
LPOVERLAPPED  lpoOverlapped;   /* address of overlapped structure */
LPDWORD  lpcbTransfer;   /* address of actual bytes count */
BOOL  fWait;   /* wait flag */

The GetOverlappedResult function returns the results of an overlapped operation on the specified file, named pipe, or communications device.

Parameters

hFile

Identifies the file, named pipe, or communications device. This is the same handle that was specified when the overlapped operation was started by a call to the ReadFile, WriteFile, ConnectNamedPipe, TransactNamedPipe, DeviceIoControl, or WaitCommEvent function.

lpoOverlapped

Points to an OVERLAPPED structure that was specified when the overlapped operation was started. The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcbTransfer

Points to a 32-bit variable that receives the number of bytes that were actually transferred by a read or write operation. For a TransactNamedPipe operation, this is the number of bytes that were read from the pipe. For a DeviceIoControl operation, this is the number of bytes of output data returned by the device driver. For a ConnectNamedPipe or WaitCommEvent operation, this value is undefined.

fWait

Specifies whether the function should wait for the pending overlapped operation to be completed. If TRUE, the function does not return until the operation has been completed. If FALSE and the operation is still pending, the function returns FALSE and the GetLastError function returns ERROR_IO_INCOMPLETE.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The results reported by the GetOverlappedResult function are those of the specified handle's last overlapped operation to which the specified OVERLAPPED structure was provided, and for which the operation's results were pending. A pending operation is indicated when the function that started the operation returns FALSE and the GetLastError function returns ERROR_IO_PENDING. When an input and output (I/O) operation is pending, the function that started the operation resets the hEvent member of the OVERLAPPED structure to the nonsignaled state. Then when the pending operation has been completed, the system sets the event object to the signaled state.

If the fWait parameter is TRUE, GetOverlappedResult determines whether the pending operation has been completed by waiting for the event object to be in the signaled state.

If the hEvent member of the OVERLAPPED structure is NULL, the system uses the state of the hFile handle to signal when the operation has been completed. Use of file, named pipe, or communications-device handles for this purpose is discouraged. It is safer to use an event object because of the confusion that can occur when multiple simultaneous overlapped operations are performed on the same file, named pipe, or communications device. In this situation, there is no way to know which operation caused the object's state to be signaled.

Specify a manual-reset event object in the OVERLAPPED structure. If an auto-reset event object is used, the event handle must not be specified in any other wait operation in the interval between starting the overlapped operation and the call to GetOverlappedResult. For example, the event object is sometimes specified in one of the wait functions to wait for the operation's completion. When the wait function returns, the system sets an auto-reset event's state to nonsignaled, and a subsequent call to GetOverlappedResult with the fWait parameter set to TRUE causes the function to be blocked indefinitely.

See Also

»ConnectNamedPipe«, »CreateEvent«, »DeviceIoControl«, »GetLastError«, »ReadFile«, »TransactNamedPipe«, »WaitCommEvent«, »WriteFile«


  GetPaletteEntries

UINT GetPaletteEntries(hpal, iStartIndex, nEntries, lppe)
HPALETTE  hpal;   /* handle of logical color palette */
UINT  iStartIndex;   /* first entry to retrieve */
UINT  nEntries;   /* number of entries to retrieve */
LPPALETTEENTRY  lppe;   /* address of array receiving entries */

The GetPaletteEntries function retrieves a specified range of palette entries from the given logical palette.

Parameters

hpal

Identifies the logical color palette.

iStartIndex

Specifies the first entry in the logical palette to be retrieved.

nEntries

Specifies the number of entries in the logical palette to be retrieved.

lppe

Points to an array of PALETTEENTRY structures to receive the palette entries. The array must contain at least as many structures as specified by the nEntries parameter. The PALETTEENTRY structure has the following form:

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds and the handle of the logical color palette is a valid pointer (not NULL), the return value is the number of entries retrieved from the logical palette. If the function succeeds and handle of the logical color palette is NULL, the return value is the number of entries in the given palette. Otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

If the nEntries parameter specifies more entries than exist in the palette, the remaining members of the PALETTEENTRY structure are not altered.

See Also

»GetDeviceCaps«, »GetSystemPaletteEntries«


  GetParent

HWND GetParent(hwndChild)
HWND  hwndChild;   /* handle of child window */

The GetParent function retrieves the handle of the given child window's parent window.

Parameters

hwndChild

Identifies the window whose parent window handle is to be retrieved.

Return Value

If the function succeeds, the return value is the handle of the parent window. If the window has no parent window, the return value is NULL. To get extended error information, use the GetLastError function.

See Also

»SetParent«


  GetPath

int GetPath(hdc, lpPoints, lpTypes, nSize)
HDC  hdc;   /* handle of device context */
LPPOINT  lpPoints;   /* address of array receiving path vertices */
LPBYTE  lpTypes;   /* address of array of path vertex types */
int  nSize;   /* count of points defining path */

The GetPath function retrieves the coordinates defining the endpoints of lines and the control points of curves found in the path that is selected into the specified device context.

Parameters

hdc

Identifies a device context that contains a closed path.

lpPoints

Points to an array of POINT structures where the line endpoints and curve control points are placed.

lpTypes

Points to an array of bytes where the vertex types are placed. Values are one of the following:

Type	Description
PT_MOVETO	Specifies that the corresponding point in lpPoints starts a disjoint figure.
PT_LINETO	Specifies that the previous point and the corresponding point in lpPoints are the endpoints of a line.
PT_BEZIERTO	Specifies that the corresponding point in lpPoints is a control point or ending point for a Bézier curve.
	PT_BEZIERTO types always occur in sets of three. The point in the path immediately preceding them defines the starting point for the Bézier curve. The first two PT_BEZIERTO points are the control points, and the third PT_BEZIERTO point is the ending (if hard-coded) point.
A PT_LINETO or PT_BEZIERTO type may be combined with the following flag (by using the bitwise operator OR) to indicate that the corresponding point is the last point in a figure and the figure should be closed:

Flag	Description
PT_CLOSEFIGURE	Specifies that the figure is automatically closed after the corresponding line or curve is drawn. The figure is closed by drawing a line from the line or curve endpoint to the point corresponding to the last PT_MOVETO.
nSize

Specifies the total number of POINT structures that may be placed in the lpPoints array. This value must be the same as the number of bytes that may be placed in the lpTypes array.

Return Value

If the nSize parameter is nonzero, the return value is the number of points enumerated. If nSize is 0, the return value is the total number of points in the path (and GetPath writes nothing to the buffers). If nSize is nonzero and is less than the number of points in the path, the return value is −1. Use the GetLastError function to get the error value, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_BUFFER_OVERFLOW

Comments

The device context identified by the hdc parameter must contain a closed path.

The points of the path are returned in logical coordinates. Points are stored in the path in device coordinates, so GetPath changes the points from device coordinates to logical coordinates by using the inverse of the current transformation.

The FlattenPath function may be called before GetPath to convert all curves in the path into line segments.

See Also

»FlattenPath«, »PolyDraw«, »WidenPath«


  GetPixel

COLORREF GetPixel(hdc, nXPos, nYPos)
HDC  hdc;   /* handle of device context */
int  nXPos;   /* x-coordinate of pixel */
int  nYPos;   /* y-coordinate of pixel */

The GetPixel function retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates.

Parameters

hdc

Identifies the device context.

nXPos

Specifies the logical x-coordinate of the pixel to be examined.

nYPos

Specifies the logical y-coordinate of the pixel to be examined.

Return Value

If the function succeeds, the return value is an RGB value. If the pixel is outside of the current clipping region, the return value is CLR_INVALID.

Comments

The pixel must be within the boundaries of the current clipping region.

Not all devices support GetPixel. An application should call GetDeviceCaps to determine whether a given device supports this function.

See Also

»GetDeviceCaps«


  GetPolyFillMode

int GetPolyFillMode(hdc)
HDC  hdc;   /* handle of device context */

The GetPolyFillMode function retrieves the current polygon fill mode.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value specifies the polygon fill mode, which can be either of the following values:

Value	Meaning
ALTERNATE	Selects alternate mode (fills area between odd-numbered and even-numbered polygon sides on each scan line).
WINDING	Selects winding mode (fills any region with a nonzero winding value).
If an error occurs, the return value is zero.

For more information about these modes, see the »SetPolyFillMode« function.

See Also

»SetPolyFillMode«


  GetPrinter

BOOL GetPrinter(hPrinter, dwLevel, lpbPrinter, cbBuf, lpdwNeeded)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbPrinter;   /* address of structure array */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwNeeded;   /* addr. of variable with count of bytes retrieved (or required) */

The GetPrinter function retrieves data for the given printer.

Parameters

hPrinter

Identifies the printer for which data should be retrieved.

dwLevel

Specifies the version of the structure to which lpbPrinter points. This value must be 1 or 2.

lpbPrinter

Points to an array of bytes that receives a PRINTER_INFO_1 or PRINTER_INFO_2 structure.

The PRINTER_INFO_1 structure has the following form:

typedef struct _PRINTER_INFO_1 { /* pri1 */

    DWORD  Flags;

    LPTSTR pDescription;

    LPTSTR pName;

    LPTSTR pComment;

} PRINTER_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The PRINTER_INFO_2 structure has the following form:

typedef struct _PRINTER_INFO_2 { /* pri2 */

    LPTSTR    pServerName;

    LPTSTR    pPrinterName;

    LPTSTR    pShareName;

    LPTSTR    pPortName;

    LPTSTR    pDriverName;

    LPTSTR    pComment;

    LPTSTR    pLocation;

    LPDEVMODE pDevMode;

    LPTSTR    pSepFile;

    LPTSTR    pPrintProcessor;

    LPTSTR    pDatatype;

    LPTSTR    pParameters;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD     Attributes;

    DWORD     Priority;

    DWORD     DefaultPriority;

    DWORD     StartTime;

    DWORD     UntilTime;

    DWORD     Status;

    DWORD     cJobs;

    DWORD     AveragePPM;

} PRINTER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the array to which lpbPrinter points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf was too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AbortPrinter«, »AddPrinter«, »ClosePrinter«, »DeletePrinter«, »EnumPrinters«, »OpenPrinter«, »SetPrinter«


  GetPrinterData

DWORD GetPrinterData(hPrinter, lpszType, lpdwType, lpbData, nSize, lpdwNeeded)
HANDLE  hPrinter;   /* handle of printer object */
LPTSTR  pValueName;   /* address of data type */
LPDWORD  pType;   /* reserved */
LPBYTE  pData;   /* address of array of bytes that receives data */
DWORD  nSize;   /* size,in bytes, of array */
LPDWORD  pcbNeeded;   /* addr. of variable with count of bytes retrieved (or required) */

The GetPrinterData function retrieves printer-configuration data for the given printer.

Parameters

hPrinter

Identifies the printer for which configuration data should be retrieved.

pValueName

Points to a null-terminated string that specifies the type of data that the function should retrieve.

pType

Points to a variable that receives the data type stored by SetPrinterData. The GetPrinterData function passes pType on as the lpdwType parameter of a RegQueryValueEx  function call. This parameter may be NULL.

pData

Points to an array of bytes that receives the configuration data.

nSize

Specifies the size, in bytes, of the buffer to which pData points.

pcbNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if nSize is too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter is obtained by calling the OpenPrinter function.

The function retrieves printer-configuration data set by the SetPrinter function.

See Also

»OpenPrinter«, »SetPrinter«


  GetPrinterDriver

BOOL GetPrinterDriver(hPrinter, lpszEnv, dwLevel, lpbDrvInfo, cbBuf, lpdwNeeded)
HANDLE  hPrinter;   /* printer object */
LPTSTR  lpszEnv;   /* address of environment */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbDrvInfo;   /* address of structure array */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwNeeded;   /* addr. of variable with count of bytes retrieved (or required) */

The GetPrinterDriver function retrieves driver data for the given printer.

Parameters

hPrinter

Identifies the printer for which the driver data should be retrieved.

lpszEnv

Points to a null-terminated string that specifies the environment. For example, "Windows NT x86" specifies Windows NT running on an Intel® 80386 or 80486 processor. If this string is NULL, the current environment of the caller/client (not of the destination/server) is used.

dwLevel

Specifies the version of the structure to which lpbForm points. This value must be either 1 or 2.

lpbDrvInfo

Points to either a DRIVER_INFO_1 or a DRIVER_INFO_2 structure. If dwLevel is 1, this array receives a DRIVER_INFO_1 structure; if dwLevel is 2, this array receives a DRIVER_INFO_2 structure.

The DRIVER_INFO_1 structure has the following form:

typedef struct _DRIVER_INFO_1 { /* dri1 */

    LPTSTR pName;

} DRIVER_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The DRIVER_INFO_2 structure has the following form:

typedef struct _DRIVER_INFO_2 { /* dri2 */

    DWORD  cVersion;

    LPTSTR pName;

    LPTSTR pEnvironment;

    LPTSTR pDriverPath;

    LPTSTR pDataFile;

    LPTSTR pConfigFile;

} DRIVER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuf

Specifies the size, in bytes, of the array at which lpbDrvInfo points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds or the number of bytes required if cbBuf is too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter should be retrieved by calling the OpenPrinter function.

The DRIVER_INFO_2 structure contains a full path and filename specifying the location of the printer driver. An application can use the path and filename to load a printer driver by calling the LoadLibrary function and supplying the path and filename as the single argument.

See Also

»AddPrinterDriver«, »EnumPrinterDrivers«, »LoadLibrary«, »OpenPrinter«


  GetPrinterDriverDirectory

BOOL GetPrinterDriverDirectory(lpszName, lpszEnv, dwLevel, lpbDir, cbBuf, lpdwNeeded)
LPTSTR  lpszName;   /* address of server name */
LPTSTR  lpszEnv;   /* address of environment */
DWORD  dwLevel;   /* address of structure */
LPBYTE  lpbDir;   /* address of structure array that receives path */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwNeeded;   /* addr. of variable with count of bytes retrieved (or required) */

The GetPrinterDriverDirectory function retrieves the path of the printer-driver directory.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server on which the printer driver resides. If this string is NULL, the local driver-directory path is retrieved.

lpszEnv

Points to a null-terminated string that specifies the environment. For example, "Windows NT x86" specifies Windows NT running on an Intel® 80386 or 80486 processor. If this string is NULL, the current environment of the caller/client (not of the destination/server) is used.

dwLevel

Specifies the structure level. This value must be 1.

lpbDir

Points to an array of bytes that receives the path.

cbBuf

Specifies the size of the array to which lpbDir points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds, or the number of bytes required if cbBuf is too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrinterDriver«


  GetPrintProcessorDirectory

BOOL GetPrintProcessorDirectory(lpszName, lpszEnv, dwLevel, lpbProcessorDir,
cbBuf, lpdwNeeded)
LPTSTR  lpszName;   /* address of server name */
LPTSTR  lpszEnv;   /* address of environment */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbProcessorDir;   /* address of structure array */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwNeeded;   /* addr. of variable with count of bytes retrieved (or required) */

The GetPrintProcessorDirectory function retrieves the path for the print processor on the specified server.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the server. If this string is NULL, a local path is returned.

lpszEnv

Points to a null-terminated string that specifies the environment. For example, "Windows NT x86" specifies Windows NT running on an Intel® 80386 or 80486 processor. If this string is NULL, the current environment of the caller/client (not of the destination/server) is used.

dwLevel

Specifies the structure level. This value must be 1.

lpbProcessorDir

Points to an array of bytes into which the path is copied.

cbBuf

Specifies the size of the buffer to which lpbProcessorDir points.

lpdwNeeded

Points to a value that specifies the number of bytes copied if the function succeeds, or the number of bytes required if cbBuf is too small.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AddPrintProcessor«


  GetPriorityClass

DWORD GetPriorityClass(hProcess)
HANDLE  hProcess;   /* handle to the process */

The GetPriorityClass function returns the priority class for the given process. This value together with the priority value of each thread of the process determines each thread's base priority level.

Parameters

hProcess

Identifies the process. The handle must have PROCESS_QUERY_INFORMATION access.

Return Value

If the function succeeds, the return value is the priority class of the specified process; otherwise, it is zero. To get extended error information, use the GetLastError function.

The process's priority class is one of the following values:

Priority	Meaning
IDLE_PRIORITY_CLASS	Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS	Indicates a normal process with no special scheduling needs.
HIGH_PRIORITY_CLASS	Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
REALTIME_PRIORITY_CLASS	Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.
Comments

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The operating system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level will scheduling of threads at a lower level take place.

For a table that shows the base priority levels for each combination of priority class and thread priority value, see the »SetPriorityClass« function.

See Also

»SetPriorityClass«, »GetThreadPriority«, »SetThreadPriority«


  GetPriorityClipboardFormat

int GetPriorityClipboardFormat(puPriorityList, cList)
UINT  *puPriorityList;   /* address of priority list */
int  cList;   /* number of entries in list */

The GetPriorityClipboardFormat function returns the first available clipboard format in the specified list.

Parameters

puPriorityList

Points to an array of unsigned integers identifying clipboard formats, in priority order. For a description of the clipboard formats, see the »SetClipboardData« function.

cList

Specifies the number of entries in the puPriorityList array. This value must not be greater than the number of entries in the list.

Return Value

If the function succeeds, the return value is the first clipboard format in the list for which data is available. If the clipboard is empty, the return value is NULL. If the clipboard contains data, but not in any of the formats in the list, the return value is −1. To get extended error information, use the GetLastError function.

See Also

»CountClipboardFormats«, »EnumClipboardFormats«, »GetClipboardFormatName«, »IsClipboardFormatAvailable«, »RegisterClipboardFormat«, »SetClipboardData«


  GetPrivateObjectSecurity

BOOL GetPrivateObjectSecurity(ObjectDescriptor, SecurityInformation,
ResultantDescriptor, DescriptorLength, ReturnLength)
PSECURITY_DESCRIPTOR  ObjectDescriptor;   /* address of SD to query */
SECURITY_INFORMATION  SecurityInformation;   /* requested information */
PSECURITY_DESCRIPTOR  ResultantDescriptor;   /* address of retrieved SD */
DWORD  DescriptorLength;   /* size of buffer for retrieved SD */
PDWORD  ReturnLength;   /* address of buffer size required for SD */

The GetPrivateObjectSecurity retrieves information from a protected server object's security descriptor.

Parameters

ObjectDescriptor

Points to a SECURITY_DESCRIPTOR structure. This is the security descriptor to be queried.

SecurityInformation

Specifies a SECURITY_INFORMATION structure that identifies the security information being requested.

ResultantDescriptor

Points to a buffer receiving a copy of the requested information from the specified security descriptor. The SECURITY_DESCRIPTOR structure is returned in self-relative format.

DescriptorLength

Specifies the size, in bytes, of the buffer pointed to by the ResultantDescriptor parameter.

ReturnLength

Points to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of the DescriptorLength parameter when the function returns, the function returns FALSE and none of the security descriptor is copied to the buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application must perform appropriate access/privilege checks and audits before calling this function.

See Also

»CreatePrivateObjectSecurity«, »DestroyPrivateObjectSecurity«, »GetFileSecurity«, »GetKernelObjectSecurity«, »GetUserObjectSecurity«, »SetPrivateObjectSecurity«


  GetPrivateProfileInt

UINT GetPrivateProfileInt(lpszSection, lpszKey, dwDefault, lpszFile)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKey;   /* address of key name */
INT  dwDefault;   /* return value if key name is not found */
LPCTSTR  lpszFile;   /* address of initialization filename */

The GetPrivateProfileInt function retrieves an integer associated with a key in the specified section of the given initialization file. This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string containing the section name in the initialization file.

lpszKey

Points to the null-terminated string containing the key name whose value is to be retrieved. This value is in the form of a string; the GetPrivateProfileInt function converts the string into an integer and returns the integer.

dwDefault

Specifies the default value to return if the key name cannot be found in the initialization file.

lpszFile

Points to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, Windows searches for the file in the Windows directory.

Return Value

If the function succeeds, the return value is the integer equivalent of the string following the specified key name in the specified initialization file. If the key is not found, the return value is the specified default value. If the value of the key is less than zero, the return value is zero.

Comments

The function searches the file for a key that matches the name specified by the lpszKey parameter under the section name specified by the lpszSection parameter. A section in the initialization file must have the following form:

[section]
key=value
      .
      .
      .

The GetPrivateProfileInt function is not case-sensitive; the strings in lpszSection and lpszKey can be a combination of uppercase and lowercase letters.

An application can use the GetProfileInt function to retrieve an integer value from the WIN.INI file.

Calls to private profile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileInt function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetProfileInt«, »WritePrivateProfileString«


  GetPrivateProfileSection

DWORD GetPrivateProfileSection(lpszSection, lpszReturnBuffer, cchBuffer, lpszFile)
LPCTSTR  lpszSection;   /* address of section name */
LPTSTR  lpszReturnBuffer;   /* address of return buffer */
DWORD  cchBuffer;   /* size of return buffer */
LPCTSTR  lpszFile;   /* address of initialization filename */

The GetPrivateProfileSection function retrieves all of the keys and values for the specified section from the given initialization file. This function is provided for compatibility with 16-bit applications written for Windows. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string containing the section name in the initialization file.

lpszReturnBuffer

Points to a buffer that receives the key name and value pairs associated with the named section. The buffer is filled with one or more null-terminated strings; the last string is followed by a second null character.

cchBuffer

Specifies the size, in characters, of the buffer pointed to by the lpszReturnBuffer parameter.

lpszFile

Points to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, Windows searches for the file in the Windows directory.

Return Value

The return value specifies the number of characters copied to the buffer, not including the terminating null character. If the buffer is not large enough to contain all the key name and value pairs associated with the named section, the return value is equal to cchBuffer minus two.

Comments

The data in the buffer pointed to by the lpszReturnBuffer parameter consists of one or more null-terminated strings, followed by a final null character. Each string has the following format:

key=string

The GetPrivateProfileSection function is not case-sensitive; the string pointed to by the lpszSection parameter can be a combination of uppercase and lowercase letters.

This operation is atomic; no updates to the specified initialization file are allowed while the key name and value pairs for the section are being copied to the buffer pointed to by the lpszReturnBuffer parameter.

Calls to private profile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileSection function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetProfileSection«, »WritePrivateProfileSection«,


  GetPrivateProfileString

DWORD GetPrivateProfileString(lpszSection, lpszKey, lpszDefault, lpszReturnBuffer,
cchReturnBuffer, lpszFile)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKey;   /* address of key name */
LPCTSTR  lpszDefault;   /* address of default string */
LPTSTR  lpszReturnBuffer;   /* address of destination buffer */
DWORD  cchReturnBuffer;   /* size of destination buffer */
LPCTSTR  lpszFile;   /* address of initialization filename */

The GetPrivateProfileString function retrieves a string from the specified section in the given initialization file. This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string that specifies the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function copies all section names in the file to the supplied buffer.

lpszKey

Points to the null-terminated string containing the key name whose associated string is to be retrieved. If this parameter is NULL, all key names in the section specified by the lpszSection parameter are copied to the buffer specified by the lpszReturnBuffer parameter.

lpszDefault

Points to a null-terminated string that specifies the default value for the given key if the key cannot be found in the initialization file. This parameter cannot be NULL.

lpszReturnBuffer

Points to the buffer that receives the retrieved string.

cchReturnBuffer

Specifies the size, in characters, of the buffer pointed to by the lpszReturnBuffer parameter.

lpszFile

Points to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, Windows searches for the file in the Windows directory.

Return Value

If the function succeeds, the return value is the number of characters copied to the buffer, not including the terminating null character.

If neither lpszSection nor lpszKey is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to cchReturnBuffer minus one.

If either lpszSection or lpszKey is NULL and the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters. In this case, the return value is equal to cchReturnBuffer minus two.

Comments

The GetPrivateProfileString function searches the specified initialization file for a key that matches the name specified by the lpszKey parameter under the section heading specified by the lpszSection parameter. If it finds the key, the function copies the corresponding string to the buffer. If the key does not exist, the function copies the default character string specified by the lpszDefault parameter. A section in the initialization file must have the following form:

[section]
key=string
      .
      .
      .

If lpszSection is NULL, GetPrivateProfileString copies all section names in the specified file to the supplied buffer. If lpszKey is NULL, the function copies all key names in the specified section to the supplied buffer. An application can use this method to enumerate all of the sections and keys in a file. In either case, each string is followed by a null character and the final string is followed by a second null character. If the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters.

If the string associated with lpszKey is enclosed in single or double quotation marks, the marks are discarded when the GetPrivateProfileString function retrieves the string.

The GetPrivateProfileString function is not case-sensitive; the strings can be a combination of uppercase and lowercase letters.

To retrieve a string from the WIN.INI file, use the GetProfileString function.

Calls to private profile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileString function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetProfileString«, »WritePrivateProfileString«


  GetProcAddress

FARPROC GetProcAddress(hModule, lpszProc)
HMODULE  hModule;   /* handle to DLL module */
LPCSTR  lpszProc;   /* name of function */

The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.

Parameters

hModule

Identifies the DLL module that contains the function. The LoadLibrary or GetModuleHandle function return this handle.

lpszProc

Points to a null-terminated string containing the function name or specifies the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.

Return Value

If the function succeeds, the return value is the address of the function's entrypoint; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

Use the GetProcAddress function to retrieve addresses of exported functions in DLLs.

The spelling and case of the function name pointed to by lpszProc must be identical to that in the EXPORTS statement of the source DLL's module-definition file.

The lpszProc parameter can identify the DLL function by specifying an ordinal value associated with the function in the EXPORTS statement. GetProcAddress verifies that the specified ordinal is in the range 1 through the highest ordinal value exported in the module-definition file. The function then uses the ordinal as an index to read the function's address from a function table. If the module-definition file does not number the functions consecutively from 1 to N (where N is the number of exported functions), an error can occur where GetProcAddress returns an invalid, non-NULL address, even though there is no function with the specified ordinal.

In cases where the function may not exist, specify the function by name rather than by ordinal value.

See Also

»LoadLibrary«, »FreeLibrary«, »GetModuleHandle«


  GetProcessHeap

HANDLE GetProcessHeap (VOID)

The GetProcessHeap function obtains a handle to the calling process' heap. This handle can then be used in calls to the HeapAlloc, HeapReAlloc, HeapFree, and HeapSize functions.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is a handle to the calling process' heap.

If the function fails, the return value is NULL.

Comments

The GetProcessHeap function allows Win32 programs to allocate memory from the process heap without having to first create a heap with the HeapCreate function. Here is an example of such a call:

HeapAlloc( GetProcessHeap(), 0, dwBytes );

Note that the handle obtained by calling this function should not be used in calls to the HeapDestroy function.

Also, the HEAP_NO_SERIALIZE flag should not be specified when using the HeapAlloc, HeapFree, HeapReAlloc, and HeapSize functions to access the process heap. The system may create additional threads within the application's process (like a Ctrl-C handler) that simultaneously access the process heap. For more information about HEAP_NO_SERIALIZE, see the »HeapCreate« function.

See Also

»HeapAlloc«, »HeapCreate«, »HeapDestroy«, »HeapFree«, »HeapReAlloc«, »HeapSize«


  GetProcessShutdownParameters

BOOL GetProcessShutdownParameters(lpdwLevel, lpdwFlags)
LPDWORD  lpdwLevel;
LPDWORD  lpdwFlags;

The GetProcessShutdownParameters function retrieves shutdown parameters for the currently calling process. For the parameter descriptions, see the »SetProcessShutdownParameters« function.

Parameters

lpdwLevel

Points to a variable that receives the shutdown level. Higher levels shutdown first. System level shutdown orders are reserved for system components. Higher numbers shutdown first. Following are the level conventions.

Value	Meaning
000−0FF	System reserved last shutdown range
100−1FF	Application reserved last shutdown range
200−2FF	Application reserved "in between" shutdown range
300−3FF	Application reserved first shutdown range
400−4FF	System reserved first shutdown range
All processes start at shutdown level 0x280.

lpdwFlags

Points to a variable that receives the shutdown flags. The flags can be added together:

Value	Meaning
SHUTDOWN_NORETRY	If this process takes longer than the specified timeout to shutdown, do not put up a retry dialog for the user. Instead, just cause the process to directly exit.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»SetProcessShutdownParameters«


  GetProcessWindowStation

HWINSTA GetProcessWindowStation(VOID)

The GetProcessWindowStation function returns a handle of the window station associated with the calling process. This handle can be used in calls to the GetUserObjectSecurity and SetUserObjectSecurity functions.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is a handle of the window station associated with the calling process.

If the function fails, the return value is NULL. This can occur if the calling process is not an application written for Windows NT. Use the GetLastError function to get extended error information.

See Also

»GetThreadDesktop«, »GetUserObjectSecurity«, »SetUserObjectSecurity«


  GetProfileInt

UINT GetProfileInt(lpszSection, lpszKey, dwDefault)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKey;   /* address of key name */
INT  dwDefault;   /* default value if key name is not found */

The GetProfileInt function retrieves an integer from the specified key name in the given section of the WIN.INI file. This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string that specifies the section containing the key name.

lpszKey

Points to the null-terminated string containing the key name whose value is to be retrieved. This value is in the form of a string; the GetProfileInt function converts the string into an integer and returns the integer.

dwDefault

Specifies the default value to return if the key name cannot be found in the initialization file..

Return Value

If the function succeeds, the return value is the integer equivalent of the string following the key name in WIN.INI. If the function cannot find the key, the return value is the default value. If the value of the key is less than zero, the return value is zero.

Comments

If the key name consists of digits followed by characters that are not numeric, the function returns only the value of the digits. For example, the function returns 102 for the following line: KeyName=102abc.

Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the GetProfileInt function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetPrivateProfileInt«, »WriteProfileString«


  GetProfileSection

DWORD GetProfileSection(lpszSection, lpszReturnBuffer, cchBuffer)
LPCTSTR  lpszSection;   /* address of section name */
LPTSTR  lpszReturnBuffer;   /* address of return buffer */
DWORD  cchBuffer;   /* size of return buffer */

The GetProfileSection function retrieves all of the keys and values for the specified section of the WIN.INI file. This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string containing the section name in the WIN.INI file.

lpszReturnBuffer

Points to a buffer that receives the keys and values associated with the named section. The buffer is filled with one or more null-terminated strings; the last string is followed by a second null character.

cchBuffer

Specifies the size, in characters, of the buffer pointed to by the lpszReturnBuffer parameter.

Return Value

The return value specifies the number of characters copied to the specified buffer, not including the terminating null character. If the buffer is not large enough to contain all the keys and values associated with the named section, the return value is equal to the length specified by cchBuffer minus two.

Comments

The format of the returned keys and values is one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The GetProfileSection function is not case-sensitive; the strings can be a combination of uppercase and lowercase letters.

This operation is atomic; no updates to the WIN.INI file are allowed while the keys and values for the section are being copied to the buffer.

Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the GetProfileSection function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetPrivateProfileSection«, »WriteProfileSection«


  GetProfileString

DWORD GetProfileString(lpszSection, lpszKey, lpszDefault, lpszReturnBuffer, cchReturnBuffer)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKey;   /* address of key name */
LPCTSTR  lpszDefault;   /* address of default string */
LPTSTR  lpszReturnBuffer;   /* address of destination buffer */
DWORD  cchReturnBuffer;   /* size of destination buffer */

The GetProfileString function retrieves the string associated with the specified key in the given section of the WIN.INI file. This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string that specifies the section containing the key. If this parameter is NULL, the function copies all section names in the file to the supplied buffer.

lpszKey

Points to a null-terminated string containing the key name whose associated string is to be retrieved. If this parameter is NULL, the function copies all keys in the given section to the supplied buffer. Each string is followed by a null character, and the final string is followed by a second null character.

lpszDefault

Points to the default value for the given key if the key cannot be found in the initialization file. This parameter cannot be NULL.

lpszReturnBuffer

Points to a buffer that receives the character string.

cchReturnBuffer

Specifies the size, in characters, of the buffer pointed to by the lpszReturnBuffer parameter.

Return Value

If the function succeeds, the return value is the number of characters copied to the buffer, not including the null-terminating character.

If neither lpszSection nor lpszKey is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to cchReturnBuffer minus one.

If either lpszSection or lpszKey is NULL and the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters. In this case, the return value is equal to cchReturnBuffer minus two.

Comments

If the string associated with the lpszKey parameter is enclosed in single or double quotation marks, the marks are discarded when the GetProfileString function returns the string.

The GetProfileString function is not case-sensitive; the strings can contain a combination of uppercase and lowercase letters.

A section in the WIN.INI file must have the following form:

[section]
key=string
      .
      .
      .

An application can use the GetPrivateProfileString function to retrieve a string from a specified initialization file.

The lpszDefault parameter must point to a valid string, even if the string is empty (that is, even if its first character is a null character).

Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the GetProfileString function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetPrivateProfileString«, »WriteProfileString«


  GetProp

HANDLE GetProp(hwnd, lpsz)
HWND  hwnd;   /* handle of window */
LPCTSTR  lpsz;   /* atom or address of string */

The GetProp function retrieves a data handle from the property list of the given window. The given character string identifies the handle to be retrieved. The string and handle must have been added to the property list by a previous call to the SetProp function.

Parameters

hwnd

Identifies the window whose property list is to be searched.

lpsz

Points to a null-terminated character string or contains an atom that identifies a string. If this parameter is an atom, it must have been created by using the AddAtom function. The atom, a 16-bit value, must be placed in the low-order word of the lpsz parameter; the high-order word must be zero.

Return Value

If the property list contains the given string, the return value is the associated data handle. Otherwise, the return value is NULL.

See Also

»AddAtom«, »EnumProps«, »RemoveProp«, »SetProp«


  GetQueueStatus

DWORD GetQueueStatus(fuFlags)
UINT  fuFlags;   /* queue-status flags */

The GetQueueStatus function returns flags that indicate the type of messages found in the calling thread's message queue.

Parameters

fuFlags

Specifies queue-status flags giving the types of messages to check for. This parameter can be a combination of the following values:

Value	Meaning
QS_ALLINPUT	Any message is in the queue.
QS_HOTKEY	A WM_HOTKEY message is in the queue.
QS_INPUT	An input message is in the queue.
QS_KEY	A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.
QS_MOUSE	A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEBUTTON	A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEMOVE	A WM_MOUSEMOVE message is in the queue.
QS_PAINT	A WM_PAINT message is in the queue.
QS_POSTMESSAGE	A posted message (other than those just listed) is in the queue.
QS_SENDMESSAGE	A message sent by another thread or application is in the queue.
QS_TIMER	A WM_TIMER message is in the queue.
Return Value

The high-order word of the return value indicates the types of messages currently in the queue. The low-order word indicates the types of messages that have been added to the queue and that are still in the queue since the last call to the GetQueueStatus, GetMessage, or PeekMessage function.

This function is very fast; it is typically used inside speed-critical loops to determine whether the GetMessage or PeekMessage function should be called to process input.

Comments

The presence of a QS_ flag in the return value does not guarantee that a subsequent call to the PeekMessage or GetMessage function will return a message. GetMessage and PeekMessage perform some internal filtering that may cause the message to be processed internally. For this reason, the return value from GetQueueStatus should be considered only a hint as to whether GetMessage or PeekMessage should be called.

See Also

»GetInputState«, »GetMessage«, »PeekMessage«


  GetRasterizerCaps

BOOL GetRasterizerCaps(lprs, cb)
LPRASTERIZER_STATUS  lprs;   /* address of rasterizer information structure */
UINT  cb;   /* number of bytes in structure */

The GetRasterizerCaps function returns flags indicating whether TrueType® fonts are installed in the system.

Parameters

lprs

Points to a RASTERIZER_STATUS structure to receive information about the rasterizer. The RASTERIZER_STATUS structure has the following form:

typedef struct _RASTERIZER_STATUS {    /* rs */

    short nSize;

    short wFlags;

    short nLanguageID;

} RASTERIZER_STATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cb

Specifies the number of bytes to be copied into the structure pointed to by the lprs parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetRasterizerCaps function enables applications and printer drivers to determine whether TrueType is installed.

If the TT_AVAILABLE flag is set in the wFlags member of the RASTERIZER_STATUS structure, at least one TrueType font is installed. If the TT_ENABLED flag is set, TrueType is enabled for the system.

The actual number of bytes copied is either the member specified in the cb parameter or the length of the RASTERIZER_STATUS structure, whichever is less.

See Also

»GetOutlineTextMetrics«, »RASTERIZER_STATUS«


  GetRegionData

DWORD GetRegionData(hRgn, dwCount, lpRgnData)
HRGN  hRgn;   /* handle of region */
DWORD  dwCount;   /* size of buffer containing region data */
LPRGNDATA  lpRgnData;   /* address of buffer containing region data */

The GetRegionData function fills the specified buffer with data describing the given region. This data includes the dimensions of the rectangles that make up the region.

Parameters

hRgn

Identifies the region.

dwCount

Specifics the size, in bytes, of the lpRgnData buffer.

lpRgnData

Points to a RGNDATA structure that receives the information. If this parameter is NULL, the return value contains the number of bytes needed for the region data. The RGNDATA structure has the following form:

typedef struct _RGNDATA { /* rgnd */

    RGNDATAHEADER rdh;

    char          Buffer[1];

} RGNDATA;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds and dwCount specifies an adequate number of bytes, the return value is 1. If dwCount is too small or lpRgnData is NULL, the return value is the required number of bytes. Otherwise, the return value is zero.

Comments

This function is used in conjunction with the ExtCreateRegion function.

See Also

»ExtCreateRegion«


  GetRgnBox

int GetRgnBox(hrgn, lprc)
HRGN  hrgn;   /* handle of a region */
LPRECT  lprc;   /* address of structure that receives bounding rect. */

The GetRgnBox function retrieves the bounding rectangle of the given region.

Parameters

hrgn

Identifies the region.

lprc

Points to a RECT structure that receives the bounding rectangle. The RECT structure has the following format:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

The return value specifies the region's complexity. It can be one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than a single rectangle.
If the hrgn parameter does not identify a valid region, the return value is zero.


  GetROP2

int GetROP2(hdc)
HDC  hdc;   /* handle of device context */

The GetROP2 function retrieves the foreground mix mode. The mix mode specifies how the pen or interior color and the color already on the screen are combined to yield a new color.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value specifies the foreground mix mode; otherwise, it is zero.

Comments

Following are the foreground mix modes:

Mix mode	Description
R2_BLACK	Pixel is always 0.
R2_WHITE	Pixel is always 1.
R2_NOP	Pixel remains unchanged.
R2_NOT	Pixel is the inverse of the screen color.
R2_COPYPEN	Pixel is the pen color.
R2_NOTCOPYPEN	Pixel is the inverse of the pen color.
R2_MERGEPENNOT	Pixel is a combination of the pen color and the inverse of the screen color.
R2_MASKPENNOT	Pixel is a combination of the colors common to both the pen and the inverse of the screen.
R2_MERGENOTPEN	Pixel is a combination of the screen color and the inverse of the pen color.
R2_MASKNOTPEN	Pixel is a combination of the colors common to both the screen and the inverse of the pen.
R2_MERGEPEN	Pixel is a combination of the pen color and the screen color.
R2_NOTMERGEPEN	Pixel is the inverse of the R2_MERGEPEN color.
R2_MASKPEN	Pixel is a combination of the colors common to both the pen and the screen.
R2_NOTMASKPEN	Pixel is the inverse of the R2_MASKPEN color.
R2_XORPEN	Pixel is a combination of the colors in the pen and in the screen, but not in both.
R2_NOTXORPEN	Pixel is the inverse of the R2_XORPEN color.
See Also

»SetROP2«


  GetSaveFileName

BOOL GetSaveFileName(lpofn)
LPOPENFILENAME  lpofn;   /* address of structure with initialization data */

The GetSaveFileName function creates a system-defined dialog box that enables the user to select a file to save.

Parameters

lpofn

Points to an OPENFILENAME structure that contains information used to initialize the dialog box. When GetSaveFileName returns, this structure contains information about the user's file selection. The OPENFILENAME structure has the following form:

typedef struct tagOFN { /* ofn */

    DWORD     lStructSize;

    HWND      hwndOwner;

    HINSTANCE hInstance;

    LPCSTR    lpstrFilter;

    LPSTR     lpstrCustomFilter;

    DWORD     nMaxCustFilter;

    DWORD     nFilterIndex;

    LPSTR     lpstrFile;

    DWORD     nMaxFile;

    LPSTR     lpstrFileTitle;

    DWORD     nMaxFileTitle;

    LPSTR     lpstrInitialDir;

    LPCSTR    lpstrTitle;

    DWORD     Flags;

    WORD      nFileOffset;

    WORD      nFileExtension;

    LPCSTR    lpstrDefExt;

    DWORD     lCustData;

    LPOFNHOOKPROC lpfnHook;

    LPCSTR    lpTemplateName;

} OPENFILENAME;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the user selects a file to save, the return value is TRUE. It is FALSE if an error occurs, the user clicks the Cancel button, the user chooses the Close command on the System menu to close the dialog box, or the buffer identified by the lpstrFile member of the OPENFILENAME structure is too small to contain the string that specifies the selected file.

Use the CommDlgExtendedError function to retrieve extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE
CDERR_INITIALIZATION
CDERR_LOCKRESFAILURE
CDERR_LOADRESFAILURE
CDERR_LOADSTRFAILURE
CDERR_MEMALLOCFAILURE
CDERR_MEMLOCKFAILURE
CDERR_NOHINSTANCE
CDERR_NOHOOK
CDERR_NOTEMPLATE
CDERR_STRUCTSIZE
FNERR_BUFFERTOOSMALL
FNERR_INVALIDFILENAME
FNERR_SUBCLASSFAILURE

Comments

If the hook function (pointed to by the lpfnHook member of the OPENFILENAME structure) processes the WM_CTLCOLOR message, this function must return a handle for the brush that should be used to paint the control background.

Ending the dialog from within the hook function by calling the EndDialog function prevents the comdlg32 DLL from properly exiting its worker thread. For applications that dynamically load and/or unload the comdlg32 dll, this may result in an access violation during unload as the worker thread's address space is invalidated.

See Also

»CommDlgExtendedError«, »GetOpenFilename«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  GetScrollPos

int GetScrollPos(hwnd, fnBar)
HWND  hwnd;   /* handle of window with scroll bar */
int  fnBar;   /* scroll bar flags */

The GetScrollPos function retrieves the current position of the scroll box (thumb) in the given scroll bar. The current position is a relative value that depends on the current scrolling range. For example, if the scrolling range is 0 through 100 and the scroll box is in the middle of the bar, the current position is 50.

Parameters

hwnd

Identifies a scroll bar control or a window with a standard scroll bar, depending on the value of the fnBar parameter.

fnBar

Specifies the scroll bar to be examined. This parameter can be one of the following values:

Value	Meaning
SB_CTL	Retrieves the position of the scroll box in a scroll bar control. The hwnd parameter must be the handle of the scroll bar control.
SB_HORZ	Retrieves the position of the scroll box in a window's standard horizontal scroll bar.
SB_VERT	Retrieves the position of the scroll box in a window's standard vertical scroll bar.
Return Value

If the function succeeds, the return value is the current position of the scroll box; otherwise, it is zero. To get extended error information, use the GetLastError function.

See Also

»GetScrollRange«, »ScrollDC«, »ScrollWindow«, »SetScrollPos«, »SetScrollRange«


  GetScrollRange

BOOL GetScrollRange(hwnd, fnBar, lpMinPos, lpMaxPos)
HWND  hwnd;   /* handle of window with scroll bar */
int  fnBar;   /* scroll bar flags */
LPINT  lpMinPos;   /* address of variable that receives minimum position */
LPINT  lpMaxPos;   /* address of variable that receives maximum position */

The GetScrollRange function retrieves the current minimum and maximum scroll box (thumb) positions for the given scroll bar.

Parameters

hwnd

Identifies a scroll bar control or a window with a standard scroll bar, depending on the value of the fnBar parameter.

fnBar

Specifies the scroll bar from which the positions are retrieved. This parameter can be one of the following values:

Value	Meaning
SB_CTL	Retrieves the positions of a scroll bar control. The hwnd parameter must be the handle of the scroll bar control.
SB_HORZ	Retrieves the positions of the window's standard horizontal scroll bar.
SB_VERT	Retrieves the positions of the window's standard vertical scroll bar.
lpMinPos

Points to the integer variable that receives the minimum position.

lpMaxPos

Points to the integer variable that receives the maximum position.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the given window does not have standard scroll bars or is not a scroll bar control, the GetScrollRange function copies zero to the lpMinPos and lpMaxPos parameters.

The default range for a standard scroll bar is 0 through 100. The default range for a scroll bar control is empty (both values are zero).

See Also

»GetScrollPos«, »SetScrollPos«, »SetScrollRange«


  GetSecurityDescriptorControl

BOOL GetSecurityDescriptorControl(psd, psdc, lpdwRevision)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
PSECURITY_DESCRIPTOR_CONTROL  psdc;   /* address of  control structure */
LPDWORD  lpdwRevision;   /* address of revision value */

The GetSecurityDescriptorControl function retrieves a security descriptor's control and revision information.

Parameters

psd

Points to a SECURITY_DESCRIPTOR structure whose control and revision information the function retrieves.

psdc

Points to a SECURITY_DESCRIPTOR_CONTROL structure receiving the security descriptor's control information.

lpdwRevision

Points to a variable receiving the security descriptor's revision value. This value is always set, even when GetSecurityDescriptorControl returns an error.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »IsValidSecurityDescriptor«


  GetSecurityDescriptorDacl

BOOL GetSecurityDescriptorDacl(psd, lpfDaclPresent, lppAcl, lpfDaclDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
LPBOOL  lpfDaclPresent;   /* address of flag for presence of disc. ACL */
PACL  *lppAcl;   /* address of pointer to ACL */
LPBOOL  lpfDaclDefaulted;   /* address of flag for default disc. ACL */

The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access-control list (ACL) in a specified security descriptor.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure containing the discretionary ACL. The function retrieves a pointer to it.

lpfDaclPresent

Points to a flag the function sets to indicate the presence of a discretionary ACL in the specified security descriptor. If this parameter is TRUE, the security descriptor contains a discretionary ACL, and the remaining output parameters in this function receive valid values. If this parameter is FALSE, the security descriptor does not contain a discretionary ACL, and the remaining output parameters do not receive valid values.

lppAcl

Points to a pointer to an ACL structure. If a discretionary ACL exists, the function sets the pointer pointed to by lppAcl to the address of the security descriptor's discretionary ACL. If a discretionary ACL does not exist, no value is stored.

If the function stores a NULL value in the pointer pointed to by lppAcl, the security descriptor has a NULL discretionary ACL. A NULL discretionary ACL implicitly allows all access to an object.

lpfDaclDefaulted

Points to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a discretionary ACL exists for the security descriptor. If this flag is TRUE, the discretionary ACL was retrieved by a default mechanism; if FALSE, the discretionary ACL was explicitly specified by a user.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »InitializeSecurityDescriptor«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorDacl«


  GetSecurityDescriptorGroup

BOOL GetSecurityDescriptorGroup(psd, lppsidGroup, lpfGroupDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
PSID *  lppsidGroup;   /* address of pointer to group SID */
LPBOOL  lpfGroupDefaulted;   /* address of flag for default */

The GetSecurityDescriptorGroup function retrieves the primary group information from a security descriptor.

Parameters

psd

Points to a SECURITY_DESCRIPTOR structure whose primary group information the function retrieves.

lppsidGroup

Points to a pointer to an SID structure identifying the primary group when the function returns. (An SID is a security identifier.) If the security descriptor does not contain a primary group, the function sets the pointer pointed to by lppsidGroup to NULL and ignores the remaining output parameter, lpfGroupDefaulted. If the security descriptor contains a primary group, the function sets the pointer pointed to by lppsidGroup to the address of the security descriptor's group SID structure and provides a valid value for the variable pointed to by lpfGroupDefaulted.

lpfGroupDefaulted

Points to a flag set to the value of the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the lppsidGroup parameter is NULL, no value is set.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorGroup«


  GetSecurityDescriptorLength

DWORD GetSecurityDescriptorLength(psd)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */

The GetSecurityDescriptorLength function returns the length, in bytes, of a structurally valid SECURITY_DESCRIPTOR structure. The length includes the length of all associated structures, such as SID and ACL structures.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure whose length the function returns. The SECURITY_DESCRIPTOR structure is assumed to be valid.

Return Value

If the function succeeds, the return value is the length, in bytes, of the SECURITY_DESCRIPTOR structure. If the SECURITY_DESCRIPTOR's structure is invalid, the return value is undefined.

Comments

The minimum length of a security descriptor is SECURITY_DESCRIPTOR_MIN_LENGTH. A security descriptor of this length has no associated SID or ACL structures.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »IsValidSecurityDescriptor«


  GetSecurityDescriptorOwner

BOOL GetSecurityDescriptorOwner(psd, lppsidOwner, lpfOwnerDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
PSID  *lppsidOwner;   /* address of pointer to owner SID */
LPBOOL  lpfOwnerDefaulted;   /* address of flag for default */

The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor.

Parameters

psd

Points to a SECURITY_DESCRIPTOR structure whose owner information the function retrieves.

lppsidOwner

Points to a pointer to an SID structure identifying the owner when the function returns. (An SID is a security identifier.) If the security descriptor does not contain an owner, the function sets the pointer pointed to by lppsidOwner to NULL and ignores the remaining output parameter, lpfOwnerDefaulted. If the security descriptor contains an owner, the function sets the pointer pointed to by lppsidOwner to the address of the security descriptor's owner SID structure and provides a valid value for the variable pointed to by lpfOwnerDefaulted.

lpfOwnerDefaulted

Points to a flag set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the lppsidOwner parameter is NULL, no value is set.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorSacl«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorOwner«


  GetSecurityDescriptorSacl

BOOL GetSecurityDescriptorSacl(psd, lpfSaclPresent, lppAcl, lpfSaclDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
LPBOOL  lpfSaclPresent;   /* address of flag for presence of system ACL */
PACL  *lppAcl;   /* address of pointer to ACL */
LPBOOL  lpfSaclDefaulted;   /* address of flag for default system ACL */

The GetSecurityDescriptorSacl function retrieves a pointer to the system access-control list (ACL) in a specified security descriptor.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure containing the system ACL to which the function retrieves a pointer to.

lpfSaclPresent

Points to a flag the function sets to indicate the presence of a system ACL in the specified security descriptor. If this parameter is TRUE, the security descriptor contains a system ACL, and the remaining output parameters in this function receive valid values. If this parameter is FALSE, the security descriptor does not contain a system ACL, and the remaining output parameters do not receive valid values.

lppAcl

Points to a pointer to an ACL structure. If a system ACL exists, the function sets the pointer pointed to by lppAcl to the address of the security descriptor's system ACL. If a system ACL does not exist, no value is stored.

If the function stores a NULL value in the pointer pointed to by lppAcl, the security descriptor has a NULL system ACL.

lpfSaclDefaulted

Points to a flag set to the value of the SE_SACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a system ACL exists for the security descriptor.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »InitializeSecurityDescriptor«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorSacl«


  GetSidIdentifierAuthority

PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(psid)
PSID  psid;   /* address of SID to query */

The GetSidIdentifierAuthority function returns the address of the SID_IDENTIFIER_AUTHORITY structure in a specified security identifier (SID).

Parameters

psid

Points to the SID structure for which the address of the SID_IDENTIFIER_AUTHORITY structure is returned.

The SID_IDENTIFIER_AUTHORITY structure has the following form:

typedef struct _SID_IDENTIFIER_AUTHORITY { /* sia */

    BYTE Value[6];

} SID_IDENTIFIER_AUTHORITY ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the address of the SID_IDENTIFIER_AUTHORITY structure for the specified SID structure.

If the function fails, the return value is undefined. The function fails if the SID structure pointed to by the psid parameter is invalid. To get extended error information, use the GetLastError function.

See Also

»GetLengthSid«, »GetSidLengthRequired«, »GetSidSubAuthority«, »GetSidSubAuthorityCount«, »IsValidSid«


  GetSidLengthRequired

DWORD GetSidLengthRequired(cSubauthorities)
UCHAR  cSubauthorities;   /* count of subauthorities */

The GetSidLengthRequired function returns the length, in bytes, of the buffer required to store an SID structure with a specified number of subauthorities.

Parameters

cSubauthorities

Specifies the number of subauthorities to be stored in the SID structure.

Return Value

The return value is the length, in bytes, of the buffer required to store the SID structure. This function cannot fail.

See Also

»AllocateAndInitializeSid«, »GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidSubAuthority«, »GetSidSubAuthorityCount«, »InitializeSid«, »IsValidSid«


  GetSidSubAuthority

PDWORD GetSidSubAuthority(psid, dwSubauthority)
PSID  psid;   /* address of SID to query */
DWORD  dwSubauthority;   /* index of subauthority to retrieve */

The GetSidSubAuthority function returns the address of a specified subauthority in an SID structure. The subauthority value is a relative identifier (RID). An SID is a security identifier.

Parameters

psid

Points to the SID structure from which the address of a subauthority is to be returned.

dwSubauthority

Specifies an index value identifying the subauthority array element whose address the function will return. The function performs no validation tests on this value. An application can call the GetSidSubAuthorityCount function to discover the range of acceptable values.

Return Value

If the function succeeds, the return value is the address of the specified SID subauthority. To get extended error information, use the GetLastError function.

If the function fails, the return value is undefined. The function fails if the specified SID structure is invalid or if the index value specified by the dwSubauthority parameter is out of bounds.

See Also

»GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidLengthRequired«, »GetSidSubAuthorityCount«, »IsValidSid«


  GetSidSubAuthorityCount

PUCHAR GetSidSubAuthorityCount(psid)
PSID  psid;   /* address of SID to query */

The GetSidSubAuthorityCount function returns the address of the field in an SID structure containing the subauthority count. An SID is a security identifier.

Parameters

psid

Points to the SID structure from which a pointer to the subauthority count is returned.

Return Value

If the function succeeds, the return value is a pointer to the subauthority count for the specified SID structure.

If the function fails, the return value is undefined. The function fails if the specified SID structure is invalid. To get extended error information, use the GetLastError function.

See Also

»GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidLengthRequired«, »GetSidSubAuthority«, »IsValidSid«


  GetStartupInfo

VOID GetStartupInfo(lpsi)
LPSTARTUPINFO  lpsi;   /* address of STARTUPINFO structure */

The GetStartupInfo function retrieves the contents of the STARTUPINFO structure that was specified when the calling process was created.

Parameters

lpsi

Points to a STARTUPINFO structure that is filled in by the function. The STARTUPINFO structure has the following format:

typedef struct _STARTUPINFO { /* si */

    DWORD   cb;

    LPTSTR  lpReserved;

    LPTSTR  lpDesktop;

    LPTSTR  lpTitle;

    DWORD   dwX;

    DWORD   dwY;

    DWORD   dwXSize;

    DWORD   dwYSize;

    DWORD   dwXCountChars;

    DWORD   dwYCountChars;

    DWORD   dwFillAttribute;

    DWORD   dwFlags;

    WORD    wShowWindow;

    WORD    cbReserved2;

    LPBYTE  lpReserved2;

    HANDLE  hStdInput;

    HANDLE  hStdOutput;

    HANDLE  hStdError;

} STARTUPINFO, *LPSTARTUPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function does not return a value.

Comments

The STARTUPINFO structure was specified by the process that created the calling process. It can be used to specify properties associated with the main window of the calling process.

See Also

»CreateProcess«


  GetStdHandle

HANDLE GetStdHandle(fdwDevice)
DWORD  fdwDevice;   /* input, output, or error device */

The GetStdHandle function returns a handle for the standard input, standard output, or standard error device.

Parameters

fdwDevice

Specifies the device to return the handle for. This parameter can have one of the following values:

Value	Meaning
STD_INPUT_HANDLE	Standard input handle
STD_OUTPUT_HANDLE	Standard output handle
STD_ERROR_HANDLE	Standard error handle
Return Value

If the function succeeds, the return value is a handle of the specified device; otherwise, it is the INVALID_HANDLE_VALUE flag. To get extended error information, use the GetLastError function.

Comments

Handles returned by GetStdHandle can be used by applications that need to read from or write to the console. When a console is created, the standard input handle is a handle of the console's input buffer, and the standard output and standard error handles are handles of the console's active screen buffer. These handles can be used by the ReadFile or WriteFile function, or any of the console functions that access the console input buffer or a screen buffer (for example, the ReadConsoleInput, WriteConsole, or GetConsoleScreenBufferInfo function).

All handles returned by this function have GENERIC_READ and GENERIC_WRITE access unless the SetStdHandle function has been used to set a standard handle to be some handle with a lesser access.

The standard handles of a process may have been redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle. If the standard handles have been redirected, you can specify "CONIN$" in a call to the CreateFile function to get a handle of a console's input buffer. Similarly, you can specify "CONOUT$" to get a handle of a console's active screen buffer.

See Also

»SetStdHandle«


  GetStockObject

HGDIOBJ GetStockObject(fnObject)
int  fnObject;   /* type of stock object */

The GetStockObject function retrieves a handle to one of the predefined stock pens, brushes, fonts, or palettes.

Parameters

fnObject

Specifies the type of stock object. This parameter can be any one of the following values:

Value	Meaning
BLACK_BRUSH	Black brush.
DKGRAY_BRUSH	Dark gray brush.
GRAY_BRUSH	Gray brush.
HOLLOW_BRUSH	Hollow brush (equivalent to NULL_BRUSH).
LTGRAY_BRUSH	Light gray brush.
NULL_BRUSH	Null brush (equivalent to HOLLOW_BRUSH).
WHITE_BRUSH	White brush.
BLACK_PEN	Black pen.
NULL_PEN	Null pen.
WHITE_PEN	White pen.
ANSI_FIXED_FONT	Windows fixed-pitch system font.
ANSI_VAR_FONT	Windows variable-pitch system font.
DEVICE_DEFAULT_FONT	Device-dependent font.
OEM_FIXED_FONT	Original equipment manufacturer (OEM) dependent fixed font.
SYSTEM_FONT	System font. By default, Windows uses the system font to draw menus, dialog box controls, and text. In Windows versions 3.0 and later, the system font is a variable-pitch font; earlier versions of Windows use a fixed-pitch system font.
SYSTEM_FIXED_FONT	Fixed-pitch system font used in Windows versions earlier than 3.0. This stock object is available for compatibility with earlier versions of Windows.
DEFAULT_PALETTE	Default palette. This palette consists of the static colors in the system palette.
Return Value

If the function succeeds, the return value identifies the logical object requested; otherwise, it is NULL.

Comments

Use the DKGRAY_BRUSH, GRAY_BRUSH, and LTGRAY_BRUSH stock objects only in windows with the CS_HREDRAW and CS_VREDRAW styles. Using a gray stock brush in any other style of window can lead to misalignment of brush patterns after a window is moved or sized. The origins of stock brushes cannot be adjusted.

The HOLLOW_BRUSH and NULL_BRUSH stock objects are equivalent.

See Also

»DeleteObject«, »SelectObject«


  GetStretchBltMode

int GetStretchBltMode(hdc)
HDC  hdc;   /* handle of device context */

The GetStretchBltMode function retrieves the current stretching mode. The stretching mode defines how color data is added to or removed from bitmaps that are stretched or compressed when the StretchBlt function is called.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is the current stretching mode; otherwise, it is zero.

See Also

»SetStretchBltMode«, »StretchBlt«


  GetStringTypeW

BOOL GetStringTypeW(fdwInfoType, lpSrcStr, cchSrc, lpCharType)
DWORD  fdwInfoType;   /* information-type options */
LPCWSTR  lpSrcStr;   /* address of string */
int  cchSrc;   /* number of characters in string */
LPWORD  lpCharType;   /* address of buffer for output */

The GetStringTypeW function returns character-type information about a Unicode string.

Parameters

fdwInfoType

Specifies the type of character information the user wants to retrieve. The various types are divided into different levels (see the Comments section for a list of the information included in each type). This parameter can be one of the following values:

CT_CTYPE1
CT_CTYPE2
CT_CTYPE3

lpSrcStr

Points to the string for which character types are requested.

cchSrc

Specifies the number of characters in the string pointed to by the lpSrcStr parameter and in the buffer specified by lpCharType. If this value is −1, the string is assumed to be null terminated and the length is calculated automatically.

lpCharType

Points to an array whose length is specified in the cchSrc parameter. When the function returns, this array contains one word corresponding to each Unicode character in the source string.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The lpSrcStr and lpCharType pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The character-type bits are divided into several levels. The information for one level can be retrieved by a single call to this function. Each level is limited to 16 bits of information so that the other mapping routines limited to 16 bits of representation per character can return character-type information.

The character types supported by this function include the following.

Ctype 1: These types support ANSI C and POSIX (LC_CTYPE) character-typing functions. A combination of these values is returned in the array pointed to by the lpCharType parameter when the fdwInfoType parameter is set to CT_CTYPE1.

Name	Value	Meaning
C1_UPPER	0x0001	Uppercase
C1_LOWER	0x0002	Lowercase
C1_DIGIT	0x0004	Decimal digits
C1_SPACE	0x0008	Space characters
C1_PUNCT	0x0010	Punctuation
C1_CNTRL	0x0020	Control characters
C1_BLANK	0x0040	Blank characters
C1_XDIGIT	0x0080	Hexadecimal digits
C1_ALPHA	0x0100	Any letter
The following character types are either constant or computable from basic types and do not need to be supported by this function.

Type	Description
Alphanumeric	Alphabetic characters and digits
Printable	Graphic characters and blank
Ctype 2: These types support proper layout of Unicode™ text. The direction attributes are assigned so that the bidirectional layout algorithm standardized by Unicode produces accurate results. These types are mutually exclusive. For more information about the use of these attributes, see The Unicode Standard: Worldwide Character Encoding, Volumes 1 and 2, Addison Wesley Publishing Company: 1991, 1992, ISBN 0201567881.

Name	Value	Meaning
Strong:
C2_LEFTTORIGHT	0x1	Left to right
C2_RIGHTTOLEFT	0x2	Right to left
Weak:
C2_EUROPENUMBER	0x3	European number, European digit
C2_EUROPESEPARATOR	0x4	European numeric separator
C2_EUROPETERMINATOR	0x5	European numeric terminator
C2_ARABICNUMBER	0x6	Arabic number
C2_COMMONSEPARATOR	0x7	Common numeric separator
Neutral:
C2_BLOCKSEPARATOR	0x8	Block separator
C2_SEGMENTSEPARATOR	0x9	Segment separator
C2_WHITESPACE	0xA	White space
C2_OTHERNEUTRAL	0xB	Other neutrals
Not applicable:
C2_NOTAPPLICABLE	0x0	No implicit directionality (for example, control codes)
Ctype 3: These types are intended to be placeholders for extensions to the POSIX types required for general text processing or for the standard C library functions. These types are supported in the current version of Microsoft® Windows NT™. A combination of these values is returned when fdwInfoType is set to CT_CTYPE3.

Name	Value	Meaning
C3_NONSPACING	0x1	Nonspacing mark
C3_DIACRITIC	0x2	Diacritic nonspacing mark
C3_VOWELMARK	0x4	Vowel nonspacing mark
C3_SYMBOL	0x8	Symbol
Not applicable:
C3_NOTAPPLICABLE	0x0	Not applicable
See Also

»GetLocaleInfoW«


  GetSubMenu

HMENU GetSubMenu(hmenu, nPos)
HMENU  hmenu;   /* handle of menu */
int  nPos;   /* menu item position */

The GetSubMenu function retrieves the handle of the pop-up menu activated by the specified menu item.

Parameters

hmenu

Identifies the menu.

nPos

Specifies the zero-based relative position in the given menu of an item that activates a pop-up menu.

Return Value

If the function succeeds, the return value is the handle of the pop-up menu activated by the menu item. If the menu item does not activate a pop-up menu, it is NULL.

See Also

»CreatePopupMenu«, »GetMenu«


  GetSysColor

DWORD GetSysColor(nIndex)
int  nIndex;   /* display element */

The GetSysColor function retrieves the current color of the specified display element. Display elements are the parts of a window and the Windows display that appear on the system display screen.

Parameters

nIndex

Specifies the display element whose color is to be retrieved. This parameter must be one of the following values:

Value	Meaning
COLOR_ACTIVEBORDER	Active window border.
COLOR_ACTIVECAPTION	Active window caption.
COLOR_APPWORKSPACE	Background color of multiple document interface (MDI) applications.
COLOR_BACKGROUND	Desktop.
COLOR_BTNFACE	Face shading on push buttons.
COLOR_BTNSHADOW	Edge shading on push buttons.
COLOR_BTNTEXT	Text on push buttons.
COLOR_CAPTIONTEXT	Text in caption, size box, and scroll bar arrow box.
COLOR_GRAYTEXT	Grayed (disabled) text. This color is set to 0 if the current display driver does not support a solid gray color.
COLOR_HIGHLIGHT	Item(s) selected in a control.
COLOR_HIGHLIGHTTEXT	Text of item(s) selected in a control.
COLOR_INACTIVEBORDER	Inactive window border.
COLOR_INACTIVECAPTION	Inactive window caption.
COLOR_INACTIVECAPTIONTEXT	Color of text in an inactive caption.
COLOR_MENU	Menu background.
COLOR_MENUTEXT	Text in menus.
COLOR_SCROLLBAR	Scroll bar gray area.
COLOR_SHADOW	Color of automatic window shadows.
COLOR_WINDOW	Window background.
COLOR_WINDOWFRAME	Window frame.
COLOR_WINDOWTEXT	Text in windows.
Return Value

If the function succeeds, the return value is the red, green, blue (RGB) color value that specifies the color of the given element.

Comments

System colors for monochrome displays are usually interpreted as shades of gray.

See Also

»SetSysColors«


  GetSysModalWindow

The GetSysModalWindow function has been deleted.


  GetSystemDefaultLangID

LANGID GetSystemDefaultLangID(void)

The GetSystemDefaultLangID function retrieves the system default language identifier.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the system default language identifier.

Comments

For more information about language identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetUserDefaultLangID«, »MAKELANGID«


  GetSystemDefaultLCID

LCID GetSystemDefaultLCID(void)

The GetSystemDefaultLCID function retrieves the system default locale identifier.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the system default locale identifier.

Comments

For more information about locale identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetLocaleInfoW«, »GetUserDefaultLCID«, »MAKELCID«


  GetSystemDir

The GetSystemDir function is not supported in the Win32 API. For Win32 applications, use the GetSystemDirectory function to determine the system directory.

See Also

»GetSystemDirectory«


  GetSystemDirectory

UINT GetSystemDirectory(lpszSysPath, cchSysPath)
LPTSTR  lpszSysPath;   /* address of buffer for system directory */
UINT  cchSysPath;   /* size of directory buffer */

The GetSystemDirectory function retrieves the path of the Windows system directory. The system directory contains such files as Windows libraries, drivers, and font files.

Parameters

lpszSysPath

Points to the buffer to receive the null-terminated string containing the path. This path does not end with a backslash unless the system directory is the root directory. For example, if the system directory is named WINDOWS\SYSTEM on drive C, the path of the system directory retrieved by this function is C:\WINDOWS\SYSTEM.

cchSysPath

Specifies the maximum size of the buffer, in characters. This value should be set to at least MAX_PATH.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer, not including the terminating null character. If the length is greater than the size of the buffer, the return value is the size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Comments

Applications should not create files in the system directory. If the user is running a shared version of Windows, the application does not have write access to the system directory. Applications should create files only in the directory returned by the GetWindowsDirectory function.

See Also

»GetCurrentDirectory«, »GetWindowsDirectory«, »SetCurrentDirectory«


  GetSystemInfo

VOID GetSystemInfo(lpSystemInfo)
LPSYSTEM_INFO  lpSystemInfo;   /* address of system info. structure */

The GetSystemInfo function returns information about the current system.

Parameters

lpSystemInfo

Points to a SYSTEM_INFO structure to be filled in by this function. The SYSTEM_INFO structure has the following form:

typedef struct _SYSTEM_INFO { /* sinf */

    DWORD  dwOemId;

    DWORD  dwPageSize;

    LPVOID lpMinimumApplicationAddress;

    LPVOID lpMaximumApplicationAddress;

    DWORD  dwActiveProcessorMask;

    DWORD  dwNumberOfProcessors;

    DWORD  dwProcessorType;

    DWORD  dwReserved1;

    DWORD  dwReserved2;

} SYSTEM_INFO;

For a full description of the SYSTEM_INFO structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function does not return a value.


  GetSystemMenu

HMENU GetSystemMenu(hwnd, fRevert)
HWND  hwnd;   /* handle of window to own System menu */
BOOL  fRevert;   /* reset flag */

The GetSystemMenu function allows the application to access the System menu (also known as Control menu) for copying and modifying.

Parameters

hwnd

Identifies the window that will own a copy of the System menu.

fRevert

Specifies the action to be taken. If this parameter is FALSE, the GetSystemMenu function returns the handle of the copy of the System menu currently in use. The copy is initially identical to the System menu, but it can be modified.

If this parameter is TRUE, GetSystemMenu resets the System menu back to the Windows default state. The previous System menu, if any, is destroyed.

Return Value

If the fRevert parameter is FALSE, the return value is the handle of a copy of the System menu. If the fRevert parameter is TRUE, the return value is NULL.

Comments

Any window that does not use the GetSystemMenu function to make its own copy of the System menu receives the standard System menu.

The handle returned by the GetSystemMenu function is used with the AppendMenu, InsertMenu, or ModifyMenu function to change the System menu.

The System menu initially contains items with various identifier values, such as SC_CLOSE, SC_MOVE, and SC_SIZE.

Menu items on the System menu send WM_SYSCOMMAND messages.

All predefined System menu items have identifier numbers greater than 0xF000. If an application adds commands to the System menu, it should use identifier numbers less than 0xF000.

Windows automatically grays items on the standard System menu, depending on the situation. The application can carry out its own checking or graying by responding to the WM_INITMENU message, that is sent before any menu is displayed.

See Also

»AppendMenu«, »GetMenu«, »InsertMenu«, »ModifyMenu«


  GetSystemMetrics

int GetSystemMetrics(nIndex)
int  nIndex;   /* system measurement to retrieve */

The GetSystemMetrics function retrieves system metrics. System metrics are the widths and heights of various elements of the Windows display. GetSystemMetrics can also return flags that indicate whether the current version is a debugging version, whether a mouse is present, or whether the meanings of the left and right mouse buttons have been exchanged.

Parameters

nIndex

Specifies the system measurement to be retrieved. All measurements are given in pixels. This parameter must be one of the following values:

Index	Meaning
SM_CXBORDER	Width of window frame that cannot be sized.
SM_CYBORDER	Height of window frame that cannot be sized.
SM_CYCAPTION	Actual caption height plus SM_CYBORDER.
SM_CXCURSOR	Width of cursor.
SM_CYCURSOR	Height of cursor.
SM_CXDLGFRAME	Width of frame when window has WS_DLGFRAME style.
SM_CYDLGFRAME	Height of frame when window has WS_DLGFRAME style.
SM_CXDOUBLECLK	Width of rectangle around location of first click in a double-click sequence. The second click must occur within this rectangle for the system to consider the two clicks a double-click.
SM_CYDOUBLECLK	Height of rectangle around location of first click in a double-click sequence. The second click must occur within this rectangle for the system to consider the two clicks a double-click.
SM_CXFRAME	Width of window frame that can be sized.
SM_CYFRAME	Height of window frame that can be sized.
SM_CXFULLSCREEN	Width of window client area for full-screen window.
SM_CYFULLSCREEN	Height of window client area for full-screen window (equivalent to height of the screen minus height of the window caption).
SM_CXHSCROLL	Width of arrow bitmap on horizontal scroll bar.
SM_CYHSCROLL	Height of arrow bitmap on horizontal scroll bar.
SM_CXICON	Width of icon.
SM_CYICON	Height of icon.
SM_CXICONSPACING	Width of rectangles that Program Manager uses to position tiled icons.
SM_CYICONSPACING	Height of rectangles that Program Manager uses to position tiled icons.
SM_CYKANJIWINDOW	Height of Kanji window.
SM_CYMENU	Height of single-line menu bar minus SM_CYBORDER.
SM_CXMIN	Minimum width of window.
SM_CYMIN	Minimum height of window.
SM_CXMINTRACK	Minimum tracking width of window.
SM_CYMINTRACK	Minimum tracking height of window.
SM_CMOUSEBUTTONS	Number of buttons on mouse.
SM_CXSCREEN	Width of screen.
SM_CYSCREEN	Height of screen.
SM_CXSIZE	Width of bitmaps contained in title bar.
SM_CYSIZE	Height of bitmaps contained in title bar.
SM_CXVSCROLL	Width of arrow bitmap on vertical scroll bar.
SM_CYVSCROLL	Height of arrow bitmap on vertical scroll bar.
SM_CXHTHUMB	Width of thumb box on horizontal scroll bar.
SM_CYVTHUMB	Height of thumb box on vertical scroll bar.
SM_DBCSENABLED	Status of double-byte character set: nonzero if enabled.
SM_DEBUG	Debugging version: nonzero if Windows.
SM_MENUDROPALIGNMENT	Alignment of pop-up menus. If this value is zero, the left side of a pop-up menu is aligned with the left side of the corresponding menu-bar item. If this value is nonzero, the left side of a pop-up menu is aligned with the right side of the corresponding menu-bar item.
SM_MOUSEPRESENT	Status of mouse hardware: nonzero if installed.
SM_PENWINDOWS	Handle of Pen Windows dynamic-link library (DLL) if Pen Windows is installed.
SM_SWAPBUTTON	Status of mouse buttons: nonzero if left and right mouse buttons swapped.
Return Value

If the function succeeds, the return value is the requested system metric.

Comments

System metrics may vary from display to display.


  GetSystemPaletteEntries

UINT GetSystemPaletteEntries(hdc, iStartIndex, nEntries, lppe)
HDC  hdc;   /* handle of device context */
UINT  iStartIndex;   /* index of first entry to be retrieved */
UINT  nEntries;   /* number of entries to be retrieved */
LPPALETTEENTRY  lppe;   /* array receiving system-palette entries */

The GetSystemPaletteEntries function retrieves a range of palette entries from the system palette that is associated with the given device context.

Parameters

hdc

Identifies the device context.

iStartIndex

Specifies the first entry to be retrieved from the system palette.

nEntries

Specifies the number of entries to be retrieved from the system palette.

lppe

Points to an array of PALETTEENTRY structures to receive the palette entries. The array must contain at least as many structures as specified by the nEntries parameter. If this parameter is NULL, the function returns the total number of entries in the palette. The PALETTEENTRY structure has the following form:

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the number of entries retrieved from the palette; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

An application can determine whether or not a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

See Also

»GetDeviceCaps«, »GetPaletteEntries«


  GetSystemPaletteUse

UINT GetSystemPaletteUse(hdc)
HDC  hdc;   /* handle of device context */

The GetSystemPaletteUse function retrieves the current state of the system (physical) palette for the given device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is the current state of the system palette. It can be any of the following values:

Value	Meaning
SYSPAL_NOSTATIC	The system palette contains no static colors, except black and white.
SYSPAL_STATIC	The system palette contains static colors that will not change when an application realizes its logical palette.
SYSPAL_ERROR	The given device-context is invalid or does not support a color palette.
To get extended error information, use the GetLastError function.

Comments

By default, the system palette contains 20 static colors that are not changed when an application realizes its logical palette. An application can gain access to most of these colors by calling the SetSystemPaletteUse function.

The device context identified by the hdc parameter must represent a device that supports color palettes.

An application can determine whether or not a device supports color palettes by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

See Also

»GetDeviceCaps«, »SetSystemPaletteUse«


  GetSystemTime

VOID GetSystemTime(lpst)
LPSYSTEMTIME  lpst;   /* address of system time structure */

The GetSystemTime function retrieves the current system date and time. The system time is expressed in the Coordinated Universal Time (UTC).

Parameters

lpst

Points to a SYSTEMTIME structure to receive the current system date and time.

The SYSTEMTIME structure has the following form:

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function does not return a value.

See Also

»GetLocalTime«, »SetSystemTime«


  GetTabbedTextExtent

DWORD GetTabbedTextExtent(hdc, lpszStr, cchString, nTabPos, lpnTabStopPos)
HDC  hdc;   /* handle of device context */
LPCTSTR  lpszStr;   /* address of character string */
int  cchString;   /* number of characters in string */
int  nTabPos;   /* number of tab positions */
LPINT  lpnTabStopPos;   /* address of array of tab positions */

The GetTabbedTextExtent function computes the width and height of a character string. If the string contains one or more tab characters, the width of the string is based upon the specified tab stops. The GetTabbedTextExtent function uses the currently selected font to compute the dimensions of the string.

Parameters

hdc

Identifies the device context.

lpszStr

Points to a character string.

cchString

Specifies the number of characters in the text string.

nTabPos

Specifies the number of tab-stop positions in the array pointed to by the lpnTabStopPos parameter.

lpnTabStopPos

Points to an array containing the tab-stop positions, in device units. The tab stops must be sorted in increasing order; the smallest x-value should be the first item in the array.

Return Value

If the function succeeds, the return value is the dimensions of the string. The height is in the high-order word and the width is in the low-order word.

Comments

The current clipping region does not affect the width and height returned by the GetTabbedTextExtent function.

Because some devices do not place characters in regular cell arrays (that is, they kern the characters), the sum of the extents of the characters in a string may not be equal to the extent of the string.

If the nTabPos parameter is zero and the lpnTabStopPos parameter is NULL, tabs are expanded to eight times the average character width.

If nTabPos is 1, the tab stops are separated by the distance specified by the first value in the array to which lpnTabStopPos points.

See Also

»GetTextExtentPoint«, »GetTextExtent«, »HIWORD«, »LOWORD«, »TabbedTextOut«


  GetTapeParameters

DWORD GetTapeParameters(hDevice, dwOperation, lpdwSize, lpTapeInformation)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwOperation;   /* type of information requested */
LPDWORD  lpdwSize;   /* address of returned information */
LPVOID  lpTapeInformation;   /* tape media or drive information */

The GetTapeParameters function retrieves information that describes the tape or the tape drive.

Parameters

hDevice

Identifies the device about which information is sought. This handle is created by using the CreateFile function.

dwOperation

Specifies the type of information requested. This must be one of the following values:

Value	Description
GET_TAPE_MEDIA_INFORMATION	Retrieves information about the tape in the tape device.
GET_TAPE_DRIVE_INFORMATION	Retrieves information about the tape device.
lpdwSize

Points to a variable that receives the size, in bytes, of the buffer specified by the lpTapeInformation parameter. If the buffer is too small, this parameter receives the required size.

lpTapeInformation

Points to a structure that contains the requested information. If the dwOperation parameter is GET_TAPE_MEDIA_INFORMATION, lpTapeInformation points to a TAPE_GET_MEDIA_PARAMETERS structure.

The TAPE_GET_MEDIA_PARAMETERS structure has the following form:

typedef struct _TAPE_GET_MEDIA_PARAMETERS {  /* tgmp */

    LARGE_INTEGER   Capacity;

    LARGE_INTEGER   Remaining;

    DWORD   BlockSize;

    DWORD   PartitionCount;

    BOOLEAN WriteProtected;

} TAPE_GET_MEDIA_PARAMETERS;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

If dwOperation is GET_TAPE_DRIVE_INFORMATION, lpTapeInformation points to a TAPE_GET_DRIVE_PARAMETERS structure.

The TAPE_GET_DRIVE_PARAMETERS structure has the following form:

typedef struct _TAPE_GET_DRIVE_PARAMETERS { /* tgdp */

    BOOLEAN ECC;

    BOOLEAN Compression;

    BOOLEAN DataPadding;

    BOOLEAN ReportSetmarks;

    ULONG   DefaultBlockSize;

    ULONG   MaximumBlockSize;

    ULONG   MinimumBlockSize;

    ULONG   MaximumPartitionCount;

    ULONG   FeaturesLow;

    ULONG   FeaturesHigh;

    ULONG   EOTWarningZoneSize;

} TAPE_GET_DRIVE_PARAMETERS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, it can be one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

The block size range values (maximum and minimum) returned by the GetTapeParameters function called with dwOperation set to GET_TAPE_DRIVE_INFORMATION will indicate system limits, not drive limits. However, it is the tape drive device, and the media present in the drive, that determine the true block size limits. Thus, an application may not be able to set all the block sizes mentioned in the range obtained by a GetTapeParameters GET_TAPE_DRIVE_INFORMATION call.

See Also

»SetTapeParameters«


  GetTapePosition

DWORD GetTapePosition(hDevice, dwPositionType, lpdwPartition, lpdwOffsetLow,
lpdwOffsetHigh)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwPositionType;   /* type of address to obtain */
LPDWORD  lpdwPartition;   /* current tape partition */
LPDWORD  lpdwOffsetLow;   /* low-order 32 bits of tape position */
LPDWORD  lpdwOffsetHigh;   /* high-order 32 bits of tape position */

The GetTapePosition function retrieves the current address of the tape, in logical or absolute blocks.

Parameters

hDevice

Identifies the device on which to get the tape position. This handle is created by using CreateFile.

dwPositionType

Specifies the type of address to obtain. This parameter can be one of the following values:

Value	Description
TAPE_ABSOLUTE_POSITION	The lpdwOffsetLow and lpdwOffsetHigh parameters receive the device-specific block address. The dwPartition parameter receives zero.
TAPE_LOGICAL_POSITION	The lpdwOffsetLow and lpdwOffsetHigh parameters receive the logical block address. The dwPartition parameter receives the logical tape partition.
lpdwPartition

Points to a variable that receives the number of the current tape partition. Partitions are numbered logically from 1 through n, where 1 is the first partition on the tape and n is the last. When a device-specific block address is retrieved, or if the device supports only one partition, this parameter receives zero.

lpdwOffsetLow

Points to a variable that receives the low-order 32 bits of the current tape position.

lpdwOffsetHigh

Points to a variable that receives the high-order 32 bits of the current tape position. This parameter can be NULL if the high 32-bits are not required.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

A logical block address is relative to a partition; the first logical block address on each partition is zero.

Call the GetTapeParameters function to obtain information about the status, capabilities, and capacities of tape drives and media.

See Also

»GetTapeParameters«, »SetTapePosition«


  GetTapeStatus

DWORD GetTapeStatus(hDevice)
HANDLE  hDevice;   /* handle of open device */

The GetTapeStatus function indicates whether the tape device is ready to process tape commands.

Parameters

hDevice

Identifies the device for which to get the device status. This handle is created by using the CreateFile function.

Return Value

If the tape device is ready to accept appropriate tape-access commands without returning errors, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.


  GetTempDrive

The GetTempDrive function is obsolete. Win32 applications should use the GetTempPath function.

See Also

»GetTempPath«


  GetTempFileName

UINT GetTempFileName(lpszPath, lpszPrefix, uUnique, lpszTempFile)
LPCTSTR  lpszPath;   /* address of name of dir. where temp. file is created */
LPCTSTR  lpszPrefix;   /* address of prefix of temp. filename */
UINT  uUnique;   /* number used to create temp. filename */
LPTSTR  lpszTempFile;   /* address buffer that will receive temp. filename */

The GetTempFileName function creates a temporary filename of the following form:

path\preuuuu.tmp

The following table describes the filename syntax:

Component	Meaning
path	The path specified by the lpszPath parameter
pre	The first three letters of the lpszPrefix string
uuuu	The hexadecimal value of uUnique
Parameters

lpszPath

Points to a null-terminated string that specifies the path where the function creates the temporary filename. This string must consist of characters in the ANSI character set. Applications typically specify a period (.) or the result of the GetTempPath function for this parameter. If this parameter is NULL, the function fails.

lpszPrefix

Points to a null-terminated string that will be used as the temporary filename prefix. This string must consist of characters in the ANSI character set.

uUnique

Specifies an unsigned integer used in creating the temporary filename. If this parameter is nonzero, it is appended to the temporary filename. If this parameter is zero, Windows uses the current system time to create a number to append to the filename.

lpszTempFile

Points to the buffer that receives the temporary filename. This null-terminated string consists of characters in the ANSI character set. This buffer should be at least the length, in bytes, specified by MAX_PATH to accommodate the path.

Return Value

The return value specifies a unique numeric value used in the temporary filename. If the uUnique parameter is nonzero, the return value specifies this same number.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Comments

When Windows shuts down, temporary files whose name has been created by this function are not automatically deleted.

To avoid problems resulting from converting an ANSI character set string to a Windows string, an application should call the CreateFile function to create the temporary file.

If the uUnique parameter is zero, GetTempFileName attempts to form a unique number based on the current system time. If a file with the resulting filename exists, the number is increased by one and the test for existence is repeated. This continues until a unique filename is found. GetTempFileName then creates a file by that name and closes it. When uUnique is nonzero, no attempt is made to create and open the file.

See Also

»CreateFile«, »GetTempPath«


  GetTempPath

DWORD GetTempPath(cchBuffer, lpszTempPath)
DWORD  cchBuffer;   /* size, in characters, of the buffer */
LPTSTR  lpszTempPath;   /* address of buffer for temp. path name */

The GetTempPath function retrieves the path of the directory designated for temporary files.

Parameters

cchBuffer

Specifies the size, in characters, of the string buffer identified by lpszTempPath.

lpszTempPath

Points to a string buffer that receives the null-terminated temporary file path.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to lpszTempPath, not including the terminating null character. If the return value is greater than cchBuffer, the return value is the size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

See Also

»GetTempFileName«


  GetTextAlign

UINT GetTextAlign(hdc)
HDC  hdc;   /* handle of device context */

The GetTextAlign function retrieves the text-alignment setting for the given device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is the status of the text-alignment flags. Otherwise, it is GDI_ERROR.

To get extended error information, use the GetLastError function.

For a list of status return values, see the Comments section of this entry. The return value is a combination of one or more of the following values:

Value	Meaning
TA_BASELINE	The reference point is on the base line of the text.
TA_BOTTOM	The reference point is on the bottom edge of the bounding rectangle.
TA_TOP	The reference point is on the top edge of the bounding rectangle.
TA_CENTER	The reference point is aligned horizontally with the center of the bounding rectangle.
TA_LEFT	The reference point is on the left edge of the bounding rectangle.
TA_RIGHT	The reference point is on the right edge of the bounding rectangle.
TA_NOUPDATECP	The current position is not updated after each text output call.
TA_UPDATECP	The current position is updated after each text output call.
When the current font has a vertical default base line (as with Kanji), the following values are used instead of TA_BASELINE and TA_CENTER:

Value	Meaning
VTA_BASELINE	The reference point is on the base line of the text.
VTA_CENTER	The reference point is aligned vertically with the center of the bounding rectangle.
Comments

The bounding rectangle is a rectangle bounding all of the character cells in a string of text. Its dimensions can be obtained by calling the GetTextExtent function.

The text-alignment flags determine how the TextOut and ExtTextOut functions align a string of text in relation to the string's reference point provided to TextOut or ExtTextOut.

The text-alignment flags are not necessarily single bit flags and may be equal to zero.

The flags must be examined in groups of related flags, as shown in the following list:

TA_LEFT, TA_RIGHT, and TA_CENTER
TA_BOTTOM, TA_TOP, and TA_BASELINE
TA_NOUPDATECP and TA_UPDATECP

If the current font has a vertical default base line, the related flags are as shown in the following list:

TA_LEFT, TA_RIGHT, and VTA_BASELINE
TA_BOTTOM, TA_TOP, and VTA_CENTER
TA_NOUPDATECP and TA_UPDATECP

To verify that a particular flag is set in the return value of this function, the application must perform the following steps:

1.	Apply the bitwise OR operator to the flag and its related flags.

2.	Apply the bitwise AND operator to the result and the return value.

3.	Test for the equality of this result and the flag.

See Also

»ExtTextOut«, »SetTextAlign«, »TextOut«


  GetTextCharacterExtra

int GetTextCharacterExtra(hdc)
HDC  hdc;   /* handle of device context */

The GetTextCharacterExtra function retrieves the current intercharacter spacing for the given device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is the current intercharacter spacing. Otherwise, it is INVALID_WIDTH.

Comments

The intercharacter spacing defines the extra space, in logical units along the base line, that the TextOut or ExtTextOut functions add to each character as a line is written. The spacing is used to expand lines of text.

See Also

»ExtTextOut«, »TextOut«


  GetTextColor

COLORREF GetTextColor(hdc)
HDC  hdc;   /* handle of device context */

The GetTextColor function retrieves the current text color for the given device context.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is the current text color as a COLORREF value; otherwise, it is CLR_INVALID.

Comments

The text color defines the foreground color of characters drawn by using the TextOut or ExtTextOut function.

See Also

»ExtTextOut«, »TextOut«


  GetTextExtent

The GetTextExtent function has been deleted. For Win32 applications, use the GetTextExtentPoint function.

See Also

»GetTextExtentPoint«


  GetTextExtentExPoint

BOOL GetTextExtentExPoint(hdc, lpszStr, cchString, nMaxExtent, lpnFit, alpDx, lpSize)
HDC  hdc;   /* handle of device context */
LPCTSTR  lpszStr;   /* address of character string */
int  cchString;   /* number of characters in string */
int  nMaxExtent;   /* maximum width for formatted string */
LPINT  lpnFit;   /* address of value specifying max. number of chars. */
LPINT  alpDx;   /* address of array for partial string widths */
LPSIZE  lpSize;   /* address of structure with string dimensions */

The GetTextExtentExPoint function retrieves the number of characters in a specified string that will fit within a given space and fills an array with the text extent for each of those characters. (A text extent is the distance between the beginning of the space and a character that will fit in the space.) This information is useful for word-wrapping calculations.

Parameters

hdc

Identifies the device context.

lpszStr

Points to the null-terminated string for which extents are to be retrieved.

cchString

Specifies the number of bytes in the string pointed to by the lpszStr parameter.

nMaxExtent

Specifies the maximum allowable width, in logical units, of the formatted string.

lpnFit

Points to an integer to receive a count of the maximum number of characters that will fit in the space specified by the nMaxExtent parameter. When the lpnFit parameter is NULL, the nMaxExtent parameter is ignored.

alpDx

Points to an array of integers to receive partial string extents. Each element in the array gives the distance, in logical units, between the beginning of the string and one of the characters that fits in the space specified by the nMaxExtent parameter. Although this array should have at least as many elements as characters specified by the cchString parameter, the function fills the array with extents only for as many characters as are given by the lpnFit parameter. If alpDx is NULL, the function does not compute partial string widths.

lpSize

Points to a SIZE structure that contains the dimensions of the string, in logical units when the function returns. This value cannot be NULL. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If both the lpnFit and alpDx parameters are NULL, calling the GetTextExtentExPoint function is equivalent to calling the GetTextExtentPoint function.

See Also

»GetTextExtentPoint«


  GetTextExtentPoint

BOOL GetTextExtentPoint(hdc, lpsz, cbString, lpSize)
HDC  hdc;   /* handle of device context */
LPCTSTR  lpsz;   /* address of text string */
int  cbString;   /* number of characters in string */
LPSIZE  lpSize;   /* address of structure for string size */

The GetTextExtentPoint function computes the width and height of the given string of text.

Parameters

hdc

Identifies the device context.

lpsz

Points to the string of text.

cbString

Specifies the number of characters in the string.

lpSize

Points to a SIZE structure in which the dimensions of the string are to be returned. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The GetTextExtentPoint function uses the currently selected font to compute the dimensions of the string. The width and height, in logical units, are computed without considering any clipping.

Because some devices kern characters, the sum of the extents of the characters in a string may not be equal to the extent of the string.

The calculated string width takes into account the intercharacter spacing set by the SetTextCharacterExtra function.

See Also

»SetTextCharacterExtra«


  GetTextFace

int GetTextFace(hdc, nCount, lpFaceName)
HDC  hdc;   /* handle of device context */
int  nCount;   /* length of buffer receiving typeface name */
LPTSTR  lpFaceName;   /* address of buffer receiving typeface name */

The GetTextFace function retrieves the typeface name of the font that is selected into the given device context.

Parameters

hdc

Identifies the device context.

nCount

Specifies the size, in characters, of the buffer.

lpFaceName

Points to the buffer that is to receive the typeface name. If this parameter is NULL, the function returns the number of characters in the name, including the terminating null character.

Return Value

If the function succeeds, the return value is the number of characters copied to the buffer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The typeface name is copied as a null-terminated character string.

If the name is longer than the number of characters specified by the nCount parameter, the name is truncated.

See Also

»GetTextAlign«, »GetTextColor«, »GetTextExtentPoint«, »GetTextMetrics«


  GetTextMetrics

BOOL GetTextMetrics(hdc, lptm)
HDC  hdc;   /* handle of device context */
LPTEXTMETRIC  lptm;   /* address of text metrics structure */

The GetTextMetrics function fills the given buffer with the metrics for the currently selected font.

Parameters

hdc

Identifies the device context.

lptm

Points to the TEXTMETRIC structure that is to receive the metrics. The TEXTMETRIC structure has the following form:

typedef struct tagTEXTMETRIC { /* tm */

    LONG tmHeight;

    LONG tmAscent;

    LONG tmDescent;

    LONG tmInternalLeading;

    LONG tmExternalLeading;

    LONG tmAveCharWidth;

    LONG tmMaxCharWidth;

    LONG tmWeight;

    LONG tmOverhang;

    LONG tmDigitizedAspectX;

    LONG tmDigitizedAspectY;

    BYTE tmFirstChar;

    BYTE tmLastChar;

    BYTE tmDefaultChar;

    BYTE tmBreakChar;

    BYTE tmItalic;

    BYTE tmUnderlined;

    BYTE tmStruckOut;

    BYTE tmPitchAndFamily;

    BYTE tmCharSet;

} TEXTMETRIC;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetTextAlign«, »GetTextExtent«, »GetTextFace«, »SetTextJustification«


  GetThreadContext

BOOL GetThreadContext(hThread, lpContext)
HANDLE  hThread;   /* handle of thread with context */
LPCONTEXT  lpContext;   /* address of context structure */

The GetThreadContext function retrieves the context of the specified thread.

Parameters

hThread

Identifies an open handle of a thread whose context is to be retrieved. The handle must have THREAD_GET_CONTEXT access to the thread.

lpContext

Points to the address of a CONTEXT structure that receives the appropriate context of the specified thread. The value of the ContextFlags member of this structure specifies which portions of a thread's context are retrieved. The CONTEXT structure is highly machine specific. Two versions of the CONTEXT structure currently exist, one version for x86 processors and another for MIPS™ processors.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

GetThreadContext is used to retrieve the context of the specified thread. The function allows a selective context to be retrieved based on the value of the ContextFlags member of the CONTEXT structure. The thread identified by the hThread handle is typically being debugged, but the function can also operate when it is not being debugged.

See Also

»SetThreadContext«


  GetThreadDesktop

HDESK GetThreadDesktop(idThread)
DWORD  idThread;   /* thread identifier */

The GetThreadDesktop function returns the handle of the desktop associated with the specified thread. This handle can be used in calls to the GetUserObjectSecurity and SetUserObjectSecurity functions.

Parameters

idThread

Specifies the thread to return the desktop handle for.

Return Value

If the function succeeds, the return value is the handle of the desktop associated with the specified thread.

See Also

»GetCurrentThreadId«, »GetProcessWindowStation«, »GetUserObjectSecurity«, »SetUserObjectSecurity«


  GetThreadLocale

LCID GetThreadLocale(VOID)

The GetThreadLocale function returns the calling thread's current locale.

When a thread is created, it is given the system default thread locale. The system reads the system default thread locale from the registry when the system boots. This system default can be modified for future process and thread creation using Control Panel's International applet.

Parameters

This function has no parameters.

Return Value

The function returns the calling thread's 32-bit LCID locale identifier.

Comments

For more information about locale identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»SetThreadLocale«, »GetSystemDefaultLCID«, »GetUserDefaultLCID«


  GetThreadPriority

int GetThreadPriority(hThread)
HANDLE  hThread;   /* handle to thread */

The GetThreadPriority function returns the priority value for the given thread. This value together with the priority class of the thread's process determines the thread's base priority level.

Parameters

hThread

Identifies the thread. The handle must have THREAD_QUERY_INFORMATION access.

Return Value

If the function succeeds, the return value is the thread's priority level; otherwise, it is THREAD_PRIORITY_ERROR_RETURN. To get extended error information, use the GetLastError function.

The thread's priority level is one of the following values:

Priority	Meaning
THREAD_PRIORITY_IDLE
	Indicates a base priority level of 1 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 16 for REALTIME_PRIORITY_CLASS processes.
THREAD_PRIORITY_LOWEST
	Indicates 2 points below normal priority for the priority class.
THREAD_PRIORITY_BELOW_NORMAL
	Indicates 1 point below normal priority for the priority class.
THREAD_PRIORITY_NORMAL
	Indicates normal priority for the priority class.
THREAD_PRIORITY_ABOVE_NORMAL
	Indicates 1 point above normal priority for the priority class.
THREAD_PRIORITY_HIGHEST
	Indicates 2 points above normal priority for the priority class.
THREAD_PRIORITY_TIME_CRITICAL
	Indicates a base priority level of 15 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 31 for REALTIME_PRIORITY_CLASS processes.
Comments

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The operating system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level will scheduling of threads at a lower level take place.

For a table that shows the base priority levels for each combination of priority class and thread priority value, refer to the reference page for the SetPriorityClass function.

See Also

»SetThreadPriority«, »GetPriorityClass«, »SetPriorityClass«


  GetThreadSelectorEntry

BOOL GetThreadSelectorEntry(hThread, dwSelector, lpSelectorEntry)
HANDLE  hThread;   /* handle of thread that contains selector */
DWORD  dwSelector;   /* number of selector value to look up */
LPLDT_ENTRY  lpSelectorEntry;   /* address of selector entry structure */

The GetThreadSelectorEntry function retrieves a descriptor table entry for the specified selector and thread.

Parameters

hThread

Identifies a handle of the thread containing the specified selector. The handle must have THREAD_QUERY_INFORMATION access.

dwSelector

Specifies the global or local selector value to look up in the thread's descriptor tables.

lpSelectorEntry

Points to a structure that receives a copy of the descriptor table entry, if the specified selector has an entry in the specified thread's descriptor table. This information can be used to convert a segment-relative address to a linear virtual address.

Return Value

If the function succeeds, the return value is TRUE. In that case, the structure pointed to by the lpSelectorEntry parameter receives a copy of the specified descriptor table entry.

If the function fails, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

This function is only functional on x86-based systems. For systems that are not x86-based, the function returns FALSE.

Debuggers use this function to convert segment-relative addresses to linear virtual addresses. The ReadProcessMemory and WriteProcessMemory functions use linear virtual addresses.


  GetThresholdEvent

The GetThresholdEvent function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  GetThresholdStatus

The GetThresholdStatus function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  GetTickCount

DWORD GetTickCount(VOID)

The GetTickCount function retrieves the number of milliseconds that have elapsed since Windows was started.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of milliseconds that have elapsed since Windows was started.

Comments

The GetTickCount function is identical to the GetCurrentTime function. Applications should use the GetTickCount function because its name matches more closely what the function does.

The GetTickCount and GetMessageTime functions return different times. GetMessageTime returns the Windows time when the given message was created, not the current Windows time.

The internal timer wraps around to zero if Windows is run continuously for approximately 49.7 days.

See Also

»GetCurrentTime«, »GetMessageTime«, »GetSystemTime«, »SetSystemTime«


  GetTimeZoneInformation

DWORD GetTimeZoneInformation(lptzi)
LPTIME_ZONE_INFORMATION  lptzi;   /* address of time-zone settings */

The GetTimeZoneInformation function retrieves the current time-zone parameters. These parameters control the translations between Coordinated Universal Time (UTC) time and local time.

Parameters

lptzi

Points to a TIME_ZONE_INFORMATION structure to receive the current time-zone parameters. The TIME_ZONE_INFORMATION structure has the following form:

typedef struct _TIME_ZONE_INFORMATION { /* tzi */

    LONG       Bias;

    WCHAR      StandardName[ 32 ];

    SYSTEMTIME StandardDate;

    LONG       StandardBias;

    WCHAR      DaylightName[ 32 ];

    SYSTEMTIME DaylightDate;

    LONG       DaylightBias;

} TIME_ZONE_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is one of the following values:

Value	Meaning
TIME_ZONE_ID_UNKNOWN	The operating system cannot determine the current time zone. This is usually because a previous call to the SetTimeZoneInformation function supplied only the bias (and no transition dates).
TIME_ZONE_ID_STANDARD	The operating system is operating in the range covered by the StandardDate member of the structure pointed to by the lptzi parameter.
TIME_ZONE_ID_DAYLIGHT	The operating system is operating in the range covered by the DaylightDate member of the structure pointed to by the lptzi parameter.
Otherwise, it is 0xFFFFFFFF. Use the GetLastError function to get extended error information.

Comments

All translations between UTC time and local time are based on the following formula:

UTC = local time + bias

The bias is the difference, in minutes, between UTC time and local time.

See Also

»SetTimeZoneInformation«


  GetTokenInformation

BOOL GetTokenInformation(hToken, tic, lpvReturnedInformation,
cbReturnedInformation, pcbReturnRequired)
HANDLE  hToken;   /* handle of access token */
TOKEN_INFORMATION_CLASS  tic;   /* type of information to retrieve */
LPVOID  lpvReturnedInformation;   /* address of retrieved information */
DWORD  cbReturnedInformation;   /* size of information buffer */
PDWORD  pcbReturnRequired;   /* address of required buffer size */

The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information.

Parameters

hToken

Identifies an access token from which information is retrieved.

tic

Specifies a variable of the TOKEN_INFORMATION_CLASS enumerated type identifying the type of information the function retrieves.

The TOKEN_INFORMATION_CLASS enumerated type has the following form:

typedef enum tagTOKEN_INFORMATION_CLASS { /* tic */

    TokenUser = 1,

    TokenGroups,

    TokenPrivileges,

    TokenOwner,

    TokenPrimaryGroup,

    TokenDefaultDacl,

    TokenSource,

    TokenType,

    TokenImpersonationLevel,

    TokenStatistics

} TOKEN_INFORMATION_CLASS;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpvReturnedInformation

Points to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type of information specified by the tic parameter, as shown in the following list:

Token Information Class	Structure Returned
TokenUser	TOKEN_USER structure. TOKEN_QUERY access is needed to retrieve this information.
TokenGroups	TOKEN_GROUPS structure. TOKEN_QUERY access is needed to retrieve this information.
TokenPrivileges	TOKEN_PRIVILEGES structure. TOKEN_QUERY access is needed to retrieve this information.
TokenOwner	TOKEN_OWNER structure. TOKEN_QUERY access is needed to retrieve this information.
TokenPrimaryGroup	TOKEN_PRIMARY_GROUP structure. TOKEN_QUERY access is needed to retrieve this information.
TokenDefaultDacl	TOKEN_DEFAULT_DACL structure. TOKEN_QUERY access is needed to retrieve this information.
TokenSource	TOKEN_SOURCE structure. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
TokenType	TOKEN_TYPE enumerated type. TOKEN_QUERY access is needed to retrieve this information.
TokenImpersonationLevel	SECURITY_IMPERSONATION_LEVEL enumerated type. TOKEN_QUERY access is needed to retrieve this information about a token. If the access token is not an impersonation token, the function fails.
TokenStatistics	TOKEN_STATISTICS structure. TOKEN_QUERY access is needed to retrieve this information.
The formats for the retrieved structures and enumerated types are listed in the Comments section.

cbReturnedInformation

Specifies the size, in bytes, of the buffer pointed to by the lpvReturnedInformation parameter.

pcbReturnRequired

Points to a variable receiving the actual number of bytes needed for the buffer pointed to by the lpvReturnedInformation parameter. If this value is larger than the value specified in the cbReturnedInformation parameter, the function fails and stores no data in the buffer.

If the value of the tic parameter is TokenDefaultDacl and the token has no default access-control list, the function sets the variable pointed to by pcbReturnRequired to zero and stores no data in the buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The TOKEN_USER structure has the following form:

typedef struct _TOKEN_USER { /* tu */

    SID_AND_ATTRIBUTES User;

} TOKEN_USER;

The TOKEN_GROUPS structure has the following form:

typedef struct _TOKEN_GROUPS { /* tg */

    DWORD GroupCount;

    SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];

} TOKEN_GROUPS;

The TOKEN_PRIVILEGES structure has the following form:

typedef struct _TOKEN_PRIVILEGES { /* tp */

    DWORD PrivilegeCount;

    LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];

} TOKEN_PRIVILEGES;

The TOKEN_OWNER structure has the following form:

typedef struct _TOKEN_OWNER { /* to */

    PSID Owner;

} TOKEN_OWNER;

The TOKEN_PRIMARY_GROUP structure has the following form:

typedef struct _TOKEN_PRIMARY_GROUP { /* tpg */

    PSID PrimaryGroup;

} TOKEN_PRIMARY_GROUP;

The TOKEN_DEFAULT_DACL structure has the following form:

typedef struct _TOKEN_DEFAULT_DACL {  /* tdd */

    PACL DefaultDacl;

} TOKEN_DEFAULT_DACL;

The TOKEN_SOURCE structure has the following form:

typedef struct _TOKEN_SOURCE { /* ts */

    CHAR SourceName[8];

    LUID SourceIdentifier;

} TOKEN_SOURCE;

The TOKEN_TYPE enumerated type has the following form:

typedef enum tagTOKEN_TYPE { /* tt */

    TokenPrimary = 1,

    TokenImpersonation

} TOKEN_TYPE;

The SECURITY_IMPERSONATION_LEVEL enumerated type has the following form:

typedef enum tagSECURITY_IMPERSONATION_LEVEL { /* sil */

    SecurityAnonymous,

    SecurityIdentification,

    SecurityImpersonation,

    SecurityDelegation

} SECURITY_IMPERSONATION_LEVEL;

The TOKEN_STATISTICS structure has the following form:

typedef struct _TOKEN_STATISTICS { /* tst */

    LUID  TokenId;

    LUID  AuthenticationId;

    LARGE_INTEGER ExpirationTime;

    TOKEN_TYPE    TokenType;

    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;

    DWORD DynamicCharged;

    DWORD DynamicAvailable;

    DWORD GroupCount;

    DWORD PrivilegeCount;

    LUID  ModifiedId;

} TOKEN_STATISTICS;

For full descriptions of these structures and enumerated types, see the Microsoft Win32 Programmer's Reference, Volume 5.

See Also

»AdjustTokenGroups«, »AdjustTokenPrivileges«, »OpenProcessToken«, »OpenThreadToken«, »SetTokenInformation«


  GetTopWindow

HWND GetTopWindow(hwndParent)
HWND  hwndParent;   /* handle of parent window */

The GetTopWindow function examines the Z order of the child windows associated with the given parent window and retrieves the handle of the child window at the top of the Z order.

Parameters

hwndParent

Identifies the parent window whose child windows are to be examined. If this parameter is NULL, the function returns the top-level window at the top of the Z order.

Return Value

If the function succeeds, the return value is the handle of the child window at the top of the Z order. If the given window has no child windows, the return value is NULL. To get extended error information, use the GetLastError function.

See Also

»GetNextWindow«, »GetWindow«


  GetUpdateRect

BOOL GetUpdateRect(hwnd, lprc, bErase)
HWND  hwnd;   /* handle of window */
LPRECT  lprc;   /* address of structure for update rectangle */
BOOL  bErase;   /* erase flag */

The GetUpdateRect function retrieves the coordinates of the smallest rectangle that completely encloses the update region of the given window. If the window was created with the CS_OWNDC style and the mapping mode is not MM_TEXT, GetUpdateRect retrieves the rectangle in logical coordinates. Otherwise, GetUpdateRect retrieves the rectangle in client coordinates. If there is no update region, GetUpdateRect retrieves an empty rectangle (sets all coordinates to zero).

Parameters

hwnd

Identifies the window whose update region is to be retrieved.

lprc

Points to the RECT structure that receives the coordinates of the enclosing rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

An application can set this parameter to NULL to determine whether an update region exists for the window. If this parameter is NULL, GetUpdateRect returns nonzero if an update region exists, and zero if one does not. This provides a simple and efficient means of determining whether a WM_PAINT message resulted from an invalid area.

bErase

Specifies whether the background in the update region is to be erased. If this parameter is TRUE and the update region is not empty, GetUpdateRect sends a WM_ERASEBKGND message to the given window to erase the background.

Return Value

If the update region is not empty, the return value is TRUE; otherwise, it is FALSE.

Comments

The update rectangle retrieved by the BeginPaint function is identical to that retrieved by GetUpdateRect.

BeginPaint automatically validates the update region, so any call to GetUpdateRect made immediately after the call to BeginPaint retrieves an empty update region.

See Also

»BeginPaint«, »GetUpdateRgn«, »InvalidateRect«, »UpdateWindow«, »ValidateRect«


  GetUpdateRgn

int GetUpdateRgn(hwnd, hrgn, fErase)
HWND  hwnd;   /* handle of window */
HRGN  hrgn;   /* handle of region */
BOOL  fErase;   /* erase background flag */

The GetUpdateRgn function retrieves the update region of the given window by copying it into the given region. The coordinates of the update region are relative to the upper-left corner of the window (that is, they are client coordinates).

Parameters

hwnd

Identifies the window whose update region is to be retrieved.

hrgn

Identifies the region to receive the update region.

fErase

Specifies whether the window background should be erased and whether nonclient areas of child windows should be drawn. If this parameter is FALSE, no drawing is done.

Return Value

The return value indicates the complexity of the resulting region; it can be one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region consists of more than one rectangle.
ERROR	An error occurred.
Comments

The BeginPaint function automatically validates the update region, so any call to GetUpdateRgn made immediately after the call to BeginPaint retrieves an empty update region.

See Also

»BeginPaint«, »GetUpdateRect«, »InvalidateRgn«, »UpdateWindow«, »ValidateRgn«


  GetUserDefaultLangID

LANGID GetUserDefaultLangID(void)

The GetUserDefaultLangID function retrieves the user default language identifier.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the user default language identifier.

Comments

For more information about language identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetSystemDefaultLangID«, »MAKELANGID«


  GetUserDefaultLCID

LCID GetUserDefaultLCID(void)

The GetUserDefaultLCID function retrieves the user default locale identifier.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the user default locale identifier.

Comments

For more information about locale identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetLocaleInfoW«, »GetSystemDefaultLCID«, »MAKELCID«


  GetUserName

BOOL GetUserName(lpBuffer, lpcchBuffer)
LPTSTR  lpBuffer;   /* address of name buffer */
LPDWORD  lpcchBuffer;   /* address of size of name buffer */

The GetUserName function retrieves the user name of the current thread. This is the name of the user currently logged onto the system.

Parameters

lpBuffer

Points to the buffer to receive the null-terminated string containing the user's logon name. If this buffer is not large enough to contain the entire user name, the function fails.

lpcchBuffer

Pointer to a DWORD that, on input, specifies the maximum size, in characters, of the buffer specified by the lpBuffer parameter. If this buffer is not large enough to contain the entire user name, the function fails. If the function succeeds, it will place the number of characters copied to the buffer into the DWORD that lpcchBuffer points to.

Return Value

If the function succeeds, the return value is TRUE, and the variable pointed to by lpcchBuffer contains the number of characters copied to the buffer specified by lpBuffer, including the terminating null character.

If the function fails, the return value is FALSE. Use the GetLastError function to obtain extended error information.

Comments

If the current thread is impersonating another client, the GetUserName function returns the user name of the client that the thread is impersonating.

See Also

»LookupAccountName«


  GetUserObjectSecurity

BOOL GetUserObjectSecurity(hObject, psi, psd, cbsd, lpcbsdRequired)
HANDLE  hObject;   /* handle of user object */
PSECURITY_INFORMATION  psi;   /* address of requested security information */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
DWORD  cbsd;   /* size of buffer for security descriptor */
LPDWORD  lpcbsdRequired;   /* address of required size of buffer */

The GetUserObjectSecurity function retrieves security information for the specified user object.

Parameters

hObject

Identifies the user object for which to return security information.

psi

Points to a SECURITY_INFORMATION structure specifying the security information being requested.

psd

Points to a SECURITY_DESCRIPTOR structure in self-relative format that contains the requested information when the function returns.

cbsd

Specifies the length, in bytes, of the buffer pointed to by the psd parameter.

lpcbsdRequired

Points to a variable receiving the number of bytes required to store the complete security descriptor. If this variable's value is greater than the value of the cbsd parameter when the function returns, the function returns FALSE and none of the security descriptor is copied to the buffer. Otherwise, the entire security descriptor is copied.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreatePrivateObjectSecurity«, »GetKernelObjectSecurity«, »GetPrivateObjectSecurity«, »SetUserObjectSecurity«


  GetVersion

DWORD GetVersion(VOID)

The GetVersion function returns the current version number of Windows and information about the operating system platform.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the major and minor version numbers of Windows and a code specifying the operating system platform. The low word contains the version number of Windows. The high byte specifies the minor version (revision) number, in hexadecimal notation. The low byte specifies the major version number, in hexadecimal notation.

The high word contains the information about the operating system platform. The high bit specifies the platform, as follows:

Value	Platform
0	Windows NT
1	Win32s™ on Windows 3.1
The remaining bits in the high word are reserved for Microsoft internal use.

Comments

This function does not return the current version number of MS-DOS®.


  GetViewportExt

The GetViewportExt function has been deleted. Win32 applications should use the GetViewportExtEx function.

See Also

»GetViewportExtEx«


  GetViewportExtEx

BOOL GetViewportExtEx(hdc, lpSize)
HDC  hdc;   /* handle of device context */
LPSIZE  lpSize;   /* address of structure receiving viewport dimensions */

The GetViewportExtEx function retrieves the x-extents and y-extents of the current viewport for the given device context (DC).

Parameters

hdc

Identifies the DC.

lpSize

Points to a SIZE structure. The x- and y-extents, in device units, are placed in this structure. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetWindowExtEx«, »SetViewportExtEx«, »SetWindowExtEx«


  GetViewportOrg

The GetViewportOrg function has been deleted. Win32 applications should use the GetViewportOrgEx function.

See Also

»GetViewportOrgEx«


  GetViewportOrgEx

BOOL GetViewportOrgEx(hdc, lpPoint)
HDC  hdc;   /* handle of device context */
LPPOINT  lpPoint;   /* address of structure receiving the viewport origin */

The GetViewportOrgEx function retrieves the x-coordinates and y-coordinates of the viewport origin for the given device context (DC).

Parameters

hdc

Identifies the DC.

lpPoint

Points to a POINT structure that receives the origin coordinates. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetWindowOrgEx«, »SetViewportOrgEx«, »SetWindowOrgEx«


  GetVolumeInformation

BOOL GetVolumeInformation(lpRootPathName, lpVolumeNameBuffer,
nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags,
lpFileSystemNameBuffer, nFileSystemNameSize)
LPTSTR  lpRootPathName;   /* address of root dir. of the file system */
LPTSTR  lpVolumeNameBuffer;   /* address of name of the volume */
DWORD  nVolumeNameSize;   /* length of lpVolumeNameBuffer */
LPDWORD  lpVolumeSerialNumber;   /* address of volume serial number */
LPDWORD  lpMaximumComponentLength;   /* address of system's max. length of filename */
LPDWORD  lpFileSystemFlags;   /* address of file system flags */
LPTSTR  lpFileSystemNameBuffer;   /* address of name of file system */
DWORD  nFileSystemNameSize;   /* length of lpFileSystemNameBuffer */

The GetVolumeInformation function returns information about the file system whose root directory is specified.

Parameters

lpRootPathName

Points to a string that contains the root directory of the volume to be described. If this parameter is NULL, the root of the current directory is used.

lpVolumeNameBuffer

Points to a buffer that receives the name of the specified volume.

nVolumeNameSize

Specifies the length, in characters, of the volume name buffer. This parameter is ignored if the volume name buffer is not supplied.

lpVolumeSerialNumber

Points to a variable that receives the volume serial number. This parameter can be NULL if the serial number is not required.

lpMaximumComponentLength

Points to a doubleword value that receives the maximum length, in characters, of a filename component supported by the specified file system. A filename component is that portion of a filename between backslashes.

On systems that use the high-performance (HPFS) and New Technology (NTFS) file systems, this function may indicate that individual filename components can be up to 255 characters. However, you cannot create a filename of this length because the CreateFile function has a limit of 255 characters for the combined path and filename.

lpFileSystemFlags

Points to a doubleword that receives flags associated with the specified file system. This parameter can be any combination of the following flags:

Value	Meaning
FS_CASE_IS_PRESERVED
	The case of filenames is preserved when the name is placed on disk.
FS_CASE_SENSITIVE
	The file system supports case-sensitive filename lookup.
FS_UNICODE_STORED_ON_DISK
	The file system supports Unicode in filenames as they appear on disk.
lpFileSystemNameBuffer

Points to a buffer that receives the name of the file system (such as FAT, HPFS, or NTFS).

nFileSystemNameSize

Specifies the length, in characters, of the file system name buffer. This parameter is ignored if the file system name buffer is not supplied.

Return Value

If all the requested information is retrieved, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetVolumeLabel«


  GetWindow

HWND GetWindow(hwnd, uCmd)
HWND  hwnd;   /* handle of original window */
UINT  uCmd;   /* relationship flag */

The GetWindow function retrieves the handle of a window that has the specified relationship to the given window.

Parameters

hwnd

Identifies a window. The window handle retrieved is relative to this window, based on the value of the uCmd parameter.

uCmd

Specifies the relationship between the given window and the window whose handle is to be retrieved. This parameter can be one of the following values:

Value	Meaning
GW_CHILD	The retrieved handle identifies the child window at the top of the Z order, if the given window is a parent window; otherwise, the retrieved handle is NULL. The function examines only child windows of the given window. It does not examine descendant windows.
GW_HWNDFIRST	The retrieved handle identifies the window at the top of the Z order. If the given window is a topmost window, the handle identifies the topmost window at the top of the Z order. If the given window is a top-level window, the handle identifies the top-level window at the top of the Z order. If the given window is a child window, the handle identifies the sibling window at the top of the Z order.
GW_HWNDLAST	The retrieved handle identifies the window at the bottom of the Z order. If the given window is a topmost window, the handle identifies the topmost window at the bottom of the Z order. If the given window is a top-level window, the handle identifies the top-level window at the bottom of the Z order. If the given window is a child window, the handle identifies the sibling window at the bottom of the Z order.
GW_HWNDNEXT	The retrieved handle identifies the window below the given window in the Z order. If the given window is a topmost window, the handle identifies the topmost window below the given window. If the given window is a top-level window, the handle identifies the top-level window below the given window. If the given window is a child window, the handle identifies the sibling window below the given window.
GW_HWNDPREV	The retrieved handle identifies the window above the given window in the Z order. If the given window is a topmost window, the handle identifies the topmost window above the given window. If the given window is a top-level window, the handle identifies the top-level window above the given window. If the given window is a child window, the handle identifies the sibling window above the given window.
GW_OWNER	The retrieved handle identifies the given window's owner window, if any.
Return Value

If the function succeeds, the return value is a window handle. If no window exists with the specified relationship to the given window, the return value is NULL. To get extended error information, use the GetLastError function.

See Also

»GetActiveWindow«, »GetNextWindow«, »GetTopWindow«


  GetWindowDC

HDC GetWindowDC(hwnd)
HWND  hwnd;   /* handle of window */

The GetWindowDC function retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars. A window DC permits painting anywhere in a window, because the origin of the DC is the upper-left corner of the window instead of the client area.

GetWindowDC assigns default attributes to the window DC each time it retrieves the DC. Previous attributes are lost.

Parameters

hwnd

Identifies the window whose DC is to be retrieved.

Return Value

If the function succeeds, the return value is the handle of a DC for the given window. Otherwise, it is NULL, indicating an error or an invalid hwnd parameter.

Comments

GetWindowDC is intended for special painting effects within a window's nonclient area. Painting in nonclient areas of any window is not recommended.

The GetSystemMetrics function can be used to retrieve the dimensions of various parts of the nonclient area, such as the title bar, menu, and scroll bars.

After painting is complete, the ReleaseDC function must be called to release the DC. Not releasing the window DC has serious effects on painting requested by applications.

See Also

»BeginPaint«, »GetSystemMetrics«, »ReleaseDC«, »GetDC«


  GetWindowExt

The GetWindowExt function has been deleted. Win32 applications should use the GetWindowExtEx function.

See Also

»GetWindowExtEx«


  GetWindowExtEx

BOOL GetWindowExtEx(hdc, lpSize)
HDC  hdc;   /* handle of device context */
LPSIZE  lpSize;   /* address of structure receiving window extents */

This function retrieves the x-extents and y-extents of the window for the given device context (DC).

Parameters

hdc

Identifies the DC.

lpSize

Points to a SIZE structure. The x- and y-extents in page-space units are placed in this structure. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetViewportExtEx«, »SetViewportExtEx«, »SetWindowExtEx«


  GetWindowLong

LONG GetWindowLong(hwnd, nIndex)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* offset of value to retrieve */

The GetWindowLong function retrieves information about the given window. The function also retrieves the 32-bit (long) value at the specified offset into the extra window memory of the given window.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the zero-based offset to the value to be retrieved. Valid values are in the range zero through the number of bytes of extra window memory, minus four; for example, if you specified 12 or more bytes of extra memory, a value of 8 would be an index to the third long integer. To set any other value, specify one of the following values:

Value	Action
GWL_EXSTYLE	Retrieves the extended window styles.
GWL_STYLE	Retrieves the window styles.
GWL_WNDPROC	Retrieves the address of the window procedure.
GWL_HINSTANCE	Retrieves the handle of the application instance.
GWL_HWNDPARENT	Retrieves the handle of the parent window, if any.
GWL_ID	Retrieves the identifier of the window.
GWL_USERDATA	Retrieves the long value associated with the window. Each window has a corresponding long value intended for use by the application that created the window.
The following values are also available when the hwnd parameter identifies a dialog box:

Value	Action
DWL_DLGPROC	Specifies the address of the dialog box procedure.
DWL_MSGRESULT	Specifies the return value of a message processed in the dialog box procedure.
DWL_USER	Specifies extra information private to the application, such as handles or pointers.
Return Value

If the function succeeds, the return value is the requested 32-bit value; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASS structure used with the RegisterClass function.

See Also

»GetWindowWord«, »SetParent«, »SetWindowLong«, »SetWindowWord«


  GetWindowOrg

The GetWindowOrg function has been deleted. Win32 applications should use the GetWindowOrgEx function.

See Also

»GetWindowOrgEx«


  GetWindowOrgEx

BOOL GetWindowOrgEx(hdc, lpPoint)
HDC  hdc;   /* handle of device context */
LPPOINT  lpPoint;   /* address of structure receiving the window origin */

The GetWindowOrgEx function retrieves the x-coordinates and y-coordinates of the window origin for the given device context (DC).

Parameters

hdc

Identifies the device context.

lpPoint

Points to a POINT structure that receives the coordinates, in page units, of the window origin. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetViewportOrgEx«, »SetViewportOrgEx«, »SetWindowOrgEx«


  GetWindowPlacement

BOOL GetWindowPlacement(hwnd, lpwndpl)
HWND  hwnd;   /* handle of window */
LPWINDOWPLACEMENT  lpwndpl;   /* address of structure for position data */

The GetWindowPlacement function retrieves the show state and the restored, minimized, and maximized positions of the given window.

Parameters

hwnd

Identifies the window.

lpwndpl

Points to the WINDOWPLACEMENT structure that receives the show state and position information. The WINDOWPLACEMENT structure has the following form:

typedef struct tagWINDOWPLACEMENT {     /* wndpl */

    UINT  length;

    UINT  flags;

    UINT  showCmd;

    POINT ptMinPosition;

    POINT ptMaxPosition;

    RECT  rcNormalPosition;

} WINDOWPLACEMENT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The flags member of the WINDOWPLACEMENT structure retrieved by this function is always zero. If the window identified by the hwnd parameter is maximized, the showCmd member is SW_SHOWMAXIMIZED. If the window is minimized, showCmd is SW_SHOWMINIMIZED. Otherwise, it is SW_SHOWNORMAL.

See Also

»SetWindowPlacement«


  GetWindowRect

BOOL GetWindowRect(hwnd, lprc)
HWND  hwnd;   /* handle of window */
LPRECT  lprc;   /* address of structure for window coordinates */

The GetWindowRect function retrieves the dimensions of the bounding rectangle of the given window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.

Parameters

hwnd

Identifies the window.

lprc

Points to a RECT structure that receives the screen coordinates of the upper left and lower right corners of the window. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetClientRect«


  GetWindowsDir

The GetWindowsDir function is not supported in the Win32 API. Win32 applications can use the GetWindowsDirectory function to determine the Windows directory.

See Also

»GetWindowsDirectory«


  GetWindowsDirectory

UINT GetWindowsDirectory(lpszWinPath, cchWinPath)
LPTSTR  lpszWinPath;   /* address of buffer for Windows directory */
UINT  cchWinPath;   /* size of directory buffer */

The GetWindowsDirectory function retrieves the path of the Windows directory. The Windows directory contains such files as Windows-based applications, initialization files, and Help files.

Parameters

lpszWinPath

Points to the buffer to receive the null-terminated string containing the path. This path does not end with a backslash unless the Windows directory is the root directory. For example, if the Windows directory is named WINDOWS on drive C, the path of the Windows directory retrieved by this function is C:\WINDOWS. If Windows was installed in the root directory of drive C, the path retrieved is C:\.

cchWinPath

Specifies the maximum size, in characters, of the buffer specified by the lpszWinPath parameter. This value should be set to at least MAX_PATH to allow sufficient room in the buffer for the path.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer, not including the terminating null character.

If the length is greater than the size of the buffer, the return value is the size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Comments

The Windows directory is the only directory where an application should create files. If the user is running a shared version of Windows, the Windows directory is the only directory guaranteed to be private to the user.

See Also

»GetCurrentDirectory«, »GetSystemDirectory«


  GetWindowTask

The GetWindowTask function is now obsolete. It has been replaced by the GetWindowThreadProcessId function.

To maintain compatibility for older applications, GetWindowTask has been replaced with a macro that calls GetWindowThreadProcessId. Older applications may continue to call GetWindowTask as previously documented, but new applications should use GetWindowThreadProcessId .

Comments

GetWindowTask is defined as returning a value with a HANDLE data type. GetWindowThreadProcessId returns a value with a DWORD data type. The macro that maps GetWindowTask to GetWindowThreadProcessId includes a cast to HANDLE, as follows:

#define GetWindowTask(hwnd) ((HANDLE) GetWindowThreadProcessId(hwnd, NULL))

See Also

»GetWindowThreadProcessId«


  GetWindowText

int GetWindowText(hwnd, lpsz, cch)
HWND  hwnd;   /* handle of window or control with text */
LPTSTR  lpsz;   /* address of buffer for text */
int  cch;   /* maximum number of characters to copy */

The GetWindowText function copies the text of the given window's title bar (if it has one) into a buffer. If the given window is a control, the text of the control is copied.

Parameters

hwnd

Identifies the window or control containing the text.

lpsz

Points to the buffer that will receive the text.

cch

Specifies the maximum number of characters to copy to the buffer. If the text exceeds this limit, it is truncated.

Return Value

If the function succeeds, the return value is the length, in characters, of the copied string, not including the terminating null character. If the window has no title bar or text, if the title bar is empty, or if the window or control handle is invalid, the return value is zero. To get extended error information, use the GetLastError function.

Comments

This function causes a WM_GETTEXT message to be sent to the given window or control.

See Also

»GetWindowTextLength«, »SetWindowText«


  GetWindowTextLength

int GetWindowTextLength(hwnd)
HWND  hwnd;   /* handle of window or control with text */

The GetWindowTextLength function retrieves the length, in characters, of the given window's title bar text (if the window has a title bar). If the given window is a control, the function retrieves the length of the text within the control.

Parameters

hwnd

Identifies the window or control.

Return Value

If the function succeeds, the return value is the length, in characters, of the text. If the window has no text, the return value is zero. To get extended error information, use the GetLastError function.

Comments

This function causes a WM_GETTEXTLENGTH message to be sent to the given window or control.

See Also

»GetWindowText«, »SetWindowText«


  GetWindowThreadProcessId

DWORD GetWindowThreadProcessId(hwnd, lpdwProcessId)
HWND  hwnd;   /* handle of window */
LPDWORD  lpdwProcessId;   /* address of variable for process identifier */

The GetWindowThreadProcessId function retrieves the identifier of the thread that created the given window and, optionally, the identifier of the process that created the window.

Parameters

hwnd

Identifies the window.

lpdwProcessId

Points to a 32-bit value that receives the process identifier. If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the process to the 32-bit value; otherwise, it does not.

Return Value

The return value is the identifier of the thread that created the window.

Comments

This function replaces the GetWindowTask function of Windows version 3.x.

See Also

»GetWindowTask«


  GetWindowWord

WORD GetWindowWord(hwnd, nIndex)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* offset of value to retrieve */

The GetWindowWord function retrieves a 16-bit (word) value at the specified offset into the extra window memory for the given window.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the zero-based byte offset of the value to be retrieved. Valid values are in the range zero through the number of bytes of extra window memory, minus two; for example, if you specified 10 or more bytes of extra window memory, a value of 8 would be an index to the fifth 16-bit integer.

Return Value

If the function succeeds, the return value is the requested 16-bit value; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASS structure used with the RegisterClass function.

The GWW_ values are obsolete in the Win32 application programming interface (API). You must use the GetWindowLong function to retrieve information about the window.

See Also

»GetParent«, »GetWindowLong«, »SetParent«, »SetWindowLong«, »SetWindowWord«


  GetWinFlags

The GetWinFlags function has been deleted. Win32 applications should use the GetSystemInfo function.

See Also

»GetSystemInfo«


  GetWinMetaFileBits

UINT GetWinMetaFileBits(hemf, cbBuffer, lpbBuffer, fnMapMode, hdcRef)
HENHMETAFILE  hemf;   /* handle of the enhanced metafile */
UINT  cbBuffer;   /* buffer size */
LPBYTE  lpbBuffer;   /* pointer to buffer */
INT  fnMapMode;   /* mapping mode */
HDC  hdcRef;   /* handle of reference device context */

The GetWinMetaFileBits function converts the enhanced-format records from a metafile into Windows-format records and stores the converted records in the specified buffer.

Parameters

hemf

Identifies the enhanced metafile.

cbBuffer

Specifies the size, in bytes, of the buffer into which the converted records are to be copied.

lpbBuffer

Points to the buffer into which the converted records are to be copied. If lpbBuffer is NULL, GetWinMetaFileBits returns the the number of bytes required to store the converted metafile records.

fnMapMode

Specifies the mapping mode to use in the converted metafile.

hdcRef

Identifies the reference device.

Return Value

If the function succeeds and the buffer pointer is NULL, the return value is the number of bytes required to store the converted records; if the function succeeds and the buffer pointer is a valid pointer, the return value is the size of the metafile data in bytes; otherwise, it is zero.

Comments

This function converts an enhanced metafile into a Windows-format metafile so that its picture can be displayed in an application that recognizes the older format.

Windows uses the reference device context to determine the resolution of the converted metafile.

The GetWinMetaFileBits function does not invalidate the enhanced metafile handle. An application should call the DeleteEnhMetaFile function to release the handle when it is no longer needed.

Due to the limitations of the Windows-format metafile, some information can be lost in the retrieved metafile contents. For example, an original call to the PolyBezier function in the enhanced metafile may be converted into a call to the Polyline function in the Windows-format metafile, because there is no equivalent PolyBezier function in the Windows format.

Windows 3.x applications define the viewport origin and extents of a picture stored in a Windows-format metafile. As a result, the Windows-format records created by GetWinMetaFileBits do not contain the SetViewportOrg and SetViewportExt functions. However, GetWinMetaFileBits does create Windows-format records for the SetWindowExt and SetMapMode functions.

To create a scalable Windows-format metafile, specify MM_ANISOTROPIC as the fnMapMode parameter.

The upper left corner of the metafile picture is always mapped to the origin of the reference device.

See Also

»DeleteEnhMetaFile«


  GetWorldTransform

BOOL GetWorldTransform(hdc, lpXform)
HDC  hdc;   /* handle of device context */
LPXFORM  lpXform;   /* address of structure receiving transformation */

The GetWorldTransform function retrieves the current world-space to page-space transformation.

Parameters

hdc

Identifies the device context.

lpXform

Points to an XFORM structure that receives the current world-space to page-space transformation. The XFORM structure has the following form:

typedef struct  tagXFORM {  /* xfrm */

    FLOAT eM11;

    FLOAT eM12;

    FLOAT eM21;

    FLOAT eM22;

    FLOAT eDx;

    FLOAT eDy;

} XFORM;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The precision of the transformation may be altered if an application calls the ModifyWorldTransform function prior to calling GetWorldTransform. (This is because the internal format for storing transformation values uses a higher precision than a FLOAT value.)

See Also

»ModifyWorldTransform«, »SetWorldTransform«


  GlobalAddAtom

ATOM GlobalAddAtom(lpszName)
LPCTSTR  lpszName;   /* address of string to add */

The GlobalAddAtom function adds a character string to the global atom table and returns a unique value (an atom) identifying the string.

Parameters

lpszName

Points to the null-terminated string to be added. Strings that differ only in case are considered identical. The case of the first string of this name added to the table is preserved and returned by the GlobalGetAtomName function.

Return Value

If the function succeeds, the return value is the newly created atom; otherwise, the return value is zero. To get extended error information, use the GetLastError function.

Comments

If the string already exists in the global atom table, the atom for the existing string is returned and the atom's reference count is incremented.

The string associated with the atom is not deleted from memory until its reference count is zero. For more information, see the description of the »GlobalDeleteAtom« function.

Global atoms are not deleted automatically when the application terminates. For every call to the GlobalAddAtom function, there must be a corresponding call to the GlobalDeleteAtom function.

GlobalAddAtom returns a string atom whose value is in the range 0xC000 through 0xFFFF.

If the lpszName parameter has the form "#1234", GlobalAddAtom returns an integer atom whose value is the 16-bit representation of the decimal number specified in the string (0x04D2, in this example). If the decimal value specified is 0x0000 or a value in the range 0xC000 through 0xFFFF, the return value is zero, indicating an error. If lpszName is in the range 0x0001 through 0xBFFF, the return value is the low-order word of lpszName.

The MAKEINTATOM macro can be used to convert a WORD value into a string that can be added to the atom table by using the GlobalAddAtom function.

See Also

»AddAtom«, »DeleteAtom«, »FindAtom«, »GetAtomName«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«, »GlobalGetAtomName«, »MAKEINTATOM«


  GlobalAlloc

HGLOBAL GlobalAlloc(fuFlags, cbBytes)
UINT  fuFlags;   /* object allocation attributes */
DWORD  cbBytes;   /* number of bytes to allocate */

The GlobalAlloc function allocates the specified number of bytes from the heap. In the linear Win32 API environment, there is no difference between the local heap and the global heap.

Parameters

fuFlags

Specifies how to allocate memory. If zero is specified, the default is GMEM_FIXED. Except for the incompatible combinations that are specifically noted, any combination of the following flags can be used. To indicate whether the function allocates fixed or movable memory, specify one of the first four flags:

Value	Meaning
GMEM_FIXED
	Allocates fixed memory. This flag cannot be combined with the GMEM_MOVEABLE or GMEM_DISCARDABLE flag. The return value is a pointer to the memory block. To access the memory, the calling process simply casts the return value to a pointer.
GMEM_MOVEABLE
	Allocates movable memory. This flag cannot be combined with the GMEM_FIXED flag. The return value is the handle of the memory object. The handle is a 32-bit quantity that is private to the calling process. To translate the handle into a pointer, use the GlobalLock function.
GPTR
	Combines the GMEM_FIXED and GMEM_ZEROINIT flags.
GHND
	Combines the GMEM_MOVEABLE and GMEM_ZEROINIT flags.
GMEM_DDESHARE
	Allocates memory to be used by the dynamic data exchange (DDE) functions for a DDE conversation. Unlike Windows versions 3.x, this memory is not shared globally. However, this flag is available for compatibility purposes. It may be used by some implementations to enhance the performance of DDE operations and it should, therefore, be set if the memory is to be used for DDE.
	Only processes that use DDE or the clipboard for interprocess communications should specify this flag.
GMEM_DISCARDABLE
	Allocates discardable memory. This flag cannot be combined with the GMEM_FIXED flag. Some Win32 implementations may ignore this flag.
GMEM_LOWER
	Ignored. This flag is provided only for compatibility with Windows versions 3.x.
GMEM_NOCOMPACT
	Does not compact or discard memory to satisfy the allocation request.
GMEM_NODISCARD
	Does not discard memory to satisfy the allocation request.
GMEM_NOT_BANKED
	Ignored. This flag is provided only for compatibility with Windows versions 3.x.
GMEM_NOTIFY
	Ignored. This flag is provided only for compatibility with Windows versions 3.x.
GMEM_SHARE
	Same as the GMEM_DDESHARE flag.
GMEM_ZEROINIT
	Initializes memory contents to zero.
cbBytes

Specifies the number of bytes to allocate. If cbBytes is zero and the fuFlags parameter specifies the GMEM_MOVEABLE flag, this function returns a handle to a memory object that is marked as discarded.

Return Value

If the function succeeds, the return value is the handle of the newly allocated memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

If the heap does not contain sufficient free space to satisfy the request, this function returns NULL.

Because NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a NULL pointer.

All memory is created with execute access; no special function is required to execute dynamically generated code.

Memory allocated with this function is guaranteed to be aligned on a 16-byte boundary.

GlobalAlloc and LocalAlloc are limited to a combined total of 65,536 handles for GMEM_MOVEABLE and LMEM_MOVEABLE memory per process. This limitation does not apply to GMEM_FIXED or LMEM_FIXED memory.

If this function succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the GlobalSize function.

See Also

»GlobalFree«, »GlobalLock«, »GlobalReAlloc«, »GlobalSize«, »LocalAlloc«


  GlobalCompact

The GlobalCompact function is obsolete.


  GlobalDeleteAtom

ATOM GlobalDeleteAtom(atm)
ATOM  atm;   /* atom to delete */

The GlobalDeleteAtom function decrements the reference count of a global string atom. If the atom's reference count reaches zero, GlobalDeleteAtom removes the string associated with the atom from the global atom table.

Parameters

atm

Identifies the atom and character string to be deleted.

Return Value

If the function succeeds, the return value is zero; otherwise, it is the value of the atm parameter. To get extended error information, use the GetLastError function.

Comments

A string atom's reference count specifies the number of times the string has been added to or removed from the atom table. The GlobalAddAtom function increments the reference count of a string that already exists in the global atom table each time it is called.

The only way to ensure that an atom has been deleted from the atom table is to call this function repeatedly until it fails. When the reference count is decremented to zero, the next GlobalFindAtom or GlobalDeleteAtom function call fails.

GlobalDeleteAtom has no effect on an integer atom (an atom created by using the MAKEINTATOM macro). The function always returns zero for an integer atom.

See Also

»AddAtom«, »DeleteAtom«, »FindAtom«, »GlobalAddAtom«, »GlobalFindAtom«, »MAKEINTATOM«


  GlobalDiscard

HGLOBAL GlobalDiscard(hglbMem)
HGLOBAL  hglbMem;   /* handle of global memory object */

The GlobalDiscard function discards the specified global memory block. The lock count of the memory object must be zero.

Parameters

hglbMem

Identifies the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Value

If the function succeeds, the return value is the handle of the memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The GlobalDiscard function discards only global objects that the calling process allocated with the GMEM_DISCARDABLE flag set. If a process attempts to discard a fixed or locked object, the function fails.

Although GlobalDiscard discards the object's memory block, the handle of the object remains valid. A process can subsequently pass the handle to the GlobalReAlloc function to allocate another global memory block identified by the same handle.

See Also

»GlobalReAlloc«


  GlobalDosAlloc

The GlobalDosAlloc function has been deleted.


  GlobalDosFree

The GlobalDosFree function has been deleted.


  GlobalFindAtom

ATOM GlobalFindAtom(lpszString)
LPCTSTR  lpszString;   /* address of string to find */

The GlobalFindAtom function searches the global atom table for the specified character string and retrieves the global atom associated with that string.

Parameters

lpszString

Points to the null-terminated character string to search for.

Return Value

If the function succeeds, the return value is the global atom associated with the given string. Otherwise, the return value is zero. To get extended error information, use the GetLastError function.

Comments

Even though Windows preserves the case of a string in an atom table as it was originally entered, the search performed by GlobalFindAtom is not case sensitive.

See Also

»AddAtom«, »DeleteAtom«, »FindAtom«, »GetAtomName«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalGetAtomName«


  GlobalFix

The GlobalFix function is obsolete.


  GlobalFlags

UINT GlobalFlags(hglbMem)
HGLOBAL  hglbMem;   /* handle of global memory object */

The GlobalFlags function returns information about the specified global memory object.

Parameters

hglbMem

Identifies the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Value

If the function succeeds, the return value is a 32-bit value specifying the allocation flags and the lock count for the memory object; otherwise, it is the GMEM_INVALID_HANDLE flag, indicating that the global handle is not valid. To get extended error information, use the GetLastError function.

Comments

The low-order byte of the low-order word of the return value contains the lock count of the object. To retrieve the lock count from the return value, use the GMEM_LOCKCOUNT mask with the bitwise AND operator (&). The lock count of memory objects allocated with the GMEM_FIXED flag is always zero.

The high-order byte of the low-order word of the return value indicates the allocation flags of the memory object. It can be zero or any combination of the following flags:

Value	Meaning
GMEM_DDESHARE	Memory was allocated for use by the dynamic data exchange (DDE) functions. Unlike Windows versions 3.x, this memory is not shared globally. However, this flag is available for compatibility purposes and may be used by some implementations to enhance the performance of DDE operations. Only processes that use DDE or the clipboard for interprocess communication should specify this flag.
GMEM_DISCARDABLE	The object's memory block can be discarded.
GMEM_DISCARDED	The object's memory block has been discarded.
See Also

»GlobalAlloc«, »GlobalDiscard«, »GlobalLock«, »GlobalReAlloc«, »GlobalUnlock«, »LocalFlags«


  GlobalFree

HGLOBAL GlobalFree(hglbMem)
HGLOBAL  hglbMem;   /* handle of global memory object */

The GlobalFree function frees the specified global memory object and invalidates its handle.

Parameters

hglbMem

Identifies the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Value

If the function succeeds, the return value is NULL; otherwise, it is equal to the handle of the global memory object. To get extended error information, use the GetLastError function.

Comments

If the memory object is locked (that is, if it has a lock count that is greater than zero), the GlobalFree function fails. The GlobalLock function locks a global memory object and increments the lock count. The GlobalUnlock function unlocks it and decrements the lock count. To get the lock count of a global memory object, use the GlobalFlags function.

If the process tries to examine or modify the memory after it has been freed, heap corruption or an access violation exception (EXCEPTION_ACCESS_VIOLATION) may occur.

If the hgblMem parameter is NULL, GlobalFree fails and the system generates an access violation exception.

See Also

»GlobalAlloc«, »GlobalFlags«, »GlobalLock«, »GlobalReAlloc«, »GlobalUnlock«


  GlobalGetAtomName

UINT GlobalGetAtomName(atm, lpszBuffer, cchBuffer)
ATOM  atm;   /* atom identifier */
LPTSTR  lpszBuffer;   /* address of buffer for atom string */
int  cchBuffer;   /* size of buffer */

The GlobalGetAtomName function retrieves a copy of the character string associated with the specified global atom.

Parameters

atm

Identifies the global atom associated with the character string to be retrieved.

lpszBuffer

Points to the buffer for the character string.

cchBuffer

Specifies the size, in characters, of the buffer.

Return Value

If the function succeeds, the return value is the length of the string copied to the buffer, in characters, not including the terminating null character. Otherwise, the return value is zero. To get extended error information, use the GetLastError function.

Comments

The string returned for an integer atom (an atom created by the MAKEINTATOM macro) is a null-terminated string in which the first character is a pound sign (#) and the remaining characters represent the unsigned integer originally passed to MAKEINTATOM.

See Also

»AddAtom«, »DeleteAtom«, »FindAtom«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«, »MAKEINTATOM«


  GlobalHandle

HGLOBAL GlobalHandle(lpvMem)
LPVOID  lpvMem;   /* address of global memory block */

The GlobalHandle function retrieves the handle associated with the specified pointer to a global memory block.

Parameters

lpvMem

Points to the first byte of the global memory block. This pointer is returned by the GlobalLock function.

Return Value

If the function succeeds, the return value is the handle of the specified global memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

When the GlobalAlloc function allocates a memory object with the GMEM_MOVEABLE flag, it returns the handle of the object. The GlobalLock function converts this handle into a pointer to the memory block, and GlobalHandle converts the pointer back into a handle.

See Also

»GlobalAlloc«, »GlobalLock«


  GlobalLock

LPVOID GlobalLock(hglbMem)
HGLOBAL  hglbMem;   /* handle of global memory object */

The GlobalLock function locks a global memory object and returns a pointer to the first byte of the object's memory block. The memory block associated with a locked memory object cannot be moved or discarded. For memory objects allocated with the GMEM_MOVEABLE flag, the function increments the lock count associated with the memory object.

Parameters

hglbMem

Identifies the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Value

If the function succeeds, the return value is a pointer to the first byte of the memory block; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, GlobalLock increments this count by one, and the GlobalUnlock function decrements the count by one. For each call that a process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the GMEM_FIXED flag always have a lock count of zero. For these objects, the value of the returned pointer is equal to the value of the specified handle.

If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL.

Discarded objects always have a lock count of zero.

See Also

»GlobalFlags«, »GlobalReAlloc«, »GlobalUnlock«


  GlobalLRUNewest

The GlobalLRUNewest function is obsolete.


  GlobalLRUOldest

The GlobalLRUOldest function is obsolete.


  GlobalMemoryStatus

VOID GlobalMemoryStatus(lpmstMemStat)
LPMEMORYSTATUS  lpmstMemStat;   /* address of memory status structure */

The GlobalMemoryStatus function retrieves information about current available memory. The function returns information about both physical and virtual memory.

Parameters

lpmstMemStat

Points to a MEMORYSTATUS structure in which the information about current memory availability is returned. Before calling this function, the calling process should set the dwLength member of this structure. The MEMORYSTATUS structure has the following form:

typedef struct _MEMORYSTATUS { /* mst */

    DWORD dwLength;        /* sizeof(MEMORYSTATUS)        */

    DWORD dwMemoryLoad;    /* percent of memory in use    */

    DWORD dwTotalPhys;     /* bytes of physical memory    */

    DWORD dwAvailPhys;     /* free physical memory bytes  */

    DWORD dwTotalPageFile; /* bytes of paging file        */

    DWORD dwAvailPageFile; /* free bytes of paging file   */

    DWORD dwTotalVirtual;  /* user bytes of address space */

    DWORD dwAvailVirtual;  /* free user bytes             */

} MEMORYSTATUS, *LPMEMORYSTATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function does not return a value.

Comments

An application can use the GlobalMemoryStatus function to determine how much memory it can allocate without severely impacting other applications.

The information returned is volatile, and there is no guarantee that two sequential calls to this function will return the same information.


  GlobalNotify

The GlobalNotify function has been deleted. Win32 applications should use the GlobalFlags function.

See Also

»GlobalFlags«


  GlobalPageLock

The GlobalPageLock function has been deleted. Win32 applications should use the VirtualLock and VirtualUnlock functions.

See Also

»VirtualLock«, »VirtualUnlock«


  GlobalPageUnlock

The GlobalPageUnlock function has been deleted. Win32 applications should use the VirtualLock and VirtualUnlock functions.

See Also

»VirtualLock«, »VirtualUnlock«


  GlobalReAlloc

HGLOBAL GlobalReAlloc(hglbMem, cbBytes, fuFlags)
HGLOBAL  hglbMem;   /* handle of global memory object */
DWORD  cbBytes;   /* new size of block */
UINT  fuFlags;   /* how to reallocate object */

The GlobalReAlloc function changes the size or attributes of a specified global memory object. The size can increase or decrease.

Parameters

hglbMem

Identifies the global memory object to be reallocated. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

cbBytes

Specifies the new size, in bytes, of the memory block. If cbBytes is zero and the fuFlags parameter specifies the GMEM_MOVEABLE flag, this function returns the handle of a memory object that is marked as discarded. If the fuFlags parameter specifies the GMEM_MODIFY flag, this parameter is ignored.

fuFlags

Specifies how to reallocate the global memory object. If the GMEM_MODIFY flag is specified, this parameter modifies the attributes of the memory object, and the cbBytes parameter is ignored. Otherwise, this parameter controls the reallocation of the memory object.

The GMEM_MODIFY flag can be combined with either or both of the following flags:

Flag	Meaning
GMEM_DISCARDABLE
	This flag allocates discardable memory. This flag is used only if the GMEM_MODIFY flag is also specified. This flag is ignored, unless the object was previously allocated as movable, or the GMEM_MOVEABLE flag is also specified.
GMEM_MOVEABLE
	This flag changes a fixed memory object to a movable memory object, if the GMEM_MODIFY flag is also specified.
If fuFlags does not specify GMEM_MODIFY, the parameter can be any combination of the following flags:

Flag	Meaning
GMEM_MOVEABLE
	If cbBytes is zero, this flag discards a previously movable and discardable memory block. If the lock count of the object is not zero, or if the block is not movable and discardable, the function fails.
	If cbBytes is nonzero, this flag enables the system to move the reallocated block to a new location. This does not change the movable or fixed attribute of the memory object. If the object is fixed, the handle returned may be different from the handle specified by the hglbMem parameter. If the object is movable, the block can be moved without invalidating the handle. This can occur even if the object is currently locked by a previous call to the GlobalLock function. To get the new address of the memory block, use GlobalLock.
GMEM_NOCOMPACT
	This flag prevents memory from being compacted or discarded to satisfy the allocation request.
GMEM_ZEROINIT
	This flag causes the additional memory contents to be initialized to zero, if the memory object is growing in size.
Return Value

If the function succeeds, the return value is the handle of the reallocated memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

If GlobalReAlloc reallocates a movable object, the return value is the handle of the memory object. To convert the handle to a pointer, use the GlobalLock function.

If GlobalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the memory block. To access the memory, a process can simply cast the return value to a pointer.

See Also

»GlobalAlloc«, »GlobalFree«, »GlobalLock«


  GlobalSize

DWORD GlobalSize(hglbMem)
HGLOBAL  hglbMem;   /* handle of global memory object */

The GlobalSize function retrieves the current size, in bytes, of the specified global memory object.

Parameters

hglbMem

Identifies the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Value

If the function succeeds, the return value is the size, in bytes, of the specified global memory object. If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error information, use the GetLastError function.

Comments

The size of a memory block may be larger than the size requested when the memory was allocated.

To verify that the specified object's memory block has not been discarded, call the GlobalFlags function before calling GlobalSize.

See Also

»GlobalAlloc«, »GlobalFlags«, »GlobalReAlloc«


  GlobalUnfix

The GlobalUnfix function is obsolete.


  GlobalUnlock

BOOL GlobalUnlock(hglbMem)
HGLOBAL  hglbMem;   /* handle of global memory object */

The GlobalUnlock function decrements the lock count associated with a memory object that was allocated with the GMEM_MOVEABLE flag. This function has no effect on memory objects allocated with the GMEM_FIXED flag.

Parameters

hglbMem

Identifies the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Value

If the object's lock count was decremented to zero, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the GlobalLock function increments this count by one, and GlobalUnlock decrements the count by one. For each call that a process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the GMEM_FIXED flag always have a lock count of zero. If the specified memory block is fixed memory, this function returns TRUE.

A process should not rely on the return value to determine the number of times it must subsequently call GlobalUnlock for a memory object.

See Also

»GlobalFlags«, »GlobalLock«


  GlobalUnWire

The GlobalUnWire function is obsolete. Applications that need to lock a global memory object should use the GlobalLock and GlobalUnlock functions.

This function is provided in Win32 only for compatibility with earlier versions of Windows. New Win32 applications should not use this function.

See Also

»GlobalLock«, »GlobalUnlock«


  GlobalWire

The GlobalWire function is obsolete. Win32 applications should use the GlobalLock and GlobalUnlock functions.

See Also

»GlobalLock«, »GlobalUnlock«


  GrayString

BOOL GrayString(hdc, hbr, lpOutputFunc, lParam, nCount, X, Y, nWidth, nHeight)
HDC  hdc;   /* handle of device context */
HBRUSH  hbr;   /* handle of brush for graying */
GRAYSTRINGPROC  lpOutputFunc;   /* address of callback function */
LPARAM  lParam;   /* address of application-defined data */
int  nCount;   /* number of characters to output */
int  X;   /* horizontal position */
int  Y;   /* vertical position */
int  nWidth;   /* width */
int  nHeight;   /* height */

The GrayString function draws gray text at the given location. The function draws the text by copying it into a memory bitmap, graying the bitmap, and then copying the bitmap to the screen. The function grays the text regardless of the selected brush and background. GrayString uses the font currently selected for the given device context (DC).

If the lpOutputFunc parameter is NULL, GDI uses the TextOut function, and the lParam parameter is assumed to be a pointer to the character string to be output. If the characters to be output cannot be handled by TextOut (for example, the string is stored as a bitmap), the application must supply its own output function.

Parameters

hdc

Identifies the DC.

hbr

Identifies the brush to be used for graying. If this parameter is NULL, the text is grayed with the same brush that was used to draw window text.

lpOutputFunc

Points to the application-defined function that will draw the string, or, if TextOut is to be used to draw the string, it is a NULL pointer. For details, see the description of the »OutputProc« callback function.

lParam

Specifies a pointer to data to be passed to the output function. If the lpOutputFunc parameter is NULL, lParam must be a pointer to the string to be output.

nCount

Specifies the number of characters to be output. If the nCount parameter is zero, GrayString calculates the length of the string (assuming lParam is a pointer to the string). If nCount is −1 and the function pointed to by lpOutputFunc returns FALSE, the image is shown but not grayed.

X

Specifies the device x-coordinate of the starting position of the rectangle that encloses the string.

Y

Specifies the device y-coordinate of the starting position of the rectangle that encloses the string.

nWidth

Specifies the width, in device units, of the rectangle that encloses the string. If this parameter is zero, GrayString calculates the width of the area, assuming lParam is a pointer to the string.

nHeight

Specifies the height, in device units, of the rectangle that encloses the string. If this parameter is zero, GrayString calculates the height of the area, assuming lParam is a pointer to the string.

Return Value

If the string is drawn, the return value is TRUE. If the return value is FALSE, either the TextOut function or the application-defined output function returned FALSE, or there was insufficient memory to create a memory bitmap for graying.

Comments

Without calling GrayString, an application can draw grayed strings on devices that support a solid gray color. The system color COLOR_GRAYTEXT is the solid-gray system color used to draw disabled text. The application can call the GetSysColor function to retrieve the color value of COLOR_GRAYTEXT. If the color is other than zero (black), the application can call the SetTextColor function to set the text color to the color value and then draw the string directly. If the retrieved color is black, the application must call GrayString to gray the text.

See Also

»DrawText«, »GetSysColor«, »SetTextColor«, »TabbedTextOut«, »TextOut«


Introduction
Programmer's Reference, Volume 4: Functions H-Z

Introduction

The Microsoft® Win32™ application programming interface (API) allows applications to exploit the power of 32-bits on the Microsoft® Windows™ family of operating systems. Applications written to the Win32 API are scalable on single and multiprocessor systems, and portable to RISC architectures. These manuals document the complete Win32 API including window management, graphics, file I/O, threading, memory management, security and networking.

This manual describes the Win32 API in alphabetic order (H through Z). Each description includes the function's syntax, purpose, parameters, and possible return values. Many descriptions also contain additional information, including whether the function supports Unicode™ or whether it is new, obsolete, or has been deleted.


About the Microsoft Win32 Programmers Reference
  About the Microsoft Win32 Programmer's Reference

The Microsoft Win32 Programmer's Reference, a set of five volumes, fully describes the Win32 API, including functions and related data types, macros, structures, and messages. The Programmer's Reference is the source for specific information about programming for Windows.

Volumes 1 and 2 describe the purpose of the functions in the Win32 API and explains the concepts and principles behind the functions. These volumes are intended for programmers who are new to Windows or who are learning parts of it for the first time. These two volumes provide the basic information needed for an understanding of Windows programming.

Volumes 3 and 4 consist of an alphabetic listing of the Win32 functions. These volumes define the details of the syntax, parameters, and return values of each function. Volume 5 contains alphabetical listings of the Win32 data types, macros, messages, and structures. Volumes 3 through 5 are intended for programmers already acquainted with Windows programming and who need only specifics of particular functions.


  Microsoft Windows and the C Programming Language

The C programming language is the preferred development language for Windows-based applications. Many of the programming features of Windows were designed with C in mind. Windows-based applications can also be developed in other languages, but C is the most straightforward and easiest language to use to access Windows functions. For this reason, all syntax and program samples are written in the C programming language.

The Win32 API uses many types, macros, and structures that are not part of standard C language. These types, macros, and structures have been defined to make the task of creating Windows-based applications simpler and to make application sources clearer and easier to understand. All types, macros, and structures discussed in this manual are defined in the Win32 C-language header files.


  Document Conventions

The following conventions are used throughout this manual to define syntax.

Convention	Meaning
Bold text	Denotes a term or character to be typed literally, such as a predefined data type or function name (HWND or CreateWindowEx), a command, or a command-line option (/x). You must type these terms exactly as shown.
Italic text	Denotes a placeholder or variable: You must provide the actual value. For example, the statement SetCursorPos(X,Y) requires you to substitute values for the X and Y parameters.
[ ]	Enclose optional parameters.
|	Separates an either/or choice.
...	Specifies that the preceding item may be repeated.
.	Represents an omitted portion of a sample application.
.
.
In addition, certain text conventions are used to help you understand this material.

Convention	Meaning
SMALL CAPITALS	Indicate the names of keys, key sequences, and key combinations — for example, ALT+SPACEBAR.
FULL CAPITALS	Indicate filenames and paths, most type and structure names (which are also bold), and constants.
monospace	Sets off code examples and shows syntax spacing.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Programmer's Reference, Volume 4:
Functions H-Z


  Handler

VOID Handler(fdwControl)
DWORD  fdwControl;   /* requested control code */

A Handler function is a function that a service process specifies as the control handling function of a particular service. The function can have any application-defined name.

Parameters

fdwControl

Indicates the requested control code. This value can be one of the standard control codes in the table, or it can be a user-defined control code in the range of 128 to 255, inclusive. For user-defined control codes, the service defines the action associated with the control code.

Value	Meaning
SERVICE_CONTROL_STOP
	Requests the service to stop.
SERVICE_CONTROL_PAUSE
	Requests the service to pause.
SERVICE_CONTROL_CONTINUE
	Requests the paused service to resume.
SERVICE_CONTROL_INTERROGATE
	Requests the service to immediately report its current status information to the service control manager.
SERVICE_CONTROL_SHUTDOWN
	Requests the service to perform cleanup tasks, because the system is shutting down. Due to extremely limited time available for shutdown, this control should only be used by services that absolutely need to shut down —  for instance, if the eventlog service needs to clear a dirty bit in the files that it maintains, or if the server service needs to shutdown so that network connections made when the system is in the shut down state.
	If the service takes time to shut down, and sends out STOP_PENDING status messages, it is highly recommended that these messages include a waithint so that the service controller will know how long to wait before indicating to the system that service shutdown is complete. The system gives the service control manager a limited amount of time (about 20 seconds) to complete service shutdown, after which time system shutdown proceeds regardless of whether service shutdown is complete.
Return Value

This function does not return a value.

Comments

When a Win32 service is started, its Service Main function should immediately call the RegisterServiceCtrlHandler function to specify a Handler function to handle control requests.

Whenever it receives a control request from the service control manager, the control dispatcher in the main thread of a Win32 service process invokes the control handler function for the specified service. After handling the control request, the control handler must call the SetServiceStatus function to report its current status to the service control manager.

See Also

»RegisterServiceCtrlHandler«, »ServiceMain«, »SetServiceStatus«


  HeapAlloc

LPVOID HeapAlloc(hHeap, dwFlags, dwBytes)
HANDLE  hHeap;   /* handle of the private heap block */
DWORD  dwFlags;   /* heap allocation control flags */
DWORD  dwBytes;   /* number of bytes to allocate */

The HeapAlloc function allocates a block of memory from a heap. The allocated memory is not movable.

Parameters

hHeap

Specifies the heap within which the memory shall be allocated. This is a handle returned by the HeapCreate or the GetProcessHeap function.

dwFlags

Specifies several controllable aspects of heap allocation. Specifying any of these flags will override the corresponding flag specified when the heap was created with the HeapCreate function. You can use one or more of the following values:

Value	Meaning
HEAP_GENERATE_EXCEPTIONS	Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE	Specifies that mutual exclusion will not be used while this function is accessing the heap. For more information about HEAP_NO_SERIALIZE, see the Comments for the »HeapCreate« function.
HEAP_ZERO_MEMORY	Specifies that the allocated memory will be initialized to zero.
dwBytes

Specifies the number of bytes to be allocated.

Return Value

If the function succeeds, the return value is a pointer to the allocated memory block.

If the function fails, and HEAP_GENERATE_EXCEPTIONS has NOT been set, the return value is NULL.

If the function fails, and HEAP_GENERATE_EXCEPTIONS has been set, the following exception values can be generated :

Value	Meaning
STATUS_NO_MEMORY	The allocation attempt failed for lack of available memory.
STATUS_ACCESS_VIOLATION	The allocation attempt failed because of heap corruption or improper function parameters.
Comments

If the HeapAlloc function succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the allocated block, use the HeapSize function.

To free a block of memory allocated by HeapAlloc, use the HeapFree function.

Memory allocated by HeapAlloc is not movable. Since the memory is not movable, it is possible for the heap to become fragmented.

Note that, if HEAP_ZERO_MEMORY is not specified, the allocated memory will not be initialized to zero.

See Also

»HeapCreate«, »HeapDestroy«, »HeapFree«, »HeapReAlloc«, »HeapSize«


  HeapCreate

HANDLE HeapCreate(flOptions, dwInitialSize, dwMaximumSize)
DWORD  flOptions;   /* heap allocation flag */
DWORD  dwInitialSize;   /* initial heap size */
DWORD  dwMaximumSize;   /* maximum heap size */

The HeapCreate function creates a heap object that is private to the calling process. This reserves a contiguous block of the process's virtual address space and allocates physical storage for a specified initial portion of this block.

Parameters

flOptions

Specifies optional attributes for the new heap. These flags will affect subsequent access to the new heap via calls to the HeapAlloc, HeapFree, HeapReAlloc, and HeapSize functions. You can specify one or more of the following values:

Value	Meaning
HEAP_GENERATE_EXCEPTIONS	Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE	Specifies that mutual exclusion will not be used when the Heap functions allocate and free memory from this heap. The default, occurring when the HEAP_NO_SERIALIZE flag is not specified, is to serialize access to the heap. Serializing heap access allows two or more threads to simultaneously allocate and free memory from the same heap.
dwInitialSize

Specifies the initial size, in bytes, of the heap. This value determines the initial amount of physical storage that is allocated for the heap. The value is rounded up to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.

dwMaximumSize

Specifies the maximum size, in bytes, of the heap. This value determines the size of the block in the process's virtual address space that is reserved. The value is rounded up to the next page boundary. If allocation requests made by the HeapAlloc function exceed the initial amount of physical storage specified by the dwInitialSize parameter, additional pages of physical storage are allocated for the heap, up to this maximum limit. If this parameter is zero, the size of the heap is limited by available memory.

Return Value

If the function succeeds, the return value is a handle of the newly created heap; otherwise, it is NULL.

Comments

The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. The initial size determines the number of committed pages that are initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a contiguous block in the process's virtual address space into which the heap can grow. If requests by the HeapAlloc function exceed the current size of committed pages, additional pages are automatically committed from this reserved space, assuming that the physical storage is available.

The memory of a private heap object is accessible only to the process that created it. If a dynamic-link library (DLL) creates a private heap, the heap is created in the address space of the process that invoked the DLL, and it is accessible only to that process.

The system uses memory from the private heap to store heap support structures, so not all of the specified heap size is available to the process. For example, if the HeapAlloc function requests 64 kilobytes from a heap with a maximum size of 64K, the request may fail because of the system overhead.

If the HEAP_NO_SERIALIZE flag is not specified, the simple default, the heap will serialize access within the calling process. This ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap.

Setting the HEAP_NO_SERIALIZE flag eliminates this mutual exclusion on the heap. Lacking serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. Thus, the HEAP_NO_SERIALIZE flag can be safely used only in the following situations:

•	The process has only one thread.

•	The process has multiple threads, but only one thread calls the heap functions for a specific heap.

•	The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

See Also

»HeapAlloc«, »HeapDestroy«, »HeapFree«, »HeapReAlloc«, »HeapSize«, »GetProcessHeap«


  HeapDestroy

BOOL HeapDestroy(hHeap)
HANDLE  hHeap;   /* handle of heap */

The HeapDestroy function destroys the specified heap object.

Parameters

hHeap

Specifies the heap to be destroyed. This should be a heap handle returned by the HeapCreate function. Do not use a heap handle returned by the GetProcessHeap function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The HeapDestroy function decommits and releases all the pages of a private heap object, and invalidates the handle of the heap.

Processes can call HeapDestroy without first calling the HeapFree function to free memory allocated from the heap.

See Also

»HeapAlloc«, »HeapCreate«, »HeapFree«, »HeapReAlloc«, »HeapSize«, »GetProcessHeap«


  HeapFree

BOOL HeapFree(hHeap, dwFlags, lpMem)
HANDLE  hHeap;   /* handle of the heap */
DWORD  dwFlags;   /* heap freedom flags */
LPVOID  lpMem;   /* address of the memory to free */

The HeapFree function frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.

Parameters

hHeap

Specifies the heap whose block the function frees. This is a handle returned by the HeapCreate or the GetProcessHeap function.

dwFlags

Specifies several controllable aspects of freeing a memory block. Only one flag is currently defined; however, all other flag values are reserved for future use. Specifying this flag will override the corresponding flag specified when the heap was created with the HeapCreate function:

Value	Meaning
HEAP_NO_SERIALIZE	Specifies that mutual exclusion will not be used while this function is accessing the heap. For more information about HEAP_NO_SERIALIZE, see the Comments for the »HeapCreate« function.
lpMem

Points to the memory block to free. This is a pointer returned by the HeapAlloc function or the HeapReAlloc function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»HeapAlloc«, »HeapCreate«, »HeapDestroy«, »HeapReAlloc«, »HeapSize«, »GetProcessHeap«


  HeapReAlloc

LPVOID HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes)
HANDLE  hHeap;   /* handle of a heap block */
DWORD  dwFlags;   /* flags specifying aspects of reallocation */
LPVOID  lpMem;   /* address of the memory to reallocate  */
DWORD  dwBytes;   /* number of bytes to reallocate */

The HeapReAlloc function re-allocates a block of memory from a heap. The allocated memory is not movable.

Parameters

hHeap

Specifies the heap within which the memory shall be re-allocated. This is a handle returned by the HeapCreate or the GetProcessHeap function.

dwFlags

Specifies several controllable aspects of heap re-allocation. Specifying any of these flags will override the corresponding flag specified when the heap was created with the HeapCreate function. You can use one or more of the following values:

Value	Meaning
HEAP_GENERATE_EXCEPTIONS	Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE	Specifies that mutual exclusion will not be used while this function is accessing the heap. For more information about HEAP_NO_SERIALIZE, see the Comments for the »HeapCreate« function.
HEAP_REALLOC_IN_PLACE_ONLY	Specifies that there can be no movement when re-allocating a memory block to a larger size. If this flag is not specified, and the re-allocation request is for a larger size, the HeapReAlloc function may move the block to a new location. If this flag is specified, and the block cannot be enlarged without moving, the function will fail, leaving the original memory block unchanged.
HEAP_ZERO_MEMORY	If the re-allocation request is for a larger size, this flag specifies that the additional region of memory beyond the original size will be initialized to zero. The contents of the memory block up to its original size are unaffected.
lpMem

Points to the block of memory that the function will re-allocate. This pointer is returned by a prior call to the HeapAlloc function or the HeapReAlloc function.

dwBytes

Specifies the new size of the memory block in bytes. A memory block's size may be increased or decreased with this function.

Return Value

If the function succeeds, the return value is a pointer to the re-allocated memory block.

If the function fails, and HEAP_GENERATE_EXCEPTIONS has NOT been set, the return value is NULL.

If the function fails, and HEAP_GENERATE_EXCEPTIONS has been set, the following exception values can be generated :

Value	Meaning
STATUS_NO_MEMORY	The re-allocation attempt failed for lack of available memory.
STATUS_ACCESS_VIOLATION	The re-allocation attempt failed because of heap corruption or improper function parameters.
Comments

If the HeapReAlloc function succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the re-allocated block, use the HeapSize function.

To free a block of memory allocated by HeapReAlloc, use the HeapFree function.

See Also

»HeapAlloc«, »HeapCreate«, »HeapDestroy«, »HeapFree«, »HeapSize«, »GetProcessHeap«


  HeapSize

DWORD HeapSize(hHeap, dwFlags, lpMem)
HANDLE  hHeap;   /* handle of the heap */
DWORD dwFlags  ;   /* heap size control flags */
LPSTR  lpMem;   /* address of memory to return size for */

The HeapSize function returns the size, in bytes, of a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.

Parameters

hHeap

Specifies the heap within which the memory block whose size is desired resides. This is a handle returned by the HeapCreate function or the GetProcessHeap function.

dwFlags

Specifies several controllable aspects of accessing a memory block. Only one flag is currently defined; however, all other flag values are reserved for future use. Specifying this flag will override the corresponding flag specified when the heap was created with the HeapCreate function:

Value	Meaning
HEAP_NO_SERIALIZE	Specifies that mutual exclusion will not be used while this function is accessing the heap. For more information about HEAP_NO_SERIALIZE, see the Comments for the »HeapCreate« function.
lpMem

Points to the memory block whose size the function will obtain. This is a pointer returned by the HeapAlloc function or the HeapReAlloc function.

Return Value

If the function succeeds, the return value is the size, in bytes, of the allocated memory block; otherwise, it is zero.

See Also

»HeapAlloc«, »HeapCreate«, »HeapDestroy«, »HeapFree«, »HeapReAlloc«, »GetProcessHeap«


  HideCaret

BOOL HideCaret(hwnd)
HWND  hwnd;   /* handle of window with caret */

The HideCaret function removes the caret from the screen. Hiding the caret does not destroy its current shape or invalidate the insertion point.

Parameters

hwnd

Identifies the window that owns the caret. If this parameter is NULL, HideCaret searches the current task for the window that owns the caret.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

HideCaret hides the caret only if the given window owns the caret. If the given window does not own the caret, HideCaret does nothing and returns FALSE.

Hiding is cumulative. If your application calls HideCaret five times in a row, it must also call ShowCaret five times before the caret is displayed.

See Also

»CreateCaret«, »DestroyCaret«, »GetCaretPos«, »SetCaretPos«, »ShowCaret«


  HiliteMenuItem

BOOL HiliteMenuItem(hwnd, hmenu, uItemHilite, uHilite)
HWND  hwnd;   /* handle of window with menu */
HMENU  hmenu;   /* handle of menu */
UINT  uItemHilite;   /* menu item to highlight or unhighlight  */
UINT  uHilite;   /* highlight flags */

The HiliteMenuItem function highlights or removes the highlighting from an item in a menu bar.

Parameters

hwnd

Identifies the window that contains the menu.

hmenu

Identifies the menu bar that contains the item to be highlighted.

uItemHilite

Specifies the menu item to be highlighted. This parameter is either the identifier of the menu item or the offset of the menu item in the menu bar, depending on the value of the uHilite parameter.

uHilite

Specifies flags that control the interpretation of the uItemHilite parameter and indicates whether the menu item is highlighted. This parameter must be a combination of either MF_BYCOMMAND or MF_BYPOSITION and MF_HILITE or MF_UNHILITE.

Value	Meaning
MF_BYCOMMAND	Indicates that the uItemHilite parameter gives the identifier of the menu item.
MF_BYPOSITION	Indicates that the uItemHilite parameter gives the zero-based relative position of the menu item.
MF_HILITE	Highlights the menu item. If this flag is not specified, the highlighting is removed from the item.
MF_UNHILITE	Removes highlighting from the menu item.
Return Value

If the menu item is set to the specified highlight state, the return value is TRUE; otherwise, it is FALSE.

Comments

The MF_HILITE and MF_UNHILITE flags can be used only with the HiliteMenuItem function; they cannot be used with the ModifyMenu function.

See Also

»ModifyMenu«


  _hread

long _hread(hFile, lpBuffer, lBytes)
HFILE  hFile;   /* handle of file */
LPVOID  lpBuffer;   /* address of buffer for read data  */
long  lBytes;   /* length, in bytes, of data buffer */

The _hread function reads data from the specified file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the ReadFile function.

Parameters

hFile

Identifies the specified file.

lpBuffer

Points to a buffer that contains the data read from the file.

lBytes

Specifies the number of bytes to read from the file.

Return Value

The return value indicates the number of bytes actually read from the file. If the number of bytes read is less than lBytes, the function has reached the end of the file (EOF) before reading the specified number of bytes. If the function fails, the return value is HFILE_ERROR. To get extended error information, use the GetLastError function.

See Also

»_hwrite«, »ReadFile«


  _hwrite

long _hwrite(hFile, lpBuffer, lBytes)
HFILE  hFile;   /* handle of file */
LPCSTR  lpBuffer;   /* address of buffer for data to be written  */
long  lBytes;   /* number of bytes to write */

The _hwrite function writes data to the specified file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the WriteFile function.

Parameters

hFile

Identifies the specified file.

lpBuffer

Points to a buffer that contains the data to write to the file.

lBytes

Specifies the number of bytes to write to the file.

Return Value

If the function succeeds, the return value indicates the number of bytes actually written to the file. Otherwise, it is HFILE_ERROR. To get extended error information, use the GetLastError function.

See Also

»_hread«, »WriteFile«


  ImpersonateDdeClientWindow

BOOL ImpersonateDdeClientWindow(hwndClient, hwndServer)
HWND  hwndClient;   /* handle of DDE client window */
HWND  hwndServer;   /* handle of DDE server window */

The ImpersonateDdeClientWindow function enables a dynamic data exchange (DDE) server application to impersonate a DDE client application's security context in order to protect secure server data from unauthorized DDE clients.

Parameters

hwndClient

Identifies the DDE client window to impersonate. The client window must have established a DDE conversation with the server window identified by the hwndServer parameter.

hwndServer

Identifies the DDE server window. An application must create the server window before calling this function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application should call the RevertToSelf function to undo the impersonation set by the ImpersonateDdeClientWindow function.

A Dynamic Data Exchange Management Library (DDEML) application should use the DdeImpersonateClient function.

See Also

»DdeImpersonateClient«, »RevertToSelf«


  ImpersonateNamedPipeClient

BOOL ImpersonateNamedPipeClient(hNamedPipe)
HANDLE  hNamedPipe;   /* handle of a named pipe */

The ImpersonateNamedPipeClient function impersonates a named-pipe client application.

Parameters

hNamedPipe

Identifies a named pipe.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ImpersonateNamedPipeClient function allows the server end of a named pipe to impersonate the client end. When this function is called, the named-pipe file system changes the thread of the calling process to start impersonating the security context of the last message read from the pipe. Only the server end of the pipe can call this function.

The server can call the RevertToSelf function when the impersonation is complete.

See Also

»DdeImpersonateClient«, »DuplicateToken«, »RevertToSelf«


  ImpersonateSelf

BOOL ImpersonateSelf(sil)
SECURITY_IMPERSONATION_LEVEL  sil;   /* impersonation level */

The ImpersonateSelf function obtains an access token that impersonates the security context of the calling process. The token is assigned to the calling thread.

Parameters

sil

Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token.

The SECURITY_IMPERSONATION_LEVEL enumerated type has the following form:

typedef enum tagSECURITY_IMPERSONATION_LEVEL { /* sil */

    SecurityAnonymous,

    SecurityIdentification,

    SecurityImpersonation,

    SecurityDelegation

} SECURITY_IMPERSONATION_LEVEL;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ImpersonateSelf function is used for tasks, such as enabling a privilege for a single thread rather than for the entire process or for changing the default discretionary access-control list for a single thread.

The server can call the RevertToSelf function when the impersonation is complete.

See Also

»DuplicateToken«, »ImpersonateNamedPipeClient«, »RevertToSelf«


  InflateRect

BOOL InflateRect(lprc, xAmt, yAmt)
LPRECT  lprc;   /* address of rectangle */
int  xAmt;   /* amount to increase or decrease width */
int  yAmt;   /* amount to increase or decrease height */

The InflateRect function increases or decreases the width and height of the specified rectangle. The InflateRect function adds xAmt units to the left and right ends of the rectangle and yAmt units to the top and bottom. The xAmt and yAmt parameters are signed values; positive values increase the width and height, and negative values decrease them.

Parameters

lprc

Points to the RECT structure that increases or decreases in size. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

xAmt

Specifies the amount to increase or decrease the rectangle width. This parameter must be negative to decrease the width.

yAmt

Specifies the amount to increase or decrease the rectangle height. This parameter must be negative to decrease the height.

Return Value

If the function is succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»IntersectRect«, »OffsetRect«, »UnionRect«


  InitAtomTable

BOOL InitAtomTable(cTableEntries)
DWORD  cTableEntries;   /* size of atom table */

The InitAtomTable function initializes the local atom table and sets it to the specified size.

Parameters

cTableEntries

Specifies the size, in table entries, of the atom table. This value should be a prime number.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

An application need not use this function to use a local atom table. The default size of the local and global atom tables is 37 table entries. If an application does use InitAtomTable, however, it should call the function before any other atom-management function.

If an application uses a large number of local atoms, it can reduce the time required to add an atom to the local atom table or to find an atom in the table by increasing the size of the table. However, this increases the amount of memory required to maintain the table.

The size of the global atom table cannot be changed.

See Also

»AddAtom«, »DeleteAtom«, »FindAtom«, »GetAtomName«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalFindAtom«, »GlobalGetAtomName«


  InitializeAcl

BOOL InitializeAcl(pAcl, cbAcl, dwAclRevision)
PACL  pAcl;   /* address of access-control list */
DWORD  cbAcl;   /* size of access-control list */
DWORD  dwAclRevision;   /* revision level of access-control list */

The InitializeAcl function creates a new ACL structure. An ACL is an access-control list.

Parameters

pAcl

Points to an ACL structure initialized by this function.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbAcl

Specifies the length, in bytes, of the buffer pointed to by the pAcl parameter. This value must be large enough to contain the ACL header and all of the access-control entries (ACEs) to be stored in the ACL.

dwAclRevision

Specifies the revision level of the ACL. This parameter must be set to the current revision level, defined as ACL_REVISION for this version of Windows.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ACL initialized by this function contains no ACEs. It is empty, as opposed to being a nonexistent ACL. If an empty ACL is applied to an object, it implicitly denies all access to that object.

See Also

»AddAccessAllowedAce«, »AddAccessDeniedAce«, »AddAce«, »AddAuditAccessAce«, »DeleteAce«, »GetAce«, »GetAclInformation«, »IsValidAcl«, »SetAclInformation«


  InitializeCriticalSection

VOID InitializeCriticalSection(lpcsCriticalSection)
LPCRITICAL_SECTION  lpcsCriticalSection;   /* address of critical section object */

The InitializeCriticalSection function initializes a critical section object.

Parameters

lpcsCriticalSection

Points to the critical section object.

Return Value

This function does not return a value.

Comments

The threads of a single process can use a critical section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection function to initialize the object.

Once a critical section object has been initialized, the threads of the process can specify the object in the EnterCriticalSection and LeaveCriticalSection functions to provide mutually exclusive access to a shared resource. For similar synchronization between the threads of different processes, use a mutex object.

A critical section object cannot be moved or copied. The process must also not modify the object, but must treat it as logically opaque. Use only the functions provided in the Win32 application programming interface to manage critical section objects.

See Also

»CreateMutex«, »DeleteCriticalSection«, »EnterCriticalSection«, »LeaveCriticalSection«


  InitializeSecurityDescriptor

BOOL InitializeSecurityDescriptor(psd, dwRevision)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor  */
DWORD  dwRevision;   /* revision level */

The InitializeSecurityDescriptor function initializes a new security descriptor.

Parameters

psd

Points to a SECURITY_DESCRIPTOR structure that the function initializes.

dwRevision

Specifies the revision level to assign to the security descriptor. This must be SECURITY_DESCRIPTOR_REVISION.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The InitializeSecurityDescriptor function initializes a security descriptor in absolute format, rather than self-relative format.

The InitializeSecurityDescriptor function initializes a security descriptor to have no system ACL, no discretionary ACL, no owner, no primary group, and all control flags set to FALSE (NULL). Thus, except for its revision level, it is empty.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorOwner«, »SetSecurityDescriptorSacl«


  InitializeSid

BOOL InitializeSid(psid, psia, cSubauthorities)
PSID  psid;   /* address of SID to initialize */
PSID_IDENTIFIER_AUTHORITY  psia;   /* address of identifier authority  */
BYTE  cSubauthorities;   /* count of subauthorities */

The InitializeSid function initializes an SID structure. An SID is a security identifier.

Parameters

psid

Points to an SID structure to be initialized.

psia

Points to an SID_IDENTIFIER_AUTHORITY structure to set in the SID structure. The SID_IDENTIFIER_AUTHORITY structure has the following form:

typedef struct _SID_IDENTIFIER_AUTHORITY { /* sia */

    BYTE Value[6];

} SID_IDENTIFIER_AUTHORITY ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cSubauthorities

Specifies the number of subauthorities to set in the SID. Values of the subauthority must be set separately, as described in the Comments section.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Although the InitializeSid function sets the number of subauthorities for the SID, it does not set the subauthority values. This must be done separately, using functions, such as GetSidSubAuthority.

An application can use the AllocateAndInitializeSid function to initialize an SID and sets its subauthority values.

See Also

»GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidLengthRequired«, »GetSidSubAuthority«, »GetSidSubAuthorityCount«, »IsValidSid«


  InitiateSystemShutdown

BOOL InitiateSystemShutdown(lpszMachineName, lpszMessage, dwTimeout,
fForceAppsClosed, fReboot)
LPTSTR  lpszMachineName;   /* addr. of name of computer to shut down */
LPTSTR  lpszMessage;   /* addr. of msg. to display in dialog box */
DWORD  dwTimeout;   /* time to display dialog box */
BOOL  fForceAppsClosed;   /* force apps. with unsaved changes flag  */
BOOL  fReboot;   /* reboot flag */

The InitiateSystemShutdown function initiates a shutdown and optional restart of the specified computer.

Parameters

lpszMachineName

Points to the null-terminated string that specifies the network name of the computer to shut down. If lpszMachineName is NULL or points to an empty string, the function shuts down the local computer.

lpszMessage

Points to a null-terminated string that specifies a message to display in the shutdown dialog box. This parameter can be NULL if no message is required.

dwTimeout

Specifies the time (in seconds) that the dialog box should be displayed. While this dialog box is displayed, the shutdown can be stopped by the AbortSystemShutdown function.

If dwTimeout is not zero, InitiateSystemShutdown displays a dialog box on the specified computer. The dialog box displays the name of the user who called the function, displays the message specified by the lpszMessage parameter, and prompts the user to log off. The dialog box beeps when it is created and remains on top of other windows in the system. The dialog box can be moved but not closed. A timer counts down the remaining time before a forced shutdown. If the user logs off, the system shuts down immediately. Otherwise, the computer is shut down when the timer expires.

If dwTimeout is zero, the computer shuts down without displaying the dialog box, and the shutdown cannot be stopped by AbortSystemShutdown.

fForceAppsClosed

Specifies whether applications with unsaved changes are to be forcibly closed. If this parameter is TRUE, such applications are closed. If this parameter is FALSE, a dialog box is displayed prompting the user to close the applications.

fReboot

Specifies whether the computer is to restart immediately after shutting down. If this parameter is TRUE, the computer is to restart. If this parameter is FALSE, the system flushes all caches to disk, clears the screen, and displays a message indicating that it is safe to power down.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To shut down the local computer, the calling process must have the SE_SHUTDOWN_NAME privilege. To shut down a remote computer, the calling process must have the SE_REMOTE_SHUTDOWN_NAME privilege on the remote computer. By default, users can enable the SE-SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers.

Common failures include invalid or inaccessible computer name or insufficient privilege.

See Also

»AbortSystemShutdown«


  InSendMessage

BOOL InSendMessage(VOID)

The InSendMessage function specifies whether the current window procedure is processing a message that was sent from another thread by a call to the SendMessage function.

Parameters

This function has no parameters.

Return Value

If the window procedure is processing a message sent to it from another thread by the SendMessage function, the return value is TRUE; otherwise, the return value is FALSE.

See Also

»PostThreadMessage«, »ReplyMessage«, »SendMessage«


  InsertMenu

BOOL InsertMenu(hmenu, uItem, fuFlags, idNewItem, lpszNewItem)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item that new menu item precedes */
UINT  fuFlags;   /* menu item flags */
UINT  idNewItem;   /* menu item identifier or pop-up menu handle  */
LPCTSTR  lpszNewItem;   /* menu item content */

The InsertMenu function inserts a new menu item into a menu, moving other items down the menu.

Parameters

hmenu

Identifies the menu to be changed.

uItem

Specifies the menu item before which the new menu item is to be inserted, as determined by the fuFlags parameter.

fuFlags

Specifies flags that control the interpretation of the uItem parameter and the content, appearance, and behavior of the new menu item. This parameter must be a combination of one of the following required values and at least one of the values listed in the Comments section.

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the new menu item. If uItem is 0xFFFFFFFF, the new menu item is appended to the end of the menu.
idNewItem

Specifies either the identifier of the new menu item or, if the fuFlags parameter is set to the MF_POPUP flag, the handle of the pop-up menu.

lpszNewItem

Specifies the content of the new menu item. The interpretation of this parameter depends on whether the fuFlags parameter includes the MF_BITMAP, MF_OWNERDRAW, or MF_STRING flag.

Value	Meaning
MF_BITMAP	Contains a bitmap handle.
MF_OWNERDRAW	Contains a 32-bit value supplied by an application that can be used to maintain additional data related to the menu item. The value is in the itemData member of the structure pointed to by the lparam parameter of the WM_MEASURE or WM_DRAWITEM message sent when the menu item is created or its appearance is updated.
MF_STRING	Contains a pointer to a null-terminated string (the default).
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The application must call the DrawMenuBar function whenever a menu changes, whether or not the menu is in a displayed window.

The following list describes the flags that can be set in the fuFlags parameter:

Value	Meaning
MF_BITMAP	Uses a bitmap as the menu item. The lpszNewItem parameter contains the handle of the bitmap.
MF_CHECKED	Places a check mark next to the menu item. If the application provides check mark bitmaps (see the »SetMenuItemBitmaps« function), this flag displays a checked bitmap next to the menu item.
MF_DISABLED	Disables the menu item so that it cannot be selected, but does not gray it.
MF_ENABLED	Enables the menu item so that it can be selected and restores it from its grayed state.
MF_GRAYED	Disables the menu item and grays it so that it cannot be selected.
MF_MENUBARBREAK	Functions the same as MF_MENUBREAK, except for pop-up menus where the new column is separated from the old column by a vertical line.
MF_MENUBREAK	Places the item on a new line (for menu bars) or in a new column (for pop-up menus) without separating columns.
MF_OWNERDRAW	Specifies that the item is an owner-drawn item. Before the menu is displayed for the first time, the window that owns the menu receives a WM_MEASUREITEM message to retrieve the width and height of the menu item. The WM_DRAWITEM message is then sent to the window procedure of the owner window whenever the appearance of the menu item must be updated.
MF_POPUP	Specifies that the menu item is a pop-up item; that is, selecting it invokes a pop-up menu. The idNewItem parameter specifies the handle of the pop-up menu. This flag is used to add a pop-up item to a menu bar or to a pop-up menu.
MF_SEPARATOR	Draws a horizontal dividing line. This flag is used only in a pop-up menu. The dividing line cannot be grayed, disabled, or highlighted. The lpszNewItem and idNewItem parameters are ignored.
MF_STRING	Specifies that the menu item is a text string; the lpszNewItem parameter points to the string.
MF_UNCHECKED	Does not place a check mark next to the menu item (default). If the application supplies check mark bitmaps (see the »SetMenuItemBitmaps« function), this flag displays the unchecked bitmap next to the menu item.
The following list shows groups of flags that cannot be used together:

•	MF_BYCOMMAND and MF_BYPOSITION

•	MF_DISABLED, MF_ENABLED, and MF_GRAYED

•	MF_BITMAP, MF_STRING, MF_OWNERDRAW, and MF_SEPARATOR

•	MF_MENUBARBREAK and MF_MENUBREAK

•	MF_CHECKED and MF_UNCHECKED

See Also

»AppendMenu«, »DeleteMenu«, »DrawMenuBar«, »ModifyMenu«, »RemoveMenu«, »SetMenuItemBitmaps«


  InterlockedDecrement

LONG InterlockedDecrement(lplVal)
LPLONG  lplVal;   /* address of the variable to decrement */

The InterlockedDecrement function both decrements (decreases by one) the value of the specified 32-bit variable and checks the resulting value. The function prevents more than one thread from using the InterlockedDecrement or InterlockedIncrement function to access the same variable simultaneously.

Parameters

lplVal

Points to the 32-bit variable to decrement.

Return Value

If the result of the decrement is zero, the return value is zero.

If the result of the decrement is less than zero, the return value is less than zero. If the result of the decrement is greater than zero, the return value is greater than zero. A nonzero return value may not be equal to the result of the decrement.

Comments

InterlockedDecrement and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The variable pointed to by the lplVal parameter must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.


  InterlockedIncrement

LONG InterlockedIncrement(lplVal)
LPLONG  lplVal;   /* address of the variable to increment */

The InterlockedIncrement function both increments (increases by one) the value of the specified 32-bit variable and checks the resulting value. The function prevents more than one thread from using the InterlockedDecrement or InterlockedIncrement function to access the same variable simultaneously.

Parameters

lplVal

Points to the 32-bit variable to increment.

Return Value

If the result of the increment is zero, the return value is zero.

If the result of the increment is less than zero, the return value is less than zero. If the result of the increment is greater than zero, the return value is greater than zero. A nonzero return value may not be equal to the result of the increment.

Comments

InterlockedDecrement and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The variable pointed to by the lplVal parameter must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.


  IntersectClipRect

int IntersectClipRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coordinate of upper-left corner of rectangle */
int  nTopRect;   /* y-coordinate of upper-left corner of rectangle */
int  nRightRect;   /* x-coordinate of lower-right corner of rectangle */
int  nBottomRect;   /* y-coordinate of lower-right corner of rectangle */

The IntersectClipRect function creates a new clipping region from the intersection of the current clipping region and the specified rectangle.

Parameters

hdc

Identifies the device context.

nLeftRect

Specifies the logical x-coordinate of the upper-left corner of the rectangle.

nTopRect

Specifies the logical y-coordinate of the upper-left corner of the rectangle.

nRightRect

Specifies the logical x-coordinate of the lower-right corner of the rectangle.

nBottomRect

Specifies the logical y-coordinate of the lower-right corner of the rectangle.

Return Value

If the function succeeds, the return value specifies the new clipping region's type. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred. (The current clipping region is unaffected.)
Comments

The lower and rightmost edges of the given rectangle are excluded from the clipping region.

See Also

»ExcludeClipRect«


  IntersectRect

BOOL IntersectRect(lprcDst, lprcSrc1, lprcSrc2)
LPRECT  lprcDst;   /* address of structure for intersection */
CONST RECT  *lprcSrc1;   /* address of structure with first rectangle */
CONST RECT  *lprcSrc2;   /* address of structure with second rectangle */

The IntersectRect function calculates the intersection of two source rectangles and places the coordinates of the intersection rectangle into the destination rectangle. If the source rectangles do not intersect, an empty rectangle (in which all coordinates are set to zero) is placed into the destination rectangle.

Parameters

lprcDst

Points to the RECT structure that is to receive the intersection of the rectangles pointed to by the lprcSrc1 and lprcSrc2 parameters. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprcSrc1

Points to the RECT structure that contains the first source rectangle.

lprcSrc2

Points to the RECT structure that contains the second source rectangle.

Return Value

If the rectangles intersect, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»InflateRect«, »OffsetRect«, »UnionRect«


  InvalidateRect

BOOL InvalidateRect(hwnd, lprc, fErase)
HWND  hwnd;   /* handle of window with changed update region */
CONST RECT  *lprc;   /* address of structure with rectangle  */
BOOL  fErase;   /* erase-background flag */

The InvalidateRect function adds a rectangle to the given window's update region. The update region represents the portion of the window's client area that must be redrawn.

Parameters

hwnd

Identifies the window whose update region has changed. If this parameter is NULL, Windows invalidates and redraws all windows, and sends the WM_ERASEBKGND and WM_NCPAINT messages to the window procedure before the function returns.

lprc

Points to a RECT structure that contains the client coordinates of the rectangle to be added to the update region. If this parameter is NULL, the entire client area is added to the update region. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fErase

Specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect or ValidateRgn function.

Windows sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.

If the fErase parameter is TRUE for any part of the update region, the background is erased in the entire region, not just in the given part.

See Also

»BeginPaint«, »InvalidateRgn«, »ValidateRect«, »ValidateRgn«


  InvalidateRgn

BOOL InvalidateRgn(hwnd, hrgn, fErase)
HWND  hwnd;   /* handle of window with changed update region */
HRGN  hrgn;   /* handle of region to add */
BOOL  fErase;   /* erase-background flag */

The InvalidateRgn function invalidates the client area within the given region by adding it to the current update region of the given window. The invalidated region, along with all other areas in the update region, is marked for painting when the next WM_PAINT message occurs.

Parameters

hwnd

Identifies the window whose update region is to be modified.

hrgn

Identifies the region to be added to the update region. The region is assumed to have client coordinates. If this parameter is NULL, the entire client area is added to the update region.

fErase

Specifies whether the background within the update region should be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If the parameter is FALSE, the background remains unchanged.

Return Value

This function always returns TRUE.

Comments

Invalidated areas accumulate in the update region until the next WM_PAINT message is processed or until the region is validated by using the ValidateRect or ValidateRgn function.

Windows sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.

The given region must have been created by using one of the region functions.

If the fErase parameter is TRUE for any part of the update region, the background in the entire region is erased, not just in the given part.

See Also

»BeginPaint«, »InvalidateRect«, »ValidateRect«, »ValidateRgn«


  InvertRect

BOOL InvertRect(hdc, lprc)
HDC  hdc;   /* handle of device context */
CONST RECT  *lprc;   /* address of structure with rectangle */

The InvertRect function inverts a rectangle in a window by performing a logical NOT operation on the color values for each pixel in the rectangle's interior.

Parameters

hdc

Identifies the device context.

lprc

Points to a RECT structure that contains the logical coordinates of the rectangle to be inverted. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

On monochrome screens, InvertRect makes white pixels black and black pixels white. On color screens, the inversion depends on how colors are generated for the screen. Calling InvertRect twice for the same rectangle restores the display to its previous colors.

If the bottom member of the RECT structure is less than or equal to the top member, or if the right member is less than or equal to the left member, the function does not draw the rectangle.

See Also

»FillRect«


  InvertRgn

BOOL InvertRgn(hdc, hrgn)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region to be inverted */

The InvertRgn function inverts the colors in the given region.

Parameters

hdc

Identifies the device context.

hrgn

Identifies the region for which colors are inverted. The region's coordinates are presumed to be logical coordinates.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

On monochrome screens, the InvertRgn function makes white pixels black and black pixels white. On color screens, this inversion is dependent on the type of technology used to generate the colors for the screen.

See Also

»FillRgn«, »PaintRgn«


  IOCTL_DISK_CHECK_VERIFY

dwIoControlCode = IOCTL_DISK_CHECK_VERIFY ;   /* operation code 	*/

lpvInBuffer = NULL;       /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;           /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_CHECK_VERIFY operation determines whether a device's media is accessible; for example, whether the media is in the device.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds and the device media is accessible, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE.


  IOCTL_DISK_EJECT_MEDIA

dwIoControlCode = IOCTL_DISK_EJECT_MEDIA;   /* operation code 	*/

lpvInBuffer = NULL;       /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;           /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_EJECT_MEDIA operation causes media to be ejected from a SCSI device.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

IOCTL_DISK_EJECT_MEDIA  may or may not be supported on SCSI devices that support removable media.

See Also

»IOCTL_DISK_MEDIA_REMOVAL«, »IOCTL_DISK_LOAD_MEDIA«


  IOCTL_DISK_FORMAT_TRACKS

dwIoControlCode = IOCTL_DISK_FORMAT_TRACKS;   /* operation code 	*/

lpvInBuffer;              /* address of input buffer 	*/

cbInBuffer;               /* size of input buffer 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_FORMAT_TRACKS operation formats a specified, contiguous set of tracks on a disk.

Parameters

lpvInBuffer

Points to a buffer that contains a FORMAT_PARAMETERS data structure. The FORMAT_PARAMETERS structure has the following form:

typedef struct _FORMAT_PARAMETERS{

   MEDIA_TYPE MediaType;

   DWORD StartCylinderNumber;

   DWORD EndCylinderNumber;

   DWORD StartHeadNumber;

   DWORD EndHeadNumber;

} FORMAT_PARAMETERS ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer, which must be large enough to contain a FORMAT_PARAMETERS data structure.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for floppy disk devices only.


  IOCTL_DISK_GET_DRIVE_GEOMETRY

dwIoControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY;   /* operation code 	*/

lpvInBuffer = NULL; /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;     /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer ;      /* address of output buffer 	*/

cbOutBuffer ;       /* size of output buffer 	*/

lpcbBytesReturned ; /* address of actual bytes of output 	*/

The IOCTL_DISK_GET_DRIVE_GEOMETRY operation returns information about the physical disk's geometry: type, number of cylinders, tracks per cylinder, sectors per track, and bytes per sector.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to a buffer that will receive a DISK_GEOMETRY data structure. The DISK_GEOMETRY structure has the following form:

typedef struct _DISK_GEOMETRY {

   MEDIA_TYPE  MediaType;

   LARGE_INTEGER  Cylinders;

   DWORD  TracksPerCylinder;

   DWORD  SectorsPerTrack;

   DWORD  BytesPerSector;

} DISK_GEOMETRY ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer, which must be greater than or equal to the size of a DISK_GEOMETRY data structure.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices.

See Also

»IOCTL_DISK_GET_MEDIA_TYPES«


  IOCTL_DISK_GET_DRIVE_LAYOUT

dwIoControlCode = IOCTL_DISK_GET_DRIVE_LAYOUT;   /* operation code 	*/

lpvInBuffer = NULL; /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;     /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer ;      /* address of output buffer 	*/

cbOutBuffer ;       /* size of output buffer 	*/

lpcbBytesReturned ; /* address of actual bytes of output 	*/

The IOCTL_DISK_GET_DRIVE_LAYOUT operation returns information about the number of partitions on a disk and the features of each partition.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to a buffer that will receive a DRIVE_LAYOUT_INFORMATION data structure and a series of PARTITION_INFORMATION data structures, one of the latter for each partition on the drive. The DRIVE_LAYOUT_INFORMATION structure has the following form:

typedef struct _DRIVE_LAYOUT_INFORMATION {

   DWORD  PartitionCount;

   DWORD  Signature;

   PARTITION_INFORMATION  PartitionEntry[1];

} DRIVE_LAYOUT_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The PARTITION_INFORMATION structure has the following form:

typedef struct _PARTITION_INFORMATION {

    BYTE PartitionType;

    BOOLEAN BootIndicator;

    BOOLEAN RecognizedPartition;

    BOOLEAN RewritePartition;

    LARGE_INTEGER StartingOffset;

    LARGE_INTEGER PartitionLength;

    LARGE_INTEGER HiddenSectors;

} PARTITION_INFORMATION ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer, which must be large enough to contain one DRIVE_LAYOUT_INFORMATION data structure and as many PARTITION_INFORMATION data structures as there are partitions on the drive.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

See Also

»IOCTL_DISK_SET_DRIVE_LAYOUT«


  IOCTL_DISK_GET_MEDIA_TYPES

dwIoControlCode = IOCTL_DISK_GET_MEDIA_TYPES;   /* operation code 	*/

lpvInBuffer = NULL; /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;     /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer ;      /* address of output buffer 	*/

cbOutBuffer ;       /* size of output buffer 	*/

lpcbBytesReturned;  /* address of actual bytes of output 	*/

The IOCTL_DISK_GET_MEDIA_TYPES returns information about the types of media a device driver supports.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to a buffer that will receive an array of DISK_GEOMETRY data structures specifying the media types the device driver supports. The DISK_GEOMETRY structure has the following form:

typedef struct _DISK_GEOMETRY {

   MEDIA_TYPE  MediaType;

   LARGE_INTEGER  Cylinders;

   DWORD  TracksPerCylinder;

   DWORD  SectorsPerTrack;

   DWORD  BytesPerSector;

} DISK_GEOMETRY ;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer, which must be large enough to contain as many DISK_GEOMETRY structures as there are media the driver supports.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for all class drivers, as well as non-SCSI hard drives and floppy disk devices.

See Also

»IOCTL_DISK_GET_DRIVE_GEOMETRY«


  IOCTL_DISK_GET_PARTITION_INFO

dwIoControlCode = IOCTL_DISK_GET_PARTITION_INFO ;   /* operation code 	*/

lpvInBuffer = NULL;   /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;       /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer;         /* address of output buffer 	*/

cbOutBuffer;          /* size of output buffer 	*/

lpcbBytesReturned;    /* address of actual bytes of output 	*/

The IOCTL_DISK_GET_PARTITION_INFO operation returns information about the type, size, and nature of a disk partition.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to a buffer that will receive a PARTITION_INFORMATION data structure. The PARTITION_INFORMATION structure has the following form:

typedef struct _PARTITION_INFORMATION {

    BYTE PartitionType;

    BOOLEAN BootIndicator;

    BOOLEAN RecognizedPartition;

    BOOLEAN RewritePartition;

    LARGE_INTEGER StartingOffset;

    LARGE_INTEGER PartitionLength;

    LARGE_INTEGER HiddenSectors;

} PARTITION_INFORMATION ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer, which must be large enough to contain a PARTITION_INFORMATION data structure.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

See Also

»IOCTL_DISK_SET_PARTITION_INFO«


  IOCTL_DISK_LOAD_MEDIA

dwIoControlCode = IOCTL_DISK_LOAD_MEDIA;   /* operation code 	*/

lpvInBuffer = NULL;       /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;           /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_LOAD_MEDIA operation causes media to be loaded into a device.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Comments

The IOCTL_DISK_LOAD_MEDIA is valid only for devices that support loadable media.

See Also

»IOCTL_DISK_EJECT_MEDIA«, »IOCTL_DISK_MEDIA_REMOVAL«


  IOCTL_DISK_MEDIA_REMOVAL

dwIoControlCode = IOCTL_DISK_MEDIA_REMOVAL;   /* operation code 	*/

lpvInBuffer;              /* address of input buffer 	*/

cbInBuffer;               /* size of input buffer 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_MEDIA_REMOVAL operation enables or disables the mechanism that ejects media, for those devices possessing that locking capability.

Parameters

lpvInBuffer

Points to a buffer that contains a PREVENT_MEDIA_REMOVAL data structure. The PREVENT_MEDIA_REMOVAL structure has the following form:

typedef struct _PREVENT_MEDIA_REMOVAL{

   BOOLEAN PreventMediaRemoval;

} PREVENT_MEDIA_REMOVAL ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

A TRUE value for that structure's PreventMediaRemoval member specifies that media removal is prevented (the device is locked). A FALSE value specifies that media removal is allowed.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer, which must be large enough to contain a PREVENT_MEDIA_REMOVAL data structure.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

The IOCTL_DISK_MEDIA_REMOVAL operation is valid only for devices that support removable media.

See Also

»IOCTL_DISK_EJECT_MEDIA«, »IOCTL_DISK_LOAD_MEDIA«


  IOCTL_DISK_PERFORMANCE

dwIoControlCode = IOCTL_DISK_PERFORMANCE;   /* operation code 	*/

lpvInBuffer = NULL; /* address of input buffer; not used; must be NULL 	*/

cbInBuffer = 0;     /* size of input buffer; not used; must be zero 	*/

lpvOutBuffer;       /* address of output buffer 	*/

cbOutBuffer;        /* size of output buffer 	*/

lpcbBytesReturned;  /* address of actual bytes of output 	*/

The IOCTL_DISK_PERFORMANCE operation provides disk performance information.

Parameters

lpvInBuffer

Points to an input buffer. Not used with this operation. Set to NULL.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer. Not used with this operation. Set to zero.

lpvOutBuffer

Points to a buffer that will receive a PERFORMANCE_INFORMATION data structure. The PERFORMANCE_INFORMATION structure has the following form:

typedef struct _DISK_PERFORMANCE {

        LARGE_INTEGER BytesRead;

        LARGE_INTEGER BytesWritten;

        LARGE_INTEGER ReadTime;

        LARGE_INTEGER WriteTime;

        DWORD ReadCount;

        DWORD WriteCount;

        DWORD QueueDepth;

} DISK_PERFORMANCE ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer, which must be large enough to contain a PERFORMANCE_INFORMATION data structure.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices.


  IOCTL_DISK_REASSIGN_BLOCKS

dwIoControlCode = IOCTL_DISK_REASSIGN_BLOCKS;   /* operation code 	*/

lpvInBuffer;              /* address of input buffer 	*/

cbInBuffer;               /* size of input buffer 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_REASSIGN_BLOCKS operation directs the disk device to map one or more blocks to its spare-block pool.

Parameters

lpvInBuffer

Points to a buffer that contains a REASSIGN_BLOCKS data structure specifying the blocks to reassign to its spare block pool. The REASSIGN_BLOCKS structure has the following form:

typedef struct _REASSIGN_BLOCKS {

    WORD   Reserved;

    WORD   Count;

    DWORD BlockNumber[1];

} REASSIGN_BLOCKS ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer, which must be large enough to contain the REASSIGN_BLOCKS data structure. Note that this structure is really a header followed by an array of block specifiers; thus, it varies in size according to the number of blocks to be reassigned; each block after the first adds the size of a DWORD to the overall size.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices.


  IOCTL_DISK_SET_DRIVE_LAYOUT

dwIoControlCode = IOCTL_DISK_SET_DRIVE_LAYOUT;   /* operation code 	*/

lpvInBuffer;              /* address of input buffer 	*/

cbInBuffer;               /* size of input buffer 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_SET_DRIVE_LAYOUT operation partitions a disk as specified by drive layout and partition information data.

Parameters

lpvInBuffer

Points to a buffer that contains drive layout and partition information data. The data exists as a DRIVE_LAYOUT_INFORMATION data structure and a series of PARTITION_INFORMATION data structures, one of the latter for each proposed partition on the drive. The DRIVE_LAYOUT_INFORMATION structure has the following form:

typedef struct _DRIVE_LAYOUT_INFORMATION {

   DWORD  PartitionCount;

   DWORD  Signature;

   PARTITION_INFORMATION  PartitionEntry[1];

} DRIVE_LAYOUT_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The PARTITION_INFORMATION structure has the following form:

typedef struct _PARTITION_INFORMATION {

    BYTE PartitionType;

    BOOLEAN BootIndicator;

    BOOLEAN RecognizedPartition;

    BOOLEAN RewritePartition;

    LARGE_INTEGER StartingOffset;

    LARGE_INTEGER PartitionLength;

    LARGE_INTEGER HiddenSectors;

} PARTITION_INFORMATION ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer, which must be large enough to contain one DRIVE_LAYOUT_INFORMATION data structure and as many PARTITION_INFORMATION data structures as there are proposed partitions on the drive.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

See Also

»IOCTL_DISK_GET_DRIVE_LAYOUT«


  IOCTL_DISK_SET_PARTITION_INFO

dwIoControlCode = IOCTL_DISK_SET_PARTITION_INFO;   /* operation code 	*/

lpvInBuffer;              /* address of input buffer 	*/

cbInBuffer;               /* size of input buffer 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_SET_PARTITION_INFO operation sets the partition type of the specified disk partition.

Parameters

lpvInBuffer

Points to a buffer that contains the partition data to be set. The data exists as a SET_PARTITION_INFORMATION data structure. The SET_PARTITION_INFORMATION structure has the following form:

typedef struct _SET_PARTITION_INFORMATION {

   BYTE PartitionType;

} SET_PARTITION_INFORMATION ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer, which must be large enough to contain a SET_PARTITION_INFORMATION data structure.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

See Also

»IOCTL_DISK_GET_PARTITION_INFO«


  IOCTL_DISK_VERIFY

dwIoControlCode = IOCTL_DISK_VERIFY;   /* operation code 	*/

lpvInBuffer;              /* address of input buffer 	*/

cbInBuffer;               /* size of input buffer 	*/

lpvOutBuffer = NULL;      /* address of output buffer; not used; must be NULL 	*/

cbOutBuffer = 0;          /* size of output buffer; not used; must be zero 	*/

lpcbBytesReturned = NULL; /* address of actual bytes of output; not used; must be NULL 	*/

The IOCTL_DISK_VERIFY operation performs a logical format of a specified extent on a disk.

Parameters

lpvInBuffer

Points to a buffer that contains a VERIFY_INFORMATION data structure. The VERIFY_INFORMATION structure has the following form:

typedef struct _VERIFY_INFORMATION {

   LARGE_INTEGER  StartingOffset;

   DWORD  Length;

} VERIFY_INFORMATION ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbInBuffer

Specifies the size in bytes of the buffer pointed to by lpvInBuffer, which must be large enough to contain a VERIFY_INFORMATION data structure.

lpvOutBuffer

Points to an output buffer. Not used with this operation. Set to NULL.

cbOutBuffer

Specifies the size in bytes of the buffer pointed to by lpvOutBuffer. Not used with this operation. Set to zero.

lpcbBytesReturned

Points to a DWORD that receives the actual size, in bytes, of the data stored into lpvOutBuffer. Not used with this operation. Set to NULL.

Return Value

If the operation succeeds, DeviceIoControl returns TRUE.

If the operation fails, DeviceIoControl returns FALSE. Use GetLastError to obtain extended error information.

Comments

This device i/o control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

See Also

»IOCTL_DISK_CHECK_VERIFY«


  IsBadCodePtr

BOOL IsBadCodePtr(lpfnProc)
FARPROC  lpfnProc;   /* address of function */

The IsBadCodePtr function determines whether the calling process has read access to the memory at the specified address.

Parameters

lpfnProc

Points to an address in memory.

Return Value

If the calling process has read access to the specified memory, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

The IsBadCodePtr function checks the read access only at the specified address and does not guarantee read access to a range of memory.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. This enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

See Also

»IsBadHugeReadPtr«, »IsBadHugeWritePtr«, »IsBadReadPtr«, »IsBadStringPtr«, »IsBadWritePtr«


  IsBadHugeReadPtr

BOOL IsBadHugeReadPtr(lpvPtr, cbBytes)
CONST VOID  *lpvPtr;   /* address of memory block  */
UINT  cbBytes;   /* number of bytes to test */

The IsBadHugeReadPtr function verifies that the calling process has read access to the specified range of memory.

Parameters

lpvPtr

Points to the first byte of the memory block.

cbBytes

Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is FALSE.

Return Value

If the calling process has read access to all bytes in the specified memory range, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

If the calling process has read access to some, but not all, of the bytes in the specified memory range, TRUE is returned.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. This enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

This function is available for compatibility with earlier versions of Windows that distinguish between normal memory allocations and huge allocations occupying multiple segments. In the Win32 API, this function is equivalent to the IsBadReadPtr function.

See Also

»IsBadHugeWritePtr«, »IsBadReadPtr«, »IsBadStringPtr«, »IsBadWritePtr«


  IsBadHugeWritePtr

BOOL IsBadHugeWritePtr(lpvPtr, cbBytes)
LPVOID  lpvPtr;   /* address of memory block  */
UINT  cbBytes;   /* number of bytes to test */

The IsBadHugeWritePtr function verifies that the calling process has write access to the specified range of memory.

Parameters

lpvPtr

Points to the first byte of the memory block.

cbBytes

Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is FALSE.

Return Value

If the calling process has write access to all bytes in the specified memory range, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

If the calling process has write access to some, but not all, of the bytes in the specified memory range, TRUE is returned .

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has write access to the specified memory, you should use structured exception handling when attempting to access the memory. This enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

This function is available for compatibility with earlier versions of Windows, which distinguish between normal memory allocations and huge allocations occupying multiple segments. In the Win32 API, this function is equivalent to the IsBadWritePtr function.

See Also

»IsBadHugeReadPtr«, »IsBadReadPtr«, »IsBadStringPtr«, »IsBadWritePtr«


  IsBadReadPtr

BOOL IsBadReadPtr(lpvPtr, cbBytes)
CONST VOID  *lpvPtr;   /* address of memory block  */
UINT  cbBytes;   /* number of bytes to test */

The IsBadReadPtr function verifies that the calling process has read access to the specified range of memory.

Parameters

lpvPtr

Points to the first byte of the memory block.

cbBytes

Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is FALSE.

Return Value

If the calling process has read access to all bytes in the specified memory range, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

If the calling process has read access to some, but not all, of the bytes in the specified memory range, TRUE is returned.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. This enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

See Also

»IsBadHugeReadPtr«, »IsBadHugeWritePtr«, »IsBadStringPtr«, »IsBadWritePtr«


  IsBadStringPtr

BOOL IsBadStringPtr(lpszStr, cchMax)
LPCTSTR  lpszStr;   /* address of string */
UINT  cchMax;   /* maximum size of string */

The IsBadStringPtr function verifies that the calling process has read access to a range of memory pointed to by a string pointer.

Parameters

lpszStr

Points to a null-terminated string, either Unicode or ASCII.

cchMax

Specifies the maximum size, in characters, of the string. This function checks for read access in all bytes up to the string's terminating null character or up to the number of bytes specified by cchMax, whichever is smaller. If this parameter is zero, the return value is FALSE.

Return Value

If the calling process has read access to all bytes up to the string's terminating null character or up to the number of bytes specified by cchMax, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

If the calling process has read access to some, but not all, of the bytes in the specified memory range, TRUE is returned.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. This enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

See Also

»IsBadCodePtr«, »IsBadHugeReadPtr«, »IsBadHugeWritePtr«, »IsBadReadPtr«, »IsBadWritePtr«


  IsBadWritePtr

BOOL IsBadWritePtr(lpvPtr, cbBytes)
LPVOID  lpvPtr;   /* address of memory block  */
UINT  cbBytes;   /* number of bytes to test */

The IsBadWritePtr function verifies that the calling process has write access to the specified range of memory.

Parameters

lpvPtr

Points to the first byte of the memory block.

cbBytes

Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is FALSE.

Return Value

If the calling process has write access to all bytes in the specified memory range, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

If the calling process has write access to some, but not all, of the bytes in the specified memory range, TRUE is returned.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has write access to the specified memory, you should use structured exception handling when attempting to access the memory. This enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

See Also

»IsBadCodePtr«, »IsBadHugeReadPtr«, »IsBadHugeWritePtr«, »IsBadReadPtr«,


  IsCharAlpha

BOOL IsCharAlpha(ch)
TCHAR  ch;   /* character to test */

The IsCharAlpha function determines whether a character is an alphabetic character. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

Parameters

ch

Specifies the character to be tested.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»IsCharAlphaNumeric«


  IsCharAlphaNumeric

BOOL IsCharAlphaNumeric(ch)
TCHAR  ch;   /* character to test */

The IsCharAlphaNumeric function determines whether a character is either an alphabetic or a numeric character. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

Parameters

ch

Specifies the character to be tested.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»IsCharAlpha«


  IsCharLower

BOOL IsCharLower(ch)
TCHAR  ch;   /* character to test */

The IsCharLower function determines whether a character is lowercase. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

Parameters

ch

Specifies the character to be tested.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»IsCharUpper«


  IsCharUpper

BOOL IsCharUpper(ch)
TCHAR  ch;   /* character to test */

The IsCharUpper function determines whether a character is uppercase. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

Parameters

ch

Specifies the character to be tested.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»IsCharLower«


  IsChild

BOOL IsChild(hwndParent, hwnd)
HWND  hwndParent;   /* handle of parent window  */
HWND  hwnd;   /* handle of window to test */

The IsChild function tests whether a specified window is a child window or descendant window of a given parent window. A child window is the direct descendant of a given parent window, if that parent window is in the chain of parent windows leading from the original overlapped or pop-up window to the child window.

Parameters

hwndParent

Identifies the parent window.

hwnd

Identifies the window to be tested.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»IsWindow«, »SetParent«


  IsClipboardFormatAvailable

BOOL IsClipboardFormatAvailable(uFormat)
UINT  uFormat;   /* clipboard format */

The IsClipboardFormatAvailable function determines whether the clipboard contains data in the specified format.

Parameters

uFormat

Specifies a standard or registered clipboard format. For a description of the clipboard formats, see the »SetClipboardData« function.

Return Value

If the clipboard format is available, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Typically, an application that recognizes only one clipboard format would call this function when processing the WM_INITMENU or WM_INITMENUPOPUP message. The application would then enable or disable the Paste menu item, depending on the return value. Applications that recognize more than one clipboard format should use the GetPriorityClipboardFormat function for this purpose.

See Also

»CountClipboardFormats«, »EnumClipboardFormats«, »RegisterClipboardFormat«, »SetClipboardData«


  IsDBCSLeadByte

BOOL IsDBCSLeadByte(bTestChar)
BYTE  bTestChar;   /* character to test */

The IsDBCSLeadByte function determines whether a character is a lead byte — that is, the first byte of a character in a double-byte character set (DBCS).

Parameters

bTestChar

Specifies the character to be tested.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Lead bytes are unique to double-byte character sets. A lead byte introduces a double-byte character. Lead bytes occupy a specific range of byte values. The IsDBCSLeadByte function uses the ANSI code page to check lead-byte ranges.

See Also

»MultiByteToWideChar«


  IsDialogMessage

BOOL IsDialogMessage(hwndDlg, lpmsg)
HWND  hwndDlg;   /* handle of dialog box */
LPMSG  lpmsg;   /* address of structure with message */

The IsDialogMessage function determines whether the specified message is intended for the given dialog box and, if it is, processes the message.

Parameters

hwndDlg

Identifies the dialog box.

lpmsg

Points to an MSG structure that contains the message to be checked. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the message has been processed, the return value is TRUE; otherwise, it is FALSE.

Comments

Although the IsDialogMessage function is intended for modeless dialog boxes, you can use it with any window that contains controls, enabling the windows to provide the same keyboard selection as is used in a dialog box.

When IsDialogMessage processes a message, it checks for keyboard messages and converts them into selection commands for the corresponding dialog box. For example, the TAB key, when pressed, selects the next control or group of controls, and the DOWN ARROW key, when pressed, selects the next control in a group.

Because the IsDialogMessage function performs all necessary translating and dispatching of messages, a message processed by IsDialogMessage must not be passed to the TranslateMessage or DispatchMessage function.

IsDialogMessage sends WM_GETDLGCODE messages to the dialog box procedure to determine which keys should be processed.

IsDialogMessage can send DM_GETDEFID and DM_SETDEFID messages to the window. These messages are defined in the WINUSER.H header file as WM_USER and WM_USER + 1, so conflicts are possible with application-defined messages having the same values.

See Also

»DispatchMessage«, »TranslateMessage«


  IsDlgButtonChecked

UINT IsDlgButtonChecked(hwndDlg, idButton)
HWND  hwndDlg;   /* handle of dialog box  */
int  idButton;   /* button identifier */

The IsDlgButtonChecked function determines whether a button control has a check mark next to it or whether a three-state button control is grayed, checked, or neither.

Parameters

hwndDlg

Identifies the dialog box that contains the button control.

idButton

Specifies the integer identifier of the button control.

Return Value

The return value from a button created with the BS_AUTOCHECKBOX, BS_AUTORADIOBUTTON, BS_AUTO3STATE, BS_CHECKBOX, BS_RADIOBUTTON, or BS_3STATE style can be one of the following:

Value	Meaning
0	Button state is unchecked.
1	Button state is checked.
2	Button state is indeterminate (applies only if the button has the BS_3STATE or BS_AUTO3STATE style).
If the button has any other style, the return value is 0.

Comments

The IsDlgButtonChecked function sends a BM_GETCHECK message to the specified button control.

See Also

»CheckDlgButton«


  IsIconic

BOOL IsIconic(hwnd)
HWND  hwnd;   /* handle of window */

The IsIconic function determines whether the given window is minimized (iconic).

Parameters

hwnd

Identifies the window.

Return Value

If function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»IsZoomed«


  IsRectEmpty

BOOL IsRectEmpty(lprc)
CONST RECT  *lprc;   /* address of structure with rectangle */

The IsRectEmpty function determines whether the specified rectangle is empty. A empty rectangle is one that has no area; that is, the coordinate of the right side is less than or equal to the coordinate of the left side, or the coordinate of the bottom side is less than or equal to the coordinate of the top side.

Parameters

lprc

Points to a RECT structure that contains the logical coordinates of the rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the rectangle is empty, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»EqualRect«, »PtInRect«


  IsTask

The IsTask function has been deleted.


  IsValidAcl

BOOL IsValidAcl(pAcl)
PACL  pAcl;   /* address of access-control list */

The IsValidAcl function validates an access-control list (ACL).

Parameters

pAcl

Points to an ACL structure validated by this function. This must be a non-NULL value.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function checks the revision level of the ACL and verifies that the number of access-control entries (ACEs) specified in the AceCount member of the ACL structure fits the space specified by the AclSize member of the ACL structure.

If pAcl is NULL, the application will fail with an access violation.

See Also

»GetAclInformation«, »InitializeAcl«


  IsValidCodePage

BOOL IsValidCodePage(CodePage)
UINT  CodePage;   /* specifies code page to check */

The IsValidCodePage determines whether a specified code page is valid.

Parameters

CodePage

Specifies the code page to check. Each code page is identified by a unique number.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. Call GetLastError for extended error information.

Comments

A code page is considered valid only if it is installed in the system.

See Also

»GetACP«, »GetCPInfo«, »GetOEMCP«


  IsValidSecurityDescriptor

BOOL IsValidSecurityDescriptor(psd)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */

The IsValidSecurityDescriptor function validates a SECURITY_DESCRIPTOR structure. Validation is performed by checking the revision level of each component in the security descriptor.

Parameters

psd

Points to a SECURITY_DESCRIPTOR structure that the function validates.

Return Value

If the structure of the security descriptor is valid, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »InitializeSecurityDescriptor«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorOwner«, »SetSecurityDescriptorSacl«


  IsValidSid

BOOL IsValidSid(psid)
PSID  psid;   /* address of SID to query */

The IsValidSid function validates an SID structure by verifying that the revision number is within a known range and that the number of subauthorities is less than the maximum. An SID is a security identifier.

Parameters

psid

Points to the SID structure to validate. This must be a non-NULL value.

Return Value

If the SID structure is valid, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If psid is NULL, the application will fail with an access violation.

See Also

»GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidLengthRequired«, »GetSidSubAuthority«, »GetSidSubAuthorityCount«


  IsWindow

BOOL IsWindow(hwnd)
HWND  hwnd;   /* handle of window */

The IsWindow function determines whether the specified window handle identifies an existing window.

Parameters

hwnd

Specifies the window handle.

Return Value

If the window handle identifies an existing window, the return value is TRUE; otherwise, it is FALSE.

See Also

»IsWindowEnabled«, »IsWindowVisible«


  IsWindowEnabled

BOOL IsWindowEnabled(hwnd)
HWND  hwnd;   /* handle of window to test */

The IsWindowEnabled function determines whether the given window is enabled for mouse and keyboard input.

Parameters

hwnd

Identifies the window.

Return Value

If the window is enabled, the return value is TRUE; otherwise, it is FALSE.

Comments

A child window receives input only if it is both enabled and visible.

See Also

»EnableWindow«, »IsWindowVisible«


  IsWindowUnicode

BOOL IsWindowUnicode(hwnd)
HWND  hwnd;   /* handle of window */

The IsWindowUnicode function determines whether the given window is a native Unicode window.

Parameters

hwnd

Identifies the window.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The system does automatic two-way translation (Unicode to ANSI-ASCII) translation for window messages. For example, if an ANSI-ASCII window message is sent to a Unicode window, the system translates that message into a Unicode message before calling the window procedure. The system calls the IsWindowUnicode function to determine whether to translate the message.

When this function returns FALSE, the window is a native ANSI-ASCII window.


  IsWindowVisible

BOOL IsWindowVisible(hwnd)
HWND  hwnd;   /* handle of window */

The IsWindowVisible function retrieves the visibility state of the given window.

Parameters

hwnd

Identifies the window.

Return Value

If the given window is visible on the screen (has the WS_VISIBLE style), the return value is TRUE; otherwise, it is FALSE. Because the return value specifies whether the window has the WS_VISIBLE style, it may be TRUE, even if the window is totally obscured by other windows.

Comments

The visibility state of a window is indicated by the WS_VISIBLE style bit. When WS_VISIBLE is set, the window is displayed and subsequent drawing into it is displayed as long as the window has the WS_VISIBLE style.

Any drawing to a window with the WS_VISIBLE style will not be displayed if the window is obscured by other windows or is clipped by its parent window.

See Also

»ShowWindow«


  IsZoomed

BOOL IsZoomed(hwnd)
HWND  hwnd;   /* handle of window */

The IsZoomed function determines whether a window is maximized.

Parameters

hwnd

Identifies the window.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»IsIconic«


  JournalPlaybackProc

LRESULT CALLBACK JournalPlaybackProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* undefined */
LPARAM  lParam;   /* address of message being processed */

The JournalPlaybackProc hook procedure is a library-defined callback function that inserts mouse and keyboard messages into the system message queue. Typically, a library uses this hook procedure to play back a series of mouse and keyboard messages recorded previously by the JournalRecordProc hook procedure. As long as a JournalPlaybackProc hook procedure is installed, regular mouse and keyboard input is disabled.

Parameters

nCode

Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:

Value	Meaning
HC_GETNEXT	The hook procedure must copy the current mouse or keyboard message to the EVENTMSG structure pointed to by the lParam parameter. For a description of the EVENTMSG structure, see the Microsoft Win32 Programmer's Reference, Volume 5.
HC_SKIP	The hook procedure must prepare to copy the next mouse or keyboard message to the EVENTMSG structure pointed to by lParam. Upon receiving the HC_GETNEXT code, the hook procedure must copy the message to the structure. For a description of the EVENTMSG structure, see the Microsoft Win32 Programmer's Reference, Volume 5.
HC_SYSMODALOFF	A system-modal dialog box has been destroyed. The hook procedure must resume playing back the messages.
HC_SYSMODALON	A system-modal dialog box is being displayed. Until the dialog box is destroyed, the hook procedure must stop playing back messages.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies a NULL value.

lParam

Points to an EVENTMSG structure that represents a message being processed by the hook procedure. This parameter is valid only when the nCode parameter is HC_GETNEXT. The EVENTMSG structure has the following form:

typedef struct tagEVENTMSG {    /* em */

    UINT  message;

    UINT  paramL;

    UINT  paramH;

    DWORD time;

    HWND  hwnd;

} EVENTMSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

To have the system wait before processing the message, the return value must be the amount of time, in clock ticks, the system should wait. (This value can be computed by calculating the difference between the time members in the current and previous input messages.) To process the message immediately, the return value should be zero. The return value is used only if the hook code is HC_GETNEXT; otherwise, it is ignored.

Comments

A JournalPlaybackProc hook procedure should copy an input message to the lParam parameter. The message must have been previously recorded by using a JournalRecordProc hook procedure, which should not modify the message.

To retrieve the same message over and over, the hook procedure can be called several times with the nCode parameter set to HC_GETNEXT without an intervening call with nCode set to HC_SKIP.

If nCode is HC_GETNEXT and the return value is greater than zero, the system sleeps for the number of milliseconds specified by the return value. When the system continues, it calls the hook procedure again with nCode set to HC_GETNEXT to retrieve the same message. The return value from this new call to JournalPlaybackProc should be zero; otherwise, the system will go back to sleep for the number of milliseconds specified by the return value, call JournalPlaybackProc again, and so on. The system will appear to be hung.

Unlike most other global hook procedures, the JournalRecordProc and JournalPlaybackProc hook procedures are always called in the context of the thread that set the hook.

After the hook procedure returns control to the system, the message continues to be processed. If nCode is HC_SKIP, the hook procedure must prepare to return the next recorded event message on its next call.

This hook procedure must be in a dynamic-link library (DLL). An application installs the hook procedure by specifying the WH_JOURNALPLAYBACK hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

If the user presses the VK_CANCEL key combination (CTRL+BREAK on most keyboards), the system stops the playback sequence and removes the JournalPlaybackProc hook procedure from the WH_JOURNALPLAYBACK hook. Removing the hook procedure prevents an error in a journaling application from locking up the system by hanging inside its JournalPlaybackProc hook procedure. This implies that a CTRL+BREAK key combination cannot be recorded. The CTRL+C key combination is not affected.

JournalPlaybackProc is a placeholder for the library-defined function name.

See Also

»CallNextHookEx«, »JournalRecordProc«, »SetWindowsHookEx«


  JournalRecordProc

LRESULT CALLBACK JournalRecordProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* undefined */
LPARAM  lParam;   /* address of message being processed */

The JournalRecordProc hook procedure is a library-defined callback function that records messages the system removes from the system message queue. Later, a library can use a JournalPlaybackProc hook procedure to play back the messages.

Parameters

nCode

Specifies how to process the message. This parameter can be one of the following values:

Value	Meaning
HC_ACTION	The lParam parameter points to an EVENTMSG structure containing information about a message removed from the system queue. The hook procedure must record the contents of the structure by copying them to a buffer or file. For a description of the EVENTMSG structure, see the the the Microsoft Win32 Programmer's Reference, Volume 5.
HC_SYSMODALOFF	A system-modal dialog box has been destroyed. The hook procedure must resume recording.
HC_SYSMODALON	A system-modal dialog box is being displayed. Until the dialog box is destroyed, the hook procedure must stop recording.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies a NULL value.

lParam

Points to an EVENTMSG structure that contains the message to be recorded. The EVENTMSG structure has the following form:

typedef struct tagEVENTMSG {    /* em */

    UINT  message;

    UINT  paramL;

    UINT  paramH;

    DWORD time;

    HWND  hwnd;

} EVENTMSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

The return value is ignored.

Comments

A JournalRecordProc hook procedure must copy but not modify the messages. After the hook procedure returns control to the system, the message continues to be processed.

This hook procedure must be in a dynamic-link library (DLL). An application installs the hook procedure by specifying the WH_JOURNALRECORD hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

Unlike most other global hook procedures, the JournalRecordProc and JournalPlaybackProc hook procedures are always called in the context of the thread that set the hook.

If the user presses the VK_CANCEL key combination (CTRL+BREAK on most keyboards), the system stops the recording sequence and removes the JournalRecordProc hook procedure from the WH_JOURNALRECORD hook. Removing the hook procedure prevents an error in a journaling application from locking up the system by hanging inside its JournalRecordProc hook procedure. This implies that a CTRL+BREAK key combination cannot be recorded. The CTRL+C key combination is not affected.

JournalRecordProc is a placeholder for the library-defined function name.

See Also

»CallNextHookEx«, »JournalPlaybackProc«, »SetWindowsHookEx«


  joyGetDevCaps

MMRESULT joyGetDevCaps(IDDevice, lpjc, cbjc)
UINT  IDDevice;   /* identifies device to query */
LPJOYCAPS  lpjc;   /* address of structure for device capabilities  */
UINT  cbjc;   /* size of structure in bytes */

The joyGetDevCaps function queries a joystick device to determine its capabilities.

Parameters

IDDevice

Identifies the device to be queried. This value is either JOYSTICKID1 or JOYSTICKID2.

lpjc

Points to a JOYCAPS structure. This structure is filled with information about the capabilities of the joystick device. The JOYCAPS structure has the following form:

typedef struct joyinfo_tag {

    WORD  wMid;

    WORD  wPid;

    TCHAR  szPname[MAXPNAMELEN];

    UINT  wXmin;

    UINT  wXmax;

    UINT  wYmin;

    UINT  wYmax;

    UINT  wZmin;

    UINT  wZmax;

    UINT  wNumButtons;

    UINT  wPeriodMin;

    UINT  wPeriodMax;

} JOYCAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbjc

Specifies the size, in bytes, of the JOYCAPS structure.

Return Value

If the function succeeds, the return value is JOYERR_NOERROR. Otherwise, the return value is an error code that can be one of the following:

Value	Meaning
MMSYSERR_NODRIVER	The joystick driver is not present.
JOYERR_PARMS	The specified joystick device identifier IDDevice is invalid.
Comments

Use the joyGetNumDevs function to determine the number of joystick devices supported by the driver.

See Also

»joyGetNumDevs«


  joyGetNumDevs

UINT joyGetNumDevs(VOID)

The joyGetNumDevs function returns the number of joystick devices supported by the system.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of joystick devices supported by the joystick driver. If no driver is present, the function returns zero.

Comments

Use the joyGetPos function to determine whether a given joystick is actually attached to the system. The joyGetPos function returns a JOYERR_UNPLUGGED error code if the specified joystick is not connected.

See Also

»joyGetDevCaps«, »joyGetPos«


  joyGetPos

MMRESULT joyGetPos(IDDevice, lpji)
UINT  IDDevice;   /* identifies device to query */
LPJOYINFO  lpji;   /* address of structure for information */

The joyGetPos function queries for the position and button activity of a joystick device.

Parameters

IDDevice

Identifies the joystick device to be queried. This value is either JOYSTICKID1 or JOYSTICKID2.

lpji

Points to a JOYINFO structure. This structure is filled with information about the position and button activity of the joystick device. The JOYINFO structure has the following form:

typedef struct joyinfo_tag {

    UINT  wXpos;

    UINT  wYpos;

    UINT  wZpos;

    UINT  wButtons;

} JOYINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is JOYERR_NOERROR. Otherwise, the return value is an error code that can be one of the following:

Value	Meaning
MMSYSERR_NODRIVER	The joystick driver is not present.
JOYERR_PARMS	The specified joystick device identifier IDDevice is invalid.
JOYERR_UNPLUGGED	The specified joystick is not connected to the system.


  joyGetThreshold

MMRESULT joyGetThreshold(IDDevice, puThreshold)
UINT  IDDevice;   /* identifies device to query */
PUINT  puThreshold;   /* address of variable for threshold */

The joyGetThreshold function queries the current movement threshold of a joystick device.

Parameters

IDDevice

Identifies the joystick device to be queried. This value is either JOYSTICKID1 or JOYSTICKID2.

puThreshold

Points to a variable that will receive the movement threshold value.

Return Value

If the function succeeds, the return value is JOYERR_NOERROR. Otherwise, the return value is an error code that can be one of the following:

Value	Meaning
MMSYSERR_NODRIVER	The joystick driver is not present.
JOYERR_PARMS	The specified joystick device identifier IDDevice is invalid.
Comments

The movement threshold is the distance the joystick must be moved before a WM_JOYMOVE message is sent to a window that has captured the device. The threshold is initially zero.

See Also

»joySetThreshold«


  joyReleaseCapture

MMRESULT joyReleaseCapture(IDDevice)
UINT  IDDevice;   /* identifies device to release */

The joyReleaseCapture function releases the capture set by the joySetCapture function on the specified joystick device.

Parameters

IDDevice

Identifies the joystick device to be released. This value is either JOYSTICKID1 or JOYSTICK2.

Return Value

If the function succeeds, the return value is JOYERR_NOERROR. Otherwise, the return value is an error code that can be one of the following:

Value	Meaning
MMSYSERR_NODRIVER	The joystick driver is not present.
JOYERR_PARMS	The specified joystick device identifier IDDevice is invalid.
See Also

»joySetCapture«


  joySetCapture

MMRESULT joySetCapture(hwnd, IDDevice, cPollingMS, fChanged)
HWND  hwnd;   /* handle of window that receives messages */
UINT  IDDevice;   /* identifies device to capture */
UINT  cPollingMS;   /* polling rate in milliseconds */
BOOL  fChanged;   /* send messages only above threshold */

The joySetCapture function causes joystick messages to be sent to the specified window.

Parameters

hwnd

Identifies the window to which messages are to be sent.

IDDevice

Identifies the joystick device to be captured. This value is either JOYSTICKID1 or JOYSTICKID2.

cPollingMS

Specifies the polling rate in milliseconds.

fChanged

If this parameter is set to TRUE, messages are sent only when the position changes by a value greater than the joystick-movement threshold.

Return Value

If the function succeeds, the return value is JOYERR_NOERROR. Otherwise, the return value is an error code that can be one of the following:

Value	Meaning
MMSYSERR_NODRIVER	The joystick driver is not present.
JOYERR_PARMS	The specified window handle hwnd or joystick device identifier IDDevice is invalid.
JOYERR_NOCANDO	Cannot capture joystick input because some required service (for example, a Windows timer) is unavailable.
JOYERR_UNPLUGGED	The specified joystick is not connected to the system.
Comments

This function fails if the specified joystick device is currently captured. Call the joyReleaseCapture function when the joystick capture is no longer needed. If the window is destroyed, the joystick will be released automatically.

See Also

»joyGetThreshold«, »joyReleaseCapture«, »joySetThreshold«


  joySetThreshold

MMRESULT joySetThreshold(IDDevice, uThreshold)
UINT  IDDevice;   /* identifies device to set threshold for  */
UINT  uThreshold;   /* new threshold value */

The joySetThreshold function sets the movement threshold of a joystick device.

Parameters

IDDevice

Identifies the joystick device. This value is either JOYSTICKID1 or JOYSTICKID2.

uThreshold

Specifies the new movement threshold.

Return Value

If the function succeeds, the return value is JOYERR_NOERROR. Otherwise, the return value is an error code that can be one of the following:

Value	Meaning
MMSYSERR_NODRIVER	The joystick driver is not present.
JOYERR_PARMS	The specified joystick device identifier IDDevice is invalid.
Comments

The movement threshold is the distance the joystick must be moved before a WM_JOYMOVE message is sent to a window that has captured the device.

See Also

»joyGetThreshold«, »joySetCapture«


  keybd_event

VOID keybd_event(bVirtualKey, bScanCode, dwFlags, dwExtraInfo)
BYTE  bVirtualKey;   /* virtual key code */
BYTE  bScanCode;   /* hardware scan code */
DWORD  dwFlags;   /* flags specifying various function options */
DWORD  dwExtraInfo;   /* additional data associated with keystroke */

The keybd_event function synthesizes a keystroke. The keystroke may subsequently be used by the system to generate a WM_KEYUP or WM_KEYDOWN message. The keyboard driver's interrupt handler calls this function.

Parameters

bVirtualKey

Specifies a virtual-key code. The code must be a value in the range 1 to 254.

bScanCode

Specifies a hardware-scan code for the key.

dwFlags

A set of flag bits that specify various aspects of function operation. You may use any combination of the following predefined constant values to set the flags:

Value	Meaning
KEYEVENTF_EXTENDEDKEY	If specified, the scan code was preceded by a prefix byte having the value 0xE0.
KEYEVENTF_KEYUP	If specified, the key is being released. If not specified, the key is being depressed.
dwExtraInfo

Specifies an additional 32-bit value associated with the key stroke.

Return Value

This function has no return value.

Comments

Although keybd_event passes an OEM-dependent hardware scan code to Windows, applications should not use the scan code. Windows converts scan codes to virtual key codes internally, and clears the up/down bit in the scan code before passing it on to applications.

An application can simulate the PRINTSCREEN key in order to take a screen snapshot and save it to the Windows clipboard. To do this, call keybd_event with bVirtualKey set to VK_SNAPSHOT and bScanCode set to 0 for a snapshot of the full screen or 1 for a snapshot of the active window.

See Also

»GetAsyncKeyState«, »GetKeyState«, »MapVirtualKey«, »SetKeyboardState«


  KeyboardProc

LRESULT CALLBACK KeyboardProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* virtual-key code */
LPARAM  lParam;   /* keystroke-message information */

The KeyboardProc hook procedure is an application-defined or library-defined callback function the system calls whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.

Parameters

nCode

Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:

Value	Meaning
HC_ACTION	The wParam and lParam parameters contain information about a keystroke message.
HC_NOREMOVE	The wParam and lParam parameters contain information about a keystroke message, and the keystroke message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies the virtual-key code of the key that generated the keystroke message.

lParam

Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. This parameter can be a combination of the following values:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31	Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.
Return Value

To prevent Windows from passing the message to the rest of the hook chain or to the target window procedure, the return value must be a nonzero value. To allow Windows to pass the message to the target window procedure, bypassing the remaining procedures in the chain, the return value must be zero.

Comments

An application installs the hook procedure by specifying the WH_KEYBOARD hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

KeyboardProc is a placeholder for the application-defined or library-defined function name.

See Also

»CallNextHookEx«, »GetMessage«, »PeekMessage«, »SetWindowsHookEx«


  KillTimer

BOOL KillTimer(hwnd, idEvent)
HWND  hwnd;   /* handle of window that installed timer  */
UINT  idEvent;   /* timer identifier */

The KillTimer function destroys the specified timer. The system searches the message queue for any pending WM_TIMER messages associated with the timer and removes them.

Parameters

hwnd

Identifies the window associated with the specified timer. This value must be the same as the hwnd value passed to the SetTimer function that created the timer.

idEvent

Specifies the timer to be destroyed. If the window handle passed to SetTimer is valid, this parameter must be the same as the idEvent value passed to SetTimer. If the application calls SetTimer with hwnd set to NULL, this parameter must be the timer identifier returned by SetTimer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»SetTimer«


  _lclose

HFILE _lclose(hFile)
HFILE  hFile;   /* handle of file to close */

The _lclose function closes the specified file so it is no longer available for reading or writing. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the CloseHandle function.

Parameters

hFile

Identifies the file to be closed. This handle is returned by the function that created or last opened the file.

Return Value

If the function succeeds, the return value is zero; otherwise, it is HFILE_ERROR. To get extended error information, use the GetLastError function.

See Also

»CreateFile«, »_lopen«


  LCMapStringW

int LCMapStringW(lcid, fdwMap, lpSrcStr, cchSrc, lpDestStr, cchDest)
LCID  lcid;   /* locale identifier */
DWORD  fdwMap;   /* mapping type */
LPCWSTR  lpSrcStr;   /* address of source string */
int  cchSrc;   /* number of characters in source string */
LPWSTR  lpDestStr;   /* address of destination buffer  */
int  cchDest;   /* size of destination buffer */

The LCMapStringW function maps one wide character string to another, performing the specified locale-dependent translation.

Parameters

lcid

Specifies a locale identifier. An application can use the MAKELCID macro to create a locale identifier. For more information about MAKELCID, see the Microsoft Win32 Programmer's Reference, Volume 5. For more information about locale identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 5.

fdwMap

Specifies flags indicating the type of transformation to be used during mapping. This parameter can be one or more of the following values:

Option	Meaning
LCMAP_BYTEREV	Use byte reversal.
LCMAP_LOWERCASE	Use lowercase. This option cannot be used with LCMAP_UPPERCASE.
LCMAP_SORTKEY	Use wide-character sort key (normalize).
LCMAP_UPPERCASE	Use uppercase. This option cannot be used with LCMAP_LOWERCASE.
NORM_IGNORECASE	Ignore case. This bit is not set by default. This option can only be used with LCMAP_SORTKEY.
NORM_IGNORENONSPACE	Ignore nonspacing. This bit is not set by default. This option cannot be used with LCMAP_LOWERCASE or LCMAP_UPPERCASE.
NORM_IGNORESYMBOLS	Ignore symbols. This bit is not set by default. This option cannot be used with LCMAP_LOWERCASE or LCMAP_UPPERCASE.
SORT_STRINGSORT	Treat punctuation the same as symbols. This option can only be used with LCMAP_SORTKEY.
lpSrcStr

Points to the string to be mapped.

cchSrc

Specifies the number of characters in the string pointed to by the lpSrcStr parameter. If this value is −1, the string is assumed to be null terminated and the length is calculated automatically.

lpDestStr

Points to the buffer to store the mapped string.

cchDest

Specifies the number of characters in the buffer pointed to by the lpDestStr parameter.

However, if LCMAP_SORTKEY is specified in the fdwMap parameter, cchDest specifies the number of bytes in the buffer pointed to by lpDestStr.

If this value is zero, the function's return value is the number of characters, or bytes if LCMAP_SORTKEY is specified, required to hold the mapped string. In this case, the buffer pointed to by lpDestStr is not used.

Return Value

If the function succeeds, and the value of cchDest is non-zero, the return value is the number of characters, or bytes if LCMAP_SORTKEY is specified, written to the buffer.

If the function succeeds, and the value of cchDest is zero, the return value is the size of the buffer in characters, or bytes if LCMAP_SORTKEY is specified, required to receive the translated string.

If the function fails, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

The mapped string is null terminated if the source string is null terminated.

The lpSrcStr and lpDestStr pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The output string is not strictly in WCHAR format because some of the mapping options, such as LCMAP_SORTKEY, return values instead of wide characters.

See Also

»CompareStringW«, »FoldStringW«, »MAKELCID«


  _lcreat

HFILE _lcreat(lpszFileName, fnAttribute)
LPCSTR  lpszFileName;   /* address of the name of the file to open  */
int  fnAttribute;   /* file attribute */

The _lcreat function creates or opens a specified file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the CreateFile function.

Parameters

lpszFileName

Points to a null-terminated string that names the file to be opened. The string must consist of characters from the Windows ANSI character set.

fnAttribute

Specifies the file attributes. The parameter must be one of the following values:

Value	Meaning
0	Normal; can be read from or written to without restriction.
1	Read only; cannot be opened for write.
2	Hidden; not found by directory search.
4	System; not found by directory search.
Return Value

If the function succeeds, the return value is a file handle; otherwise, it is HFILE_ERROR. To get extended error information, use the GetLastError function.

Comments

If the file does not exist, _lcreat creates a new file and opens it for writing. If the file does exist, _lcreat truncates the file size to zero and opens it for reading and writing. When the function opens the file, the pointer is set to the beginning of the file.

Use the _lcreat function carefully. It can open any file, even one already opened by another function.

See Also

»CreateFile«, »_lopen«


  LeaveCriticalSection

VOID LeaveCriticalSection(lpcsCriticalSection)
LPCRITICAL_SECTION  lpcsCriticalSection;   /* address of critical section object */

The LeaveCriticalSection function releases ownership of the specified critical section object.

Parameters

lpcsCriticalSection

Points to the critical section object.

Return Value

This function does not return a value.

Comments

A thread uses the EnterCriticalSection function to acquire ownership of a critical section object. Once a thread owns a critical section, it can make additional calls to EnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns. To release its ownership, the thread must call LeaveCriticalSection once for each time that it entered the critical section.

If a thread calls LeaveCriticalSection when it does not have ownership of the specified critical section object, an error occurs that may cause another thread using EnterCriticalSection to wait indefinitely.

The threads of a single process can use a critical section object to provide mutually exclusive access to a shared resource. For similar synchronization between the threads of different processes, use a mutex object.

See Also

»CreateMutex«, »DeleteCriticalSection«, »EnterCriticalSection«, »InitializeCriticalSection«


  LimitEmsPages

The LimitEmsPages function is obsolete. This function is x86 specific.

This function is provided in Win32 only for compatibility with earlier versions of Windows. New Win32 applications should not use this function.


  LineDDA

BOOL LineDDA(nXStart, nYStart, nXEnd, nYEnd, lpLineFunc, lpData)
int  nXStart;   /* x-coordinate of line's starting point */
int  nYStart;   /* y-coordinate of line's starting point */
int  nXEnd;   /* x-coordinate of line's ending point */
int  nYEnd;   /* y-coordinate of line's ending point */
LINEDDAPROC  lpLineFunc;   /* address of application-defined callback function  */
LPARAM  lpData;   /* address of application-defined data */

The LineDDA function determines which pixels should be highlighted for a line defined by the given starting and ending points.

Parameters

nXStart

Specifies the x-coordinate of the line's starting point.

nYStart

Specifies the y-coordinate of the line's starting point.

nXEnd

Specifies the x-coordinate of the line's ending point.

nYEnd

Specifies the y-coordinate of the line's ending point.

lpLineFunc

Specifies the address of an application-defined callback function. For more information, see the description of the »LineDDAProc« callback function.

lpData

Points to the application-defined data.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function passes the coordinates for each point along the line, except for the line's ending point, to the application-defined callback function. In addition to passing the coordinates of a point, this function passes any existing application-defined data.

The coordinates passed to the callback function match pixels on a video display only if the default transformations and mapping modes are used.

See Also

»LineDDAProc«


  LineDDAProc

VOID CALLBACK LineDDAFunc(X, Y, lpData)
int  X;   /* x-coordinate of point being evaluated */
int  Y;   /* y-coordinate of point being evaluated */
LPARAM  lpData;   /* address of application-defined data */

The LineDDAProc function is an application-defined callback function that processes coordinates from the LineDDA function.

Parameters

X

Specifies the x-coordinate of the current point.

Y

Specifies the y-coordinate of the current point.

lpData

Points to the application-defined data.

Return Value

This function must return a nonzero value to continue enumeration; to stop enumeration, it must return zero.

Comments

LineDDAProc is a placeholder for the application-defined function name.

An application registers this function by passing its address to the LineDDA function.

See Also

»LineDDA«


  LineTo

BOOL LineTo(hdc, nXEnd, nYEnd)
HDC  hdc;   /* device context handle */
int  nXEnd;   /* x-coordinate of line's ending point */
int  nYEnd;   /* y-coordinate of line's ending point */

The LineTo function draws a line from the current position up to, but not including, the specified point.

Parameters

hdc

Identifies a device context.

nXEnd

Specifies the x-coordinate of the line's ending point.

nYEnd

Specifies the y-coordinate of the line's ending point.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The coordinates of the line's ending point are specified in logical units.

The line is drawn by using the current pen and, if the pen is a geometric pen, the current brush.

If the function succeeds, the current position is set to the specified ending point.

See Also

»MoveToEx«, »Polyline«, »PolylineTo«


  _llseek

LONG _llseek(hFile, lOffset, nOrigin)
HFILE  hFile;   /* handle of file */
LONG  lOffset;   /* number of bytes to move  */
int  nOrigin;   /* position to move from */

The _llseek function repositions the file pointer in a previously opened file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the SetFilePointer function.

Parameters

hFile

Identifies the file.

lOffset

Specifies the number of bytes the file pointer is to be moved.

nOrigin

Specifies the starting position and direction of the file pointer. The parameter must be one of the following values:

Value	Meaning
0	Moves the file pointer lOffset bytes from the beginning of the file.
1	Moves the file pointer lOffset bytes from its current position.
2	Moves the file pointer lOffset bytes from the end of the file.
Return Value

If the function succeeds, the return value specifies the new offset of the pointer, in bytes, from the beginning of the file. Otherwise, the return value is HFILE_ERROR. To get extended error information, use the GetLastError function.

Comments

When a file is initially opened, the file pointer is set to the beginning of the file. The _llseek function moves the pointer an arbitrary amount without reading data, which facilitates random access to the file's contents.

See Also

»_lopen«, »SetFilePointer«


  LoadAccelerators

HACCEL LoadAccelerators(hinst, lpTableName)
HINSTANCE  hinst;   /* handle of application instance */
LPCTSTR  lpTableName;   /* address of table-name string */

The LoadAccelerators function loads the given accelerator table.

Parameters

hinst

Identifies an instance of the module whose executable file contains the accelerator table to be loaded.

lpTableName

Points to a null-terminated string that names the accelerator table to be loaded. Alternatively, this parameter can specify the resource identifier of an accelerator-table resource in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can be used to create this value.

Return Value

If the function succeeds, the return value is the handle of the loaded accelerator table; otherwise, it is NULL.

Comments

If the accelerator table has not yet been loaded, the function loads it from the given executable file.

Accelerator tables loaded from resources are freed automatically when the application terminates.

See Also

»CopyAcceleratorTable«, »CreateAcceleratorTable«, »DestroyAcceleratorTable«


  LoadBitmap

HBITMAP LoadBitmap(hinst, lpszBitmap)
HINSTANCE  hinst;   /* handle of application instance */
LPCTSTR  lpszBitmap;   /* address of bitmap resource name */

The LoadBitmap function loads the specified bitmap resource from the given module's executable file.

Parameters

hinst

Identifies the instance of the module whose executable file contains the bitmap to be loaded.

lpszBitmap

Points to a null-terminated string that contains the name of the bitmap resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can be used to create this value. .ifPRINT For more information about the MAKE_RESOURCE macro, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the specified bitmap; otherwise, it is NULL.

Comments

If the bitmap pointed to by the lpszBitmap parameter does not exist or there is insufficient memory to load the bitmap, the function fails.

An application can use the LoadBitmap function to access the predefined bitmaps used by Windows. To do so, the application must set the hinst parameter to NULL and the lpszBitmap parameter to one of the following values:

OBM_BTNCORNERS	OBM_OLD_RESTORE
OBM_BTSIZE	OBM_OLD_RGARROW
OBM_CHECK	OBM_OLD_UPARROW
OBM_CHECKBOXES	OBM_OLD_ZOOM
OBM_CLOSE	OBM_REDUCE
OBM_COMBO	OBM_REDUCED
OBM_DNARROW	OBM_RESTORE
OBM_DNARROWD	OBM_RESTORED
OBM_DNARROWI	OBM_RGARROW
OBM_LFARROW	OBM_RGARROWD
OBM_LFARROWD	OBM_RGARROWI
OBM_LFARROWI	OBM_SIZE
OBM_MNARROW	OBM_UPARROW
OBM_OLD_CLOSE	OBM_UPARROWD
OBM_OLD_DNARROW	OBM_UPARROWI
OBM_OLD_LFARROW	OBM_ZOOM
OBM_OLD_REDUCE	OBM_ZOOMD
Bitmap names that begin with OBM_OLD represent bitmaps used by Windows versions earlier than 3.0.

For an application to use any of the OBM_ constants, the constant OEMRESOURCE must be defined before the WINDOWS.H header file is included.

The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.

See Also

»DeleteObject«, »LoadCursor«, »LoadIcon«, »CreateBitmap«


  LoadCursor

HCURSOR LoadCursor(hinst, lpszCursor)
HINSTANCE  hinst;   /* handle of application instance */
LPCTSTR  lpszCursor;   /* name string or cursor resource identifier */

The LoadCursor function loads the specified cursor resource from the executable file associated with the given application instance.

Parameters

hinst

Identifies an instance of the module whose executable file contains the cursor to be loaded.

lpszCursor

Points to a null-terminated string that contains the name of the cursor resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can also be used to create this value.

To use one of the Win32 predefined cursors, the application must set the hinst parameter to NULL and the lpszCursor parameter to one the following values:

Value	Description
IDC_APPSTARTING	Standard arrow and small hourglass
IDC_ARROW	Standard arrow
IDC_CROSS	Crosshair
IDC_IBEAM	Text I-beam
IDC_ICON	Empty icon
IDC_NO	Slashed circle
IDC_SIZE	Four-pointed arrow
IDC_SIZEALL	Same as IDC_SIZE
IDC_SIZENESW	Double-pointed arrow pointing northeast and southwest
IDC_SIZENS	Double-pointed arrow pointing north and south
IDC_SIZENWSE	Double-pointed arrow pointing northwest and southeast
IDC_SIZEWE	Double-pointed arrow pointing west and east
IDC_UPARROW	Vertical arrow
IDC_WAIT	Hourglass
Return Value

If the function succeeds, the return value is the handle of the newly loaded cursor; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

This function only loads the cursor resource if it has not been loaded; otherwise, it retrieves the handle of the existing resource. LoadCursor returns a valid cursor handle only if the lpszCursor parameter points to a cursor resource. If lpszCursor points to any type of resource other than a cursor (such as an icon), the return value is not NULL, even though it is not a valid cursor handle.

The LoadCursor function searches the cursor resource for the cursor most appropriate for the current display device. The cursor resource can be a color or monochrome bitmap.

See Also

»SetCursor«, »ShowCursor«, »SetCursorPos«


  LoadIcon

HICON LoadIcon(hinst, lpszIcon)
HINSTANCE  hinst;   /* handle of application instance */
LPCTSTR  lpszIcon;   /* icon-name string or icon resource identifier */

The LoadIcon function loads the specified icon resource from the executable file associated with the given application instance.

Parameters

hinst

Identifies an instance of the module whose executable file contains the icon to be loaded. This parameter must be NULL when a standard icon is being loaded.

lpszIcon

Points to a null-terminated string that contains the name of the icon resource to be loaded. Alternatively, this parameter can contain the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can be used to create this value.

To use one of the Windows predefined icons, set the hinst parameter to NULL and the lpszIcon parameter to one the following values:

Value	Description
IDI_APPLICATION	Default application icon.
IDI_ASTERISK	Asterisk (used in informative messages).
IDI_EXCLAMATION	Exclamation point (used in warning messages).
IDI_HAND	Hand-shaped icon (used in serious warning messages).
IDI_QUESTION	Question mark (used in prompting messages).
Return Value

If the function succeeds, the return value is the handle of the newly loaded icon; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

LoadIcon loads the icon resource only if it has not been loaded; otherwise, it retrieves a handle to the existing resource. The function searches the icon resource for the icon most appropriate for the current display. The icon resource can be a color or monochrome bitmap.

See Also

»CreateIcon«


  LoadKeyboardLayout

HKL LoadKeyboardLayout(lpszKLName, fuFlags)
LPTSTR  lpszKLName;   /* address of buffer for layout name  */
UINT  fuFlags;   /* keyboard layout flags */

The LoadKeyboardLayout function loads a keyboard layout.

Parameters

lpszKLName

Points to the buffer that specifies the name of the keyboard layout. The name should be derived from the hexadecimal value of the language identifier corresponding to the layout. For example, US English has a language identifier of 0x0409, so the primary US English layout is named "00000409". Variants of US English layout, such as the Dvorak layout, are named "00010409",  "00020409" and so on. For a list of the primary language identifiers and sub-language identifiers that make up a language identifier, see the description of the MAKELANGID macro in Microsoft Win32 Programmer's Reference, Volume 5.

fuFlags

Specifies how the keyboard layout is to be loaded. This parameter can be one of the following values:

Value	Meaning
KLF_ACTIVATE	The layout is loaded (if it is not already loaded) and activated.
KLF_REORDER	This flag is only meaningful if the KLF_ACTIVATE is set and the layout is already loaded. If these conditions are met, and the KLF_REORDER bit is set, the specified layout is removed from its position in the system's circular list of loaded layouts and placed at the head as the active layout.
	If the KLF_ACTIVATE bit is set and the layout is loaded but the KLF_REORDER bit is not set, the system's circular list of loaded layouts is simply rotated.
	If the KLF_ACTIVATE flag is set and the layout is not already loaded, it is loaded as the active layout and inserted in the system's circular list of keyboard layouts ahead of the previously active layout.
KLF_SUBSTITUTE_OK	The specified layout is looked up in the user's profile (in the registry under the key HKEY_CURRENT_USER\Keyboard Layout\Substitutes) to find a substitution layout prefered by the user. For example, if there was a value in this section of name "00000409" equal to "00010409", loading the US English layout ("00000409") with the KLF_SUBSTITUTES_OK flag set would cause the Dvorak US English layout ("00010409") to be loaded.
KLF_UNLOADPREVIOUS	The previously active layout is unloaded.
Return Value

If the function succeeds, the return value is the handle of the keyboard layout; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

Several keyboard layouts can be loaded at a time, but only one at a time is active. Loading multiple keyboard layouts makes it possible to rapidly switch between layouts.

See Also

»ActivateKeyboardLayout«, »UnloadKeyboardLayout«


  LoadLibrary

HANDLE LoadLibrary(lpszLibFile)
LPCTSTR  lpszLibFile;   /* address of file name of executable module */

The LoadLibrary function maps the specified executable module into the address space of the calling process.

Parameters

lpszLibFile

Points to a null-terminated string that names the Win32 module (.DLL or .EXE). The name specified is the filename of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition file.

If the string specifies a path but the file does not exist in the specified directory, the function fails.

If a path is not specified and the file extension is omitted, the default library file extension .DLL is appended. However, the filename string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for the file in the following sequence:

1.	The directory from which the application loaded.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

The first directory searched is the one directory containing the image file used to create the calling process (see the »CreateProcess« function). This allows private dynamic-link library files associated with a process to be found without adding the process's installed directory to the PATH environment variable.

Once the function obtains a fully qualified path to a library module file, the path is compared (case independently) to the full paths of library modules currently loaded into the calling process. This includes libraries loaded when the process was starting up as well as those previously loaded by LoadLibrary but not unloaded by FreeLibrary. If the path matches the path of an already loaded module, the function just increments the reference count for the module and returns the module handle for that library.

Return Value

If the function succeeds, the return value is a handle to the module; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

LoadLibrary can be used to map a dynamic-link library (DLL) module and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to map other executable modules. For example, the function can specify an .EXE file to get a handle that can be used in FindResource or LoadResource.

Module handles are not global or inheritable, in that a LoadLibrary call by one process does not produce a handle another process can use, for example, in calling GetProcAddress. The other process must make its own call to LoadLibrary for the module before calling GetProcAddress.

If the module is a DLL not already mapped for the calling process, the system calls the DLL's DllEntryPoint function with the DLL_PROCESS_ATTACH flag. If the DLL's entrypoint function does not return TRUE, LoadLibrary fails and returns NULL.

See Also

»DllEntryPoint«, »FreeLibrary«, »FindResource«, »GetProcAddress«, »GetSystemDirectory«, »GetWindowsDirectory«, »LoadResource«


  LoadLibraryEx

HINSTANCE LoadLibraryEx(lpszLibFile, hFile, dwFlags)
LPCTSTR  lpszLibFile;   /* address of library-file name */
HANDLE  hFile;   /* reserved; must be NULL */
DWORD  dwFlags;   /* entrypoint execute flag */

The LoadLibraryEx function maps the specified executable module into the address space of the calling process.

Parameters

lpszLibFile

Points to a null-terminated string that names the Win32 module (.DLL or .EXE). The name specified is the filename of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition file.

If the string specifies a path but the file does not exist in the specified directory, the function fails.

If a path is not specified and the file extension is omitted, the default library extension .DLL is appended. However, the filename string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for the file in the following sequence:

1.	The directory in which the executable module for the calling process is located.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetSystemDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

hFile

Reserved; must be NULL.

dwFlags

If lpszLibFile is a dynamic-link library (DLL), specifies whether to call the DllEntryPoint function. If this parameter is zero, LoadLibraryEx is identical to the LoadLibrary function. If the DONT_RESOLVE_DLL_REFERENCES flag is specified, the DllEntryPoint function is not used for process and thread initialization and termination.

Return Value

If the function succeeds, the return value is a handle to the mapped library module; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The LoadLibraryEx function is identical to the LoadLibrary function except that it enables the option of mapping a DLL module without calling the DLL's DllEntryPoint function.

The calling process can use the returned handle to identify the module in the GetProcAddress, FindResource, and LoadResource functions.

See Also

»FreeLibrary«, »GetProcAddress«, »LoadLibrary«


  LoadMenu

HMENU LoadMenu(hinst, lpMenuName)
HINSTANCE  hinst;   /* handle of application instance */
LPCTSTR  lpMenuName;   /* menu name string or menu-resource identifier */

The LoadMenu function loads the specified menu resource from the executable file associated with the given application instance.

Parameters

hinst

Identifies the instance of the module containing the menu resource to be loaded.

lpMenuName

Points to a null-terminated string that contains the name of the menu resource. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. To create this value, use the MAKEINTRESOURCE macro.

Return Value

If the function succeeds, the return value is the handle of the menu resource; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The DestroyMenu function is used before an application closes to destroy the menu and free memory that the loaded menu occupied.

See Also

»LoadMenuIndirect«


  LoadMenuIndirect

HMENU LoadMenuIndirect(lpMenuTemplate)
CONST MENUTEMPLATE  *lpMenuTemplate;   /* address of menu template */

The LoadMenuIndirect function loads the specified menu template in memory.

Parameters

lpMenuTemplate

Points to a menu template, consisting of a MENUITEMTEMPLATEHEADER structure followed by one or more MENUITEMTEMPLATE structures, each of which defines a menu item. The MENUITEMTEMPLATEHEADER structure has the following form:

typedef struct {    /* mith */

    WORD versionNumber;

    WORD offset;

} MENUITEMTEMPLATEHEADER;

The MENUITEMTEMPLATE structure has the following form:

typedef struct {    /* mit */

    WORD mtOption;

    WORD mtID;

    WCHAR mtString[1];

} MENUITEMTEMPLATE;

For full descriptions of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the menu; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

For both the ANSI and the Unicode version of this function, the strings in the MENUITEMTEMPLATE structure must be Unicode strings.

See Also

»LoadMenu«


  LoadModule

DWORD LoadModule(lpszModule, lpvParamBlock)
LPCSTR  lpszModule;   /* address of filename to load */
LPVOID  lpvParamBlock;   /* address of parameter block for new module */

The LoadModule function loads and executes a Windows-based application or creates a new instance of an existing Windows-based application.

This function is provided for compatibility with earlier versions of Window. For Win32 applications, use the CreateProcess function.

Parameters

lpszModule

Points to a null-terminated string that contains the filename of the application to run. If the lpszModule string does not contain a directory path, Windows searches for the executable file in this order:

1.	The directory from which the application loaded.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

lpvParamBlock

Points to a LOADPARMS32 structure that defines the new application's parameter block. The LOADPARMS32 structure has the following form:

typedef struct tagLOADPARMS32 {

    LPSTR lpEnvAddress;  /* address of environment strings */

    LPSTR lpCmdLine;     /* address of command line        */

    LPSTR lpCmdShow;     /* how to show new program        */

    DWORD dwReserved;    /* must be zero                   */

} LOADPARMS32;

Member	Description
lpEnvAddress	Points to an array of null-terminated strings that supply the environment strings for the new process. The array has a value of NULL as its last entry. A value of NULL for this parameter causes the new process to start with the same environment as the calling process.
lpCmdLine	Points to a Pascal-style string that contains a correctly-formed command line. The first byte of the string contains the number of bytes in the string. The remainder of the string contains the command line arguments, excluding the name of the child process. If there are no command line arguments, this parameter must point to a zero length string; it cannot be NULL.
lpCmdShow	Points to a structure containing two WORD values. The first value must always be set to two. The second value specifies how the application window is to be shown and is used to supply the wShowWindow member of the STARTUPINFO parameter to CreateProcess. See the description of the nCmdShow parameter of the »ShowWindow« function for a list of acceptable values.
dwReserved	This parameter is reserved. It must be zero.
Set all unused members to NULL, except for lpCmdLine, which must point to a null string if it is not used.

Return Value

If the function succeeds, the return value is greater than 31; otherwise, it is an error code, which may be one of the following:

Value	Meaning
0	The system is out of memory or resources.
ERROR_FILE_NOT_FOUND	The specified file was not found.
ERROR_PATH_NOT_FOUND	The specified path was not found.
ERROR_BAD_FORMAT	The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
Comments

Win32 applications should use the CreateProcess function. In the Win32 API, the implementation of the LoadModule function calls the CreateProcess function. The following section describes how each parameter for the CreateProcess function is formed:

CreateProcess parameter	Value
lpszImageName	LoadModule lpszModule parameter
lpszCommandLine	LoadModule lpvParamBlock->lpCmdLine
lpsaProcess	NULL
lpsaThread	NULL
fInheritHandles	FALSE
fdwCreate	0
lpvEnvironment	LoadModule lpvParamBlock->lpEnvAddress
lpszCurDir	NULL
lpsiStartInfo	The structure is initialized to zero. The cb member is set to the size of the structure, and the wShowWindow member is set to the value of the second word of the LoadModule lpvParamBlock->lpCmdShow parameter.
lppiProcInfo.hProcess	The handle is immediately closed.
lppiProcInfo.hThread	The handle is immediately closed.
See Also

»CreateProcess«, »GetSystemDirectory«, »GetWindowsDirectory«, »ShowWindow«, »WinExec«


  LoadResource

HGLOBAL LoadResource(hModule, hResInfo)
HINSTANCE  hModule;   /* resource-module handle  */
HRSRC  hResInfo;   /* resource handle */

The LoadResource function loads the specified resource into global memory.

Parameters

hModule

Identifies the module whose executable file contains the resource. If hModule is NULL, Windows loads the resource from the module that was used to create the current process.

hResInfo

Identifies the resource to be loaded. This handle must be created by using the FindResource or FindResourceEx function.

Return Value

If the function succeeds, the return value is a handle to the global memory block containing the data associated with the resource. Otherwise, it is NULL. To get extended error information, us the GetLastError function.

Comments

It is not necessary to free a resource loaded by using the LoadResource function.

See Also

»FindResource«, »LoadLibrary«, »LoadModule«, »LockResource«


  LoadString

int LoadString(hinst, wID, lpBuffer, cchBuffer)
HINSTANCE  hinst;   /* handle of module containing string resource */
UINT  wID;   /* resource identifier */
LPTSTR  lpBuffer;   /* address of buffer for resource  */
int  cchBuffer;   /* size of buffer */

The LoadString function loads a string resource from the executable file associated with a specified module, copies the string into a buffer, and appends a terminating null character.

Parameters

hinst

Identifies an instance of the module whose executable file contains the string resource.

wID

Specifies the integer identifier of the string to be loaded.

lpBuffer

Points to the buffer to receive the string.

cchBuffer

Specifies the size of the buffer, in characters. The string is truncated and null terminated if it is longer than the number of characters specified.

Return Value

If the function succeeds, the return value is the number of characters copied into the buffer, not including the null-terminating character, or zero if the string resource does not exist. To get extended error information, use the GetLastError function.

See Also

»FormatMessage«, »LoadAccelerators«, »LoadBitmap«, »LoadCursor«, »LoadIcon«, »LoadMenu«, »LoadMenuIndirect«


  LocalAlloc

HLOCAL LocalAlloc(fuFlags, cbBytes)
UINT  fuFlags;   /* allocation attributes */
UINT  cbBytes;   /* number of bytes to allocate */

The LocalAlloc function allocates the specified number of bytes from the heap. In the linear Win32 API environment, there is no difference between the local heap and the global heap.

Parameters

fuFlags

Specifies how to allocate memory. If zero is specified, the default is the LMEM_FIXED flag. Except for the incompatible combinations that are specifically noted, any combination of the following flags can be specified. To indicate whether the function allocates fixed or movable memory, specify one of the first six flags:

Flag	Meaning
LMEM_FIXED
	Allocates fixed memory. This flag cannot be combined with the LMEM_MOVEABLE or LMEM_DISCARDABLE flag. The return value is a pointer to the memory block. To access the memory, the calling process simply casts the return value to a pointer.
LMEM_MOVEABLE
	Allocates movable memory. This flag cannot be combined with the LMEM_FIXED flag. The return value is the handle of the memory object. The handle is a 32-bit quantity that is private to the calling process. To translate the handle into a pointer, use the LocalLock function.
LPTR
	Combines the LMEM_FIXED and LMEM_ZEROINIT flags.
LHND
	Combines the LMEM_MOVEABLE and LMEM_ZEROINIT flags.
NONZEROLHND
	Same as the LMEM_MOVEABLE flag.
NONZEROLPTR
	Same as the LMEM_FIXED flag.
LMEM_DISCARDABLE
	Allocates discardable memory. This flag cannot be combined with the LMEM_FIXED flag. Some Win32 implementations may ignore this flag.
LMEM_NOCOMPACT
	Does not compact or discard memory to satisfy the allocation request.
LMEM_NODISCARD
	Does not discard memory to satisfy the allocation request.
LMEM_ZEROINIT
	Initializes memory contents to zero.
cbBytes

Specifies the number of bytes to allocate. If cbBytes is zero and the fuFlags parameter specifies the LMEM_MOVEABLE flag, this function returns a handle to a memory object that is marked as discarded.

Return Value

If the function succeeds, the return value is the handle of the newly allocated memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

If the heap does not contain sufficient free space to satisfy the request, this function returns NULL.

GlobalAlloc and LocalAlloc are limited to a combined total of 65,536 handles for GMEM_MOVEABLE and LMEM_MOVEABLE memory per process. This limitation does not apply to GMEM_FIXED or LMEM_FIXED memory.

If this function succeeds, it allocates at least the amount requested. If the amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the LocalSize function.

See Also

»GlobalAlloc«, »LocalFree«, »LocalLock«, »LocalReAlloc«, »LocalSize«


  LocalCompact

The LocalCompact function is obsolete.


  LocalDiscard

HLOCAL LocalDiscard(hlocMem)
HLOCAL  hlocMem;   /* handle of local memory object */

The LocalDiscard function discards the specified local memory object. The lock count of the memory object must be zero.

Parameters

hlocMem

Identifies the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Value

If the function succeeds, the return value is the handle of the local memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The LocalDiscard function discards only local objects allocated by a process with the LMEM_DISCARDABLE flag set. If a process attempts to discard a fixed or locked object, the function fails.

Although LocalDiscard discards the object's memory block, the handle of the object remains valid. A process can subsequently pass the handle to the LocalReAlloc function to allocate another local memory object identified by the same handle.

See Also

»LocalReAlloc«


  LocalFileTimeToFileTime

BOOL LocalFileTimeToFileTime(lpftLocal, lpft)
LPFILETIME  lpftLocal;   /* address of local file time to convert  */
LPFILETIME  lpft;   /* address of converted file time */

The LocalFileTimeToFileTime function converts a local file time to a file time based on the Universal Time Convention (UTC).

Parameters

lpftLocal

Points to a FILETIME structure that specifies the local file time to be converted into a UTC-based file time. The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpft

Points to a FILETIME structure to receive the converted UTC-based file time. This parameter cannot be the same as the lpftLocal parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»FileTimeToLocalFileTime«


  LocalFlags

UINT LocalFlags(hlocMem)
HLOCAL  hlocMem;   /* handle of local memory object */

The LocalFlags function returns information about the specified local memory object.

Parameters

hlocMem

Identifies the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Value

If the function succeeds, the return value is a 32-bit value that specifies the allocation flags and the lock count for the memory object; otherwise, it is the LMEM_INVALID_HANDLE flag, indicating that the local handle is not valid. To get extended error information, use the GetLastError function.

Comments

The low-order byte of the low-order word of the return value contains the lock count of the object. To retrieve the lock count from the return value, use the LMEM_LOCKCOUNT mask with the bitwise AND operator (&). The lock count of memory objects set with the LMEM_FIXED flag is always zero.

The high-order byte of the low-order word of the return value indicates the allocation flags of the memory object. It can be zero or any combination of the following flags:

Value	Description
LMEM_DISCARDABLE	The object's memory block can be discarded.
LMEM_DISCARDED	The object's memory block has been discarded.
See Also

»GlobalFlags«, »LocalAlloc«, »LocalDiscard«, »LocalLock«, »LocalReAlloc«, »LocalUnlock«


  LocalFree

HLOCAL LocalFree(hlocMem)
HLOCAL  hlocMem;   /* handle of local memory object */

The LocalFree function frees the specified local memory object and invalidates its handle.

Parameters

hlocMem

Identifies the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Value

If the function succeeds, the return value is NULL; otherwise, it is equal to the handle of the local memory object. To get extended error information, use the GetLastError function.

Comments

The LocalFree function fails if the memory object is locked, indicating a lock count greater than zero. The LocalLock function locks a local memory object and increments the lock count. The LocalUnlock function unlocks it and decrements the lock count. To get the lock count of a local memory object, use the LocalFlags function.

If the process tries to examine or modify the memory after it has been freed, heap corruption or an access violation exception (EXCEPTION_ACCESS_VIOLATION) may occur.

If the hlocMem parameter is NULL, LocalFree fails and the system generates an access violation exception.

See Also

»LocalAlloc«, »LocalFlags«, »LocalLock«, »LocalReAlloc«, »LocalUnlock«


  LocalHandle

HLOCAL LocalHandle(lpvMem)
LPVOID  lpvMem;   /* address of local memory object */

The LocalHandle function retrieves the handle associated with the specified pointer to a local memory object.

Parameters

lpvMem

Points to the first byte of the local memory object. This pointer is returned by the LocalLock function.

Return Value

If the function succeeds, the return value is the handle of the specified local memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

When the LocalAlloc function allocates a local memory object with the LMEM_MOVEABLE flag, it returns the handle of the object. The LocalLock function converts this handle into a pointer to the object's memory block, and LocalHandle converts the pointer back into a handle.

See Also

»LocalAlloc«, »LocalLock«


  LocalInit

The LocalInit function has been deleted.


  LocalLock

LPVOID LocalLock(hlocMem)
HLOCAL  hlocMem;   /* handle of local memory object */

The LocalLock function locks a local memory object and returns a pointer to the first byte of the object's memory block. The memory block associated with a locked memory object cannot be moved or discarded. For memory objects allocated with the LMEM_MOVEABLE flag, the function increments the object's lock count.

Parameters

hlocMem

Identifies the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Value

If the function succeeds, the return value is a pointer to the first byte of the memory block; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, LocalLock increments this count by one, and the LocalUnlock function decrements the count by one. For each call that a process makes to LocalLock for an object, it must eventually call LocalUnlock. Locked memory will not be moved or discarded unless the memory object is reallocated by using the LocalReAlloc function. The memory block of a locked memory object remains locked in memory until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the LMEM_FIXED flag always have a lock count of zero. For these objects, the value of the returned pointer is equal to the value of the specified handle.

If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL.

Discarded objects always have a lock count of zero.

See Also

»LocalFlags«, »LocalReAlloc«, »LocalUnlock«


  LocalReAlloc

HLOCAL LocalReAlloc(hlocMem, cbBytes, fuFlags)
HLOCAL  hlocMem;   /* handle of local memory object */
UINT  cbBytes;   /* new size of block */
UINT  fuFlags;   /* how to reallocate object */

The LocalReAlloc function changes the size or the attributes of a specified local memory object. The size can increase or decrease.

Parameters

hlocMem

Identifies the local memory object to be reallocated. This handle is returned by either the LocalAlloc or LocalReAlloc function.

cbBytes

Specifies the new size, in bytes, of the memory block. If cbBytes is zero and the fuFlags parameter specifies the LMEM_MOVEABLE flag, this function returns a handle to a memory object that is marked as discarded. This parameter is ignored if fuFlags specifies the LMEM_MODIFY flag.

fuFlags

Specifies how to reallocate the local memory object. If the LMEM_MODIFY flag is specified, this parameter modifies the attributes of the memory object, and the cbBytes parameter is ignored. Otherwise, this parameter controls the reallocation of the memory object.

The LMEM_MODIFY flag can be combined with either or both of the following flags:

Flag	Meaning
LMEM_DISCARDABLE
	This flag allocates discardable memory. This flag is used only if the LMEM_MODIFY flag is also specified. This flag is ignored, unless the object was previously allocated as movable, or the LMEM_MOVEABLE flag is also specified.
LMEM_MOVEABLE
	This flag changes a fixed memory object to a movable memory object, if the LMEM_MODIFY flag is also specified.
If fuFlags does not specify LMEM_MODIFY, the parameter can be a combination of any of the following flags:

Flag	Meaning
LMEM_MOVEABLE
	If cbBytes is zero, discards a previously movable and discardable memory block. If the object's lock count is not zero or the block is not movable and discardable, the function fails.
	If cbBytes is nonzero, this flag enables the system to move the reallocated block to a new location. This does not change the movable or fixed attribute of the memory object. If the object is fixed, the handle returned may be different from the handle specified in the hlocMem parameter. If the object is movable, the block can be moved without invalidating the handle. This can occur even if the object is currently locked by a previous call to the LocalLock function. To get the new address of the memory block, use LocalLock.
LMEM_NOCOMPACT
	This flag prevents memory from being compacted or discarded to satisfy the allocation request.
LMEM_ZEROINIT
	This flag causes the additional memory contents to be initialized to zero, if the memory object is growing in size.
Return Value

If the function succeeds, the return value is the handle of the reallocated memory object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

If LocalReAlloc reallocates a movable object, the return value is the handle of the memory object. To convert the handle to a pointer, use the LocalLock function.

If LocalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the memory block. To access the memory, a process can simply cast the return value to a pointer.

See Also

»LocalAlloc«, »LocalFree«, »LocalLock«


  LocalShrink

The LocalShrink function is obsolete.


  LocalSize

UINT LocalSize(hlocMem)
HLOCAL  hlocMem;   /* handle of local memory object */

The LocalSize function returns the current size, in bytes, of the specified local memory object.

Parameters

hlocMem

Identifies the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Value

If the function succeeds, the return value is the size, in bytes, of the specified local memory object. If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error information, use the GetLastError function.

Comments

The size of a memory block may be larger than the size requested when the memory was allocated.

To verify that the specified object's memory block has not been discarded, call the LocalFlags function before calling LocalSize.

See Also

»LocalAlloc«, »LocalFlags«, »LocalReAlloc«


  LocalUnlock

BOOL LocalUnlock(hlocMem)
HLOCAL  hlocMem;   /* handle of local memory object */

The LocalUnlock function decrements the lock count associated with a memory object that was allocated with the LMEM_MOVEABLE flag. This function has no effect on memory objects allocated with the LMEM_FIXED flag.

Parameters

hlocMem

Identifies the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Value

If the object's lock count is decremented to zero, the return value is FALSE; otherwise, it is TRUE. To get extended error information, use the GetLastError function.

Comments

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the LocalLock function increments this count by one, and LocalUnlock decrements the count by one. For each call that a process makes to LocalLock for an object, it must eventually call LocalUnlock. Locked memory will not be moved or discarded unless the memory object is reallocated by using the LocalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the LMEM_FIXED flag always have a lock count of zero. If the specified memory block is fixed memory, this function returns nonzero.

A process should not rely on the return value to determine the number of times it must subsequently call LocalUnlock for the memory block.

See Also

»LocalFlags«, »LocalLock«


  LockFile

BOOL LockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, cbLockLow, cbLockHigh)
HANDLE  hFile;   /* handle of file to lock */
DWORD  dwFileOffsetLow;   /* low-order word of lock region offset */
DWORD  dwFileOffsetHigh;   /* high-order word of lock region offset */
DWORD  cbLockLow;   /* low-order word of length to lock */
DWORD  cbLockHigh;   /* high-order word of length to lock */

The LockFile function locks a region in an open file. Locking a region prevents other processes from accessing the region.

Parameters

hFile

Identifies the file with a region to be locked. The file handle must have been created with GENERIC_READ or GENERIC_WRITE access to the file (or both).

dwFileOffsetLow

Specifies the low-order word of the starting byte offset in the file where the lock should begin.

dwFileOffsetHigh

Specifies the high-order word of the starting byte offset in the file where the lock should begin.

cbLockLow

Specifies the low-order word of the length of the byte range to be locked.

cbLockHigh

Specifies the high-order word of the length of the byte range to be locked.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Locking a region of a file gives the locking process exclusive access to the specified region. File locks are not inherited by processes created by the locking process.

Locking a region of a file denies all other processes both read and write access to the specified region. Locking a region that goes beyond the current end-of-file position is not an error.

Locks may not overlap an existing locked region of the file.

The UnlockFile function unlocks a file region locked by LockFile.

For systems using a FAT-based file system and running SHARE.EXE, the lock semantics work as described above. Without SHARE.EXE, all attempts to lock or unlock a file fail.

See Also

»CreateFile«, »UnlockFile«


  LockFileEx

BOOL LockFileEx(hFile, dwFlags, dwReserved, nNumberOfBytesToLockLow,
nNumberOfBytesToLockHigh, lpOverlapped)
HANDLE  hFile;   /* handle of file to lock */
DWORD  dwFlags;   /* functional behavior modification flags */
DWORD  dwReserved;   /* reserved; must be set to zero */
DWORD  nNumberOfBytesToLockLow;   /* low order 32-bits of length to lock */
DWORD  nNumberOfBytesToLockHigh;   /* high order 32-bits of length to lock */
LPOVERLAPPED  lpOverlapped;   /* pointer to struct with lock region start offset */

The LockFileEx function locks a byte range within an open file for shared or exclusive access.

Parameters

hFile

Supplies an open handle to a file that is to have a range of bytes locked for shared or exclusive access. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.

dwFlags

Supplies flag bits that modify the behavior of this function. You may set one or more of the following flags:

Value	Meaning
LOCKFILE_FAIL_IMMEDIATELY	If set, the function returns immediately if it is unable to acquire the requested lock. Otherwise it waits.
LOCKFILE_EXCLUSIVE_LOCK	If set, the function requests an exclusive lock. Otherwise it requests a shared lock.
dwReserved

Reserved parameter that must be set to zero.

nNumberOfBytesToLockLow

Supplies the low order 32-bits of the length of the byte range to lock.

nNumberOfBytesToLockHigh

Supplies the high order 32-bits of the length of the byte range to lock.

lpOverlapped

Required pointer to an OVERLAPPED data structure that the function uses with the locking request. This structure contains the file offset of the beginning of the lock range. The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE/NULL. Use the GetLastError function to obtain extended error information.

Comments

Locking a region of a file is used to acquire shared or exclusive access to the specified region of the file. File locks are not inherited by a new process during process creation.

Locking a portion of a file for exclusive access denies all other processes both read and write access to the specified region of the file. Locking a region that goes beyond the current end-of-file position is not an error.

Locking a portion of a file for shared access denies all other processes write access to the specified region of the file, but allows other processes to read the locked region.

If requesting an exclusive lock for a file that is already locked shared or exclusively by other threads, then this call waits until the lock is granted, unless the LOCKFILE_FAIL_IMMEDIATELY flag is specified.

Locks may not overlap an existing locked region of the file.

See Also

»CreateFile«, »LockFile«, »UnlockFile«, »UnlockFileEx«


  LockResource

LPVOID LockResource(hglb)
HGLOBAL  hglb;   /* handle to resource to lock */

The LockResource function locks the specified resource in memory.

Parameters

hglb

Identifies the resource to be locked. The LoadResource function returns this handle.

Return Value

If the loaded resource is locked, the return value is a pointer to the first byte of the resource; otherwise, it is NULL.

Comments

It is not necessary for Win32 applications to unlock resources locked by using the LockResource function.

Trying to lock a resource by using the handle returned by the FindResource or FindResourceEx function will not work. You will get back a value that is incorrect and points to random data.

See Also

»FindResource«, »FindResourceEx«, »LoadResource«


  LockSegment

The LockSegment function is obsolete.


  LockServiceDatabase

SC_LOCK LockServiceDatabase(schSCManager)
SC_HANDLE  schSCManager;   /* handle of service control manager database */

The LockServiceDatabase function locks a specified database.

Parameters

schSCManager

Identifies the service control manager database. The OpenSCManager function returns this handle, which must have SC_MANAGER_LOCK access.

Return Value

If the function succeeds, the return value is a lock to the specified service control manager database; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Errors

The following error code may be set by the service control manager. Other error codes may be set by registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with SC_MANAGER_LOCK access.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_SERVICE_DATABASE_LOCKED
	The database is locked.
Comments

The LockServiceDatabase function tries to acquire a lock on the specified database. Only one process at a time can have a lock on a database.

A lock is a protocol used by setup and configuration programs and the service control manager to serialize access to the service tree in the registry. The only time the service control manager acquires a lock is when it is starting a service. Setup and configuration programs are expected to acquire a lock before using the ChangeServiceConfig or SetServiceObjectSecurity function to reconfigure a service. They should also acquire a lock before using the registry functions to reconfigure a service. The lock prevents the service control manager from starting a service while it is being reconfigured.

A call to the StartService function to start a service in a locked database fails. All other service control manager functions are not affected by a lock.

The lock is held until the SC_LOCK handle is specified in a subsequent call to the UnlockServiceDatabase function. If a process that is holding a lock terminates, the service control manager automatically cleans up and releases the lock.

See Also

»ChangeServiceConfig«, »OpenSCManager«, »QueryServiceLockStatus«, »SetServiceObjectSecurity«, »StartService«, »UnlockServiceDatabase«


  LockWindowUpdate

BOOL LockWindowUpdate(hwndLock)
HWND  hwndLock;   /* handle of window to lock */

The LockWindowUpdate function disables or reenables drawing in the given window. Only one window can be locked at a time.

Parameters

hwndLock

Specifies the window in which drawing will be disabled. If this parameter is NULL, drawing in the locked window is enabled.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE, indicating an error occurred or another window was already locked.

Comments

If an application with a locked window (or any locked child windows) calls the GetDC, GetDCEx, or BeginPaint function, the called function returns a device context whose visible region is empty. This will occur until the application unlocks the window by calling LockWindowUpdate, specifying a value of NULL for hwndLock.

If an application attempts to draw within a locked window, the system records the extent of the attempted operation in a bounding rectangle. When the window is unlocked, the system invalidates the area within this bounding rectangle, forcing an eventual WM_PAINT message to be sent to the previously locked window and its child windows. If no drawing has occurred while the window updates were locked, no area is invalidated.

LockWindowUpdate does not make the given window invisible and does not clear the WS_VISIBLE style bit.

A locked window cannot be moved.

See Also

»BeginPaint«, »GetDC«, »GetDCEx«


  LookupAccountName

BOOL LookupAccountName(lpszSystem, lpszAccount, psid, lpcbSid,
lpszReferencedDomain, lpcchReferencedDomain, psnu)
LPTSTR  lpszSystem; 	/* address of string for system name	 */
LPTSTR  lpszAccount;   /* address of string for account name */
PSID  psid;   /* address of security identifier  */
LPDWORD  lpcbSid;   /* address of size of security identifier  */
LPTSTR  lpszReferencedDomain;   /* address of string for referenced domain  */
LPDWORD  lpcchReferencedDomain;   /* address of size of domain string   */
PSID_NAME_USE  psnu;   /* address of SID-type indicator  */

The LookupAccountName function accepts the name of a system and an account as input. It retrieves a security identifier (SID) for the account and the name of the domain on which the account was found.

Parameters

lpszSystem

Points to a null-terminated string specifying the system. This string can be the name of a remote computer. If this string is NULL, the account name is looked up on the local system.

lpszAccount

Points to a null-terminated string specifying the account name.

psid

Points to a buffer receiving the SID structure that corresponds to the account name pointed to by the lpszAccount parameter.

lpcbSid

Specifies the size of the buffer pointed to by the psid parameter. If the specified size is too small, the function sets this variable to the required buffer size.

lpszReferencedDomain

Points to a buffer receiving the name of the domain where the account name is found.

lpcchReferencedDomain

Specifies the size of the lpszReferencedDomain buffer in characters. If the specified size is too small, the function sets this variable to the required buffer size.

psnu

Points to an SID_NAME_USE enumerated type indicating the type of the account when the function returns.

The SID_NAME_USE enumerated type has the following form:

typedef enum tagSID_NAME_USE {

    SidTypeUser = 1,

    SidTypeGroup,

    SidTypeDomain,

    SidTypeAlias,

    SidTypeWellKnownGroup,

    SidTypeDeletedAccount,

    SidTypeInvalid,

    SidTypeUnknown

} SID_NAME_USE;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The LookupAccountName function attempts to find a security identifier for the specified name by first checking a list of well-known SIDs. If the name does not correspond to a well-known SID, the function checks built-in and administratively defined local accounts. Next, the function checks the primary domain. If the name is not found there, trusted domains are checked.

See Also

»EqualPrefixSid«, »GetUserName«, »LookupAccountSid«


  LookupAccountSid

BOOL LookupAccountSid(lpszSystem, psid, lpszAccount, lpcchAccount,
lpszReferencedDomain, lpcchReferencedDomain, psnu)
LPTSTR  lpszSystem;   /* address of string for system name  */
PSID  psid;   /* address of security identifier  */
LPTSTR  lpszAccount;   /* address of string for account name  */
LPDWORD  lpcchAccount;   /* address of size account string  */
LPTSTR  lpszReferencedDomain;   /* address of string for referenced domain  */
LPDWORD  lpcchReferencedDomain;   /* address of size domain string   */
PSID_NAME_USE  psnu;   /* address of structure for SID type  */

The LookupAccountSid function accepts a security identifier (SID) as input. It retrieves the name of the account for this SID and the name of the first domain on which this SID is found.

Parameters

lpszSystem

Points to a null-terminated string specifying the system. This string can be the name of a remote computer. If this string is NULL, the SID is looked up on the local system.

psid

Points to a SID structure for which the account name is looked up.

lpszAccount

Points to a buffer receiving a null-terminated string representing the account name corresponding to the psid parameter.

lpcchAccount

Specifies the size of the buffer pointed to by the lpszAccount parameter. If the specified size is too small, the function sets this variable to the required buffer size.

lpszReferencedDomain

Points to a buffer that will receive a null-terminated string giving the name of the domain where the account name was found.

For Windows NT systems, the domain name returned for most accounts in the local computer's security database is the computer's name as of the last start of the system. Backslashes are excluded. If the computer's name changes, the old name continues to be returned as the domain name until the system is restarted.

For Windows NT Advanced Server systems, the domain name returned for most accounts in the local computer's security database is the name of the domain for which the Advanced Server is a domain controller.

Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN.

lpcchReferencedDomain

Specifies the size of the buffer pointed to by the lpszReferencedDomain parameter. If the specified size is too small, the function sets this variable to the required buffer size.

psnu

Points to an SID_NAME_USE enumerated type indicating the type of the account when the function returns.

The SID_NAME_USE enumerated type has the following form:

typedef enum tagSID_NAME_USE {

    SidTypeUser = 1,

    SidTypeGroup,

    SidTypeDomain,

    SidTypeAlias,

    SidTypeWellKnownGroup,

    SidTypeDeletedAccount,

    SidTypeInvalid,

    SidTypeUnknown

} SID_NAME_USE;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The LookupAccountSid function attempts to find a name for the specified security identifier by first checking a list of well-known SIDs. If the supplied SID does not correspond to a well-known SID, the function checks built-in and administratively defined local accounts. Next, the function checks the primary domain. Security identifiers not recognized by the primary domain are checked against the trusted domains corresponding to their SID prefixes.

See Also

»EqualPrefixSid«, »LookupAccountName«


  LookupIconIdFromDirectory

int LookupIconIdFromDirectory(presbits, fIcon)
PBYTE  presbits;   /* address of resource data   */
BOOL  fIcon;   /* look for icon or cursor  */

The LookupIconIdFromDirectory function searches through icon or cursor data for the icon or cursor that best fits the current display device.

Parameters

presbits

Points to the icon or cursor directory data. Because this function does not validate the resource data, this function will cause a general protection (GP) fault or return an undefined value if presbits is not pointing to valid resource data.

fIcon

Specifies whether an icon or a cursor is sought. If this parameter is TRUE, the function is searching for an icon; if the parameter is FALSE, the function is searching for a cursor.

Return Value

If the function succeeds, the return value is an integer resource identifier for the icon or cursor that best fits the current display device.

Comments

A resource file of type RT_GROUP_ICON (RT_GROUP_CURSOR indicates cursors) contains icon (or cursor) data in several device-dependent and device-independent formats. LookupIconIdFromDirectory searches the resource file for the icon (or cursor) that best fits the current display device and returns its integer identifier. FindResource and FindResourceEx use the MAKEINTRESOURCE macro on this identifier to locate the resource in the module.

The icon directory is loaded from a resource file with resource type RT_GROUP_ICON (or RT_GROUP_CURSOR for cursors), and an integer resource name for the specific icon to be loaded. LookupIconIdFromDirectory returns an integer identifier that is the resource name of the icon that best fits the current display device.

The LoadIcon and LoadCursor functions use this function to search the specified resource data for the icon or cursor that best fits the current display device.

For more information and a code sample that uses this function, see Microsoft Win32 Programmer's Reference, Volume 1, Chapter 23, "Icons."

See Also

»CreateIconFromResource«, »CreateIconIndirect«, »GetIconInfo«


  LookupPrivilegeDisplayName

BOOL LookupPrivilegeDisplayName(lpszSystemName, lpszProgramName,
lpszDisplayName, lpcchDisplayName, lpdwLanguageId)
LPTSTR  lpszSystemName;   /* address of string specifying the system  */
LPTSTR  lpszProgramName;   /* address of string specifying the privilege  */
LPTSTR  lpszDisplayName;   /* address of string receiving the displayable name  */
LPDWORD  lpcchDisplayName;   /* address of size of string for displayable name  */
LPDWORD  lpdwLanguageId;   /* address of language identifier  */

The LookupPrivilegeDisplayName function retrieves a displayable name representing a specified privilege.

Parameters

lpszSystemName

Points to a null-terminated string specifying the name of the system on which the displayable privilege name is looked up. If a null string is specified, the function attempts to find the displayable name on the local system.

lpszProgramName

Points to a null-terminated string specifying the name of the privilege, as defined in the WINNT.H header file. For example, this string could be SE_REMOTE_SHUTDOWN_NAME.

lpszDisplayName

Points to a buffer receiving a null-terminated string giving the privilege's displayable name. For example, if the lpszProgramName parameter is SE_REMOTE_SHUTDOWN_NAME, the displayable name is, "Force shutdown from a remote system".

lpcchDisplayName

Points to a variable specifying the size, in characters, of the lpszDisplayName buffer. When the function returns, this parameter contains the length of the displayable privilege name, not including the terminating null character. If the buffer pointed to by the lpszDisplayName parameter is too small, this variable contains the required size when the function returns.

lpdwLanguageId

Points to a variable receiving the language identifier for the returned displayable name.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

For this release of Windows NT, only the privileges specified in the Defined Privileges section of WINNT.H are supported by this function.

See Also

»LookupPrivilegeName«, »LookupPrivilegeValue«


  LookupPrivilegeName

BOOL LookupPrivilegeName(lpszSystemName, pluid, lpszProgramName, lpcchName)
LPTSTR  lpszSystemName;   /* address of string specifying the system  */
PLUID  pluid;   /* address of locally unique identifier  */
LPTSTR  lpszProgramName;   /* address of string specifying the privilege  */
LPDWORD  lpcchName;   /* address of size of string for displayable name  */

The LookupPrivilegeName function retrieves the name corresponding to the privilege represented on a specific system by a specified locally unique identifier (LUID).

Parameters

lpszSystemName

Points to a null-terminated string specifying the name of the system on which the privilege name is looked up. If a null string is specified, the function attempts to find the privilege name on the local system.

pluid

Points to the locally unique identifier by which the privilege is known on the target system.

lpszProgramName

Points to a buffer receiving a null-terminated string that represents the privilege's name. For example, this string could be SE_SECURITY_NAME.

lpcchName

Points to a variable specifying the size, in characters, of the lpszProgramName buffer. When the function returns, this parameter contains the length of the privilege name, not including the terminating null character. If the buffer pointed to by the lpszProgramName parameter is too small, this variable contains the required size when the function returns.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

For this release of Windows NT, only the privileges specified in the Defined Privileges section of WINNT.H are supported by this function.

See Also

»LookupPrivilegeDisplayName«, »LookupPrivilegeValue«


  LookupPrivilegeValue

BOOL LookupPrivilegeValue(lpszSystemName, lpszPrivilege, pluid)
LPTSTR  lpszSystemName;   /* address of string specifying the system  */
LPTSTR  lpszPrivilege;   /* address of string specifying the privilege   */
PLUID  pluid;   /* address of locally unique identifier  */

The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.

Parameters

lpszSystemName

Points to a null-terminated string specifying the name of the system on which the privilege name is looked up. If a null string is specified, the function attempts to find the privilege name on the local system.

lpszPrivilege

Points to a null-terminated string specifying the privilege's name. For example, this string could be "SE_SECURITY_NAME".

pluid

Points to a variable receiving the locally unique identifier by which the privilege is known on the system specified by the lpszSystemName parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

For this release of Windows NT, only the privileges specified in the Defined Privileges section of WINNT.H are supported by this function.

See Also

»LookupPrivilegeDisplayName«, »LookupPrivilegeName«


  _lopen

HFILE _lopen(lpszFileName, fnOpenMode)
LPCSTR  lpszFileName;   /* address of name of file to open   */
int  fnOpenMode;   /* file access mode  */

The _lopen function opens an existing file and sets the file pointer to the beginning of the file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the CreateFile function.

Parameters

lpszFileName

Points to a null-terminated string that names the file to open. The string must consist of characters from the Windows ANSI character set.

fnOpenMode

Specifies the modes in which to open the file. This parameter consists of one access mode and an optional share mode. The access mode must be one of the following:

Value	Meaning
OF_READ	Opens the file for reading from only.
OF_READWRITE	Opens the file for reading from and writing to.
OF_WRITE	Opens the file for writing to only.
The share mode can be one of the following:

Value	Meaning
OF_SHARE_COMPAT	Opens the file in compatibility mode, enabling any process on a given computer to open the file any number of times. If the file has been opened by using any of the other share modes, lopen fails.
OF_SHARE_DENY_NONE	Opens the file without denying other processes read or write access to the file. If the file has been opened in compatibility mode by any other process, _lopen fails.
OF_SHARE_DENY_READ	Opens the file and denies other processes read access to the file. If the file has been opened in compatibility mode or for read access by any other process, _lopen fails.
OF_SHARE_DENY_WRITE	Opens the file and denies other processes write access to the file. If the file has been opened in compatibility mode or for write access by any other process, _lopen fails.
OF_SHARE_EXCLUSIVE	Opens the file in exclusive mode, denying other processes both read and write access to the file. If the file has been opened in any other mode for read or write access, even by the current process, _lopen fails.
Return Value

If the function succeeds, the return value is a file handle; otherwise, it is HFILE_ERROR. To get extended error information, use the GetLastError function.

See Also

»CreateFile«


  LPtoDP

BOOL LPtoDP(hdc, lpPoints, nCount)
HDC  hdc;   /* handle of device context  */
LPPOINT  lpPoints;   /* array of points   */
int  nCount;   /* count of points  */

The LPtoDP function converts logical coordinates into device coordinates. The conversion depends on the mapping mode of the device context (DC), the settings of the origins and extents for the window and viewport, and the world transformation.

Parameters

hdc

Identifies the DC.

lpPoints

Points to an array of POINT structures. The x-coordinates and y-coordinates contained in each of the POINT structures will be transformed. The POINT structure has the following form:

typedef struct tagPOINT { /* pt  */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

nCount

Specifies the number of points in the array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function fails if the logical coordinates exceed 32 bits, or if the converted device coordinates exceed 27 bits. In the case of such an overflow, the results for all the points are undefined.

See Also

»DPtoLP«


  _lread

UINT _lread(hFile, lpBuffer, cbRead)
HFILE  hFile;   /* handle of file  */
LPVOID  lpBuffer;   /* address of buffer for read data  */
UINT  cbRead;   /* length, in bytes, of data buffer  */

The _lread function reads data from the specified file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the ReadFile function.

Parameters

hFile

Identifies the specified file.

lpBuffer

Points to a buffer that contains the data read from the file.

cbRead

Specifies the number of bytes to read from the file.

Return Value

The return value indicates the number of bytes actually read from the file. If the number of bytes read is less than cbRead, the function has reached the end of the file (EOF) before reading the specified number of bytes. If the function fails, the return value is HFILE_ERROR. To get extended error information, use the GetLastError function.

See Also

»_lwrite«, »ReadFile«


  lstrcat

LPTSTR lstrcat(lpszString1, lpszString2)
LPTSTR  lpszString1;   /* address of buffer for concatenated strings   */
LPCTSTR  lpszString2;   /* address of string to add to string1  */

The lstrcat function appends one string to another.

Parameters

lpszString1

Points to a byte array containing a null-terminated string. The byte array must be large enough to contain both strings.

lpszString2

Points to the null-terminated string to be appended to the string specified in the lpszString1 parameter.

Return Value

If the function succeeds, the return value is a pointer to the byte array. To get extended error information, use the GetLastError function.

See Also

»lstrcmp«, »lstrcmpi«, »lstrcpy«, »lstrlen«


  lstrcmp

int lstrcmp(lpszString1, lpszString2)
LPCTSTR  lpszString1;   /* address of first string  */
LPCTSTR  lpszString2;   /* address of second string  */

The lstrcmp function compares two character strings. The comparison is case sensitive.

Parameters

lpszString1

Points to the first null-terminated string to be compared.

lpszString2

Points to the second null-terminated string to be compared.

Return Value

If the function succeeds and the string pointed to by lpszString1 is less than the string pointed to by lpszString2, the return value is negative; if the string pointed to by lpszString1 is greater than the string pointed to by lpszString2, it is positive. If the strings are equal, the return value is zero.

Comments

The lstrcmp function compares two strings by checking the first characters against each other, the second characters against each other, and so on until it finds an inequality or reaches the ends of the strings.

The function returns the difference of the values of the first unequal characters it encounters. For example, lstrcmp determines that "abcz" is greater than "abcdefg" and returns the difference of z and d.

The language (locale) selected by the user at setup time, or via the control panel, determines which string is greater (or whether the strings are the same). If no language (locale) is selected, Windows performs the comparison by using default values. In the Windows United States language functions, uppercase characters have lower values than lowercase characters.

With a double-byte character set (DBCS) version of Windows, this function can compare two DBCS strings.

See Also

»lstrcat«, »lstrcmpi«, »lstrcpy«, »lstrlen«


  lstrcmpi

int lstrcmpi(lpszString1, lpszString2)
LPCTSTR  lpszString1;   /* address of first string  */
LPCTSTR  lpszString2;   /* address of second string  */

The lstrcmpi function compares two character strings. The comparison is not case sensitive.

Parameters

lpszString1

Points to the first null-terminated string to be compared.

lpszString2

Points to the second null-terminated string to be compared.

Return Value

If the function succeeds and the string pointed to by lpszString1 is less than the string pointed to by lpszString2, the return value is negative; if the string pointed to by lpszString1 is greater than the string pointed to by lpszString2, it is positive. If the strings are equal, the return value is zero.

Comments

The lstrcmpi function compares two strings by checking the first characters against each other, the second characters against each other, and so on until it finds an inequality or reaches the ends of the strings.

The function returns the difference of the values of the first unequal characters it encounters. For example, lstrcmpi determines that "abcz" is greater than "abcdefg" and returns the difference of z and d.

The language (locale) selected by the user at setup time, or via the control panel, determines which string is greater (or whether the strings are the same). If no language (locale) is selected, Windows performs the comparison by using default values.

With a double-byte character set (DBCS) version of Windows, this function can compare two DBCS strings.

See Also

»lstrcat«, »lstrcmp«, »lstrcpy«, »lstrlen«


  lstrcpy

LPTSTR lstrcpy(lpszString1, lpszString2)
LPTSTR  lpszString1;   /* address of buffer  */
LPCTSTR  lpszString2;   /* address of string to copy  */

The lstrcpy function copies a string to a buffer.

Parameters

lpszString1

Points to a buffer to receive the contents of the string pointed to by the lpszString2 parameter. The buffer must be large enough to contain the string, including the terminating null character.

lpszString2

Points to the null-terminated string to be copied.

Return Value

If the function succeeds, the return value is a pointer to the buffer; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

With a double-byte character set (DBCS) version of Windows, this function can be used to copy a DBCS string.

See Also

»lstrcat«, »lstrcmp«, »lstrcmpi«, »lstrlen«


  lstrlen

int lstrlen(lpszString)
LPCTSTR  lpszString;   /* address of string to count  */

The lstrlen function returns the length, in characters, of the specified string (not including the terminating null character).

Parameters

lpszString

Points to a null-terminated string.

Return Value

If the function succeeds, the return value specifies the length, in characters, of the string.

See Also

»lstrcat«, »lstrcmp«, »lstrcmpi«, »lstrcpy«


  _lwrite

UINT _lwrite(hFile, lpBuffer, cbWrite)
HFILE  hFile;   /* handle of file  */
LPCSTR  lpBuffer;   /* address of buffer for data to be written   */
UINT  cbWrite;   /* number of bytes to write  */

The _lwrite function writes data to the specified file. This function is provided for compatibility with earlier versions of Windows. For applications written with the Win32 API, use the WriteFile function.

Parameters

hFile

Identifies the specified file.

lpBuffer

Points to a buffer that contains the data to write to the file.

cbWrite

Specifies the number of bytes to write to the file.

Return Value

If the function succeeds, the return value indicates the number of bytes actually written to the file. Otherwise, it is HFILE_ERROR. To get extended error information, use the GetLastError function.

See Also

»_lread«, »WriteFile«


  LZClose

VOID LZClose(hFile)
INT  hFile;   /* LZ file handle identifying file to be closed  */

The LZClose function closes a file that was opened by using the LZOpenFile function.

Parameters

hFile

Identifies the source file to be closed.

Return Value

This function does not return a value.

Comments

The handle identifying the file must be retrieved by calling the LZOpenFile function. If the handle is retrieved by calling the CreateFile or OpenFile function, an error occurs.

If the file is compressed by using the Microsoft File Compression Utility (COMPRESS.EXE) and opened by using LZOpenFile, LZClose frees any global heap space that was allocated to expand the file.

See Also

»LZOpenFile«


  LZCopy

LONG LZCopy(hfSource, hfDest)
INT  hfSource;   /* LZ file handle identifying source file  */
INT  hfDest;   /* LZ file handle identifying destination file  */

The LZCopy function copies a source file to a destination file. If the source file is compressed with the Microsoft File Compression Utility (COMPRESS.EXE), this function creates a decompressed destination file. If the source file is not compressed, this function duplicates the original file.

Parameters

hfSource

Identifies the source file.

hfDest

Identifies the destination file.

Return Value

If the function succeeds, the return value specifies the size, in bytes, of the destination file.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZCopy calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZCopy can return upon failure :

Value	Meaning
LZERROR_BADINHANDLE	The handle identifying the source file is not valid. The file cannot be read.
LZERROR_BADOUTHANDLE	The handle identifying the destination file is not valid. The file cannot be written.
LZERROR_GLOBALLOC	The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
LZERROR_GLOBLOCK	The LZ file handle cannot be locked down.
LZERROR_READ	The source file format is not valid.
Comments

The handles identifying the source and destination files must be retrieved by calling the LZInit or LZOpenFile function.

This function is designed for single-file copy operations. (For multiple-file copy operations, use the CopyLZFile function.)

If the function succeeds, the file identified by the hfDest parameter is always uncompressed.

See Also

»CopyLZFile«, »LZInit«, »LZOpenFile«


  LZDone

The LZDone function is obsolete. It is provided only for backwards compatibility. Win32 applications should not use it.


  LZInit

INT LZInit(hfSource)
INT  hfSource;   /* handle of source file  */

The LZInit function allocates memory for the internal data structures required to decompress files and then creates and initializes them.

Parameters

hfSource

Identifies the source file.

Return Value

If the function succeeds, the return value is a new LZ file handle.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZInit calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZInit can return upon failure :

Value	Meaning
LZERROR_BADINHANDLE	The handle identifying the source file is not valid. The file cannot be read.
LZERROR_GLOBALLOC	The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
LZERROR_GLOBLOCK	The LZ file handle cannot be locked down.
LZERROR_UNKNOWNALG	The file is compressed with an unrecognized compression algorithm.
Comments

A maximum of 16 compressed files can be open at any given time. Similarly, a maximum of 16 uncompressed files can be open at any given time.

The handle this function returns is compatible only with the functions in LZEXPAND.DLL; it should not be used for other file operations.


  LZOpenFile

INT LZOpenFile(lpFileName, lpReOpenBuf, wStyle)
LPTSTR  lpFileName;   /* address of name of file to be opened  */
LPOFSTRUCT  lpReOpenBuf;   /* address of open file structure   */
WORD  wStyle;   /* action to take  */

The LZOpenFile function creates, opens, reopens, or deletes the specified file.

Parameters

lpFileName

Points to a string that specifies the name of a file.

lpReOpenBuf

Points to the OFSTRUCT structure that is to receive information about the file when the file is first opened. The structure can be used in subsequent calls to the LZOpenFile function to refer to the open file. The OFSTRUCT structure has the following form:

typedef struct _OFSTRUCT { /* of  */

    BYTE cBytes;

    BYTE fFixedDisk;

    WORD nErrCode;

    WORD Reserved1;

    WORD Reserved2;

    BYTE szPathName[OFS_MAXPATHNAME];

} OFSTRUCT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The szPathName member of this structure contains characters from the original equipment manufacturer (OEM) character set.

wStyle

Specifies the action to take. This parameter can be a combination of the following values:

Value	Meaning
OF_CANCEL	Ignored. In the Win32 application programming interface (API), the OF_PROMPT style produces a dialog box containing a Cancel button.
OF_CREATE	Directs LZOpenFile to create a new file. If the file already exists, it is truncated to zero length.
OF_DELETE	Deletes the file.
OF_EXIST	Opens the file and then closes it to test for a file's existence.
OF_PARSE	Fills the OFSTRUCT structure but carries out no other action.
OF_PROMPT	Displays a dialog box if the requested file does not exist. The dialog box informs the user that Windows cannot find the file, and it contains Retry and Cancel buttons. Choosing the Cancel button directs LZOpenFile to return a file-not-found error message. OF_READ Opens the file for reading only.
OF_READWRITE	Opens the file for reading and writing.
OF_REOPEN	Opens the file using information in the reopen buffer.
OF_SHARE_DENY_NONE	Opens the file without denying other processes read or write access to the file. LZOpenFile fails if the file has been opened in compatibility mode by any other process.
OF_SHARE_DENY_READ	Opens the file and denies other processes read access to the file. LZOpenFile fails if the file has been opened in compatibility mode or has been opened for read access by any other process.
OF_SHARE_DENY_WRITE	Opens the file and denies other processes write access to the file. LZOpenFile fails if the file has been opened in compatibility mode or has been opened for write access by any other process.
OF_SHARE_EXCLUSIVE	Opens the file in exclusive mode, denying other processes both read and write access to the file. LZOpenFile fails if the file has been opened in any other mode for read or write access, even by the current process.
OF_WRITE	Opens the file for writing only.
Return Value

If the function succeeds and the value specified by the wStyle parameter is not OF_READ, the return value is a handle identifying the file. If the file is compressed and opened with wStyle set to OF_READ, the return value is a special file handle.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZOpenFile calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZOpenFile can return upon failure:

Value	Meaning
LZERROR_BADINHANDLE	The handle identifying the source file is not valid. The file cannot be read.
LZERROR_GLOBALLOC	The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
Comments

If the wStyle parameter is the OF_READ flag (or OF_READ and any of the OF_SHARE_ flags) and the file is compressed, LZOpenFile calls the LZInit function, which performs the required initialization for the decompression operations.

The handle this function returns is compatible only with the functions in LZEXPAND.DLL; it should not be used for other file operations.

See Also

»LZClose«, »LZInit«, »LZRead«,


  LZRead

INT LZRead(hFile, lpBuffer, cbRead)
INT  hFile;   /* LZ file handle of file  */
LPSTR  lpBuffer;   /* address of buffer for bytes   */
INT  cbRead;   /* count of bytes  */

The LZRead function reads (at most) the specified number of bytes from the given file and copies them into the given buffer.

Parameters

hFile

Identifies the source file.

lpBuffer

Points to a buffer that receives the bytes read from the file.

cbRead

Specifies the count of bytes to be read.

Return Value

If the function succeeds, the return value specifies the actual number of bytes read.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZRead calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZRead can return upon failure:

Value	Meaning
LZERROR_BADINHANDLE	The handle identifying the source file is not valid. The file cannot be read.
LZERROR_BADOUTHANDLE	The handle identifying the destination file is not valid. The file cannot be written.
LZERROR_BADVALUE	One of the input parameters is not valid.
LZERROR_GLOBALLOC	The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
LZERROR_GLOBLOCK	The LZ file handle cannot be locked down.
LZERROR_READ	The source file format is not valid.
LZERROR_WRITE	There is insufficient space for the output file.
Comments

The handle identifying the file must be retrieved by calling either the LZInit or LZOpenFile function.

If the file is compressed, LZRead emulates the _lread function on an expanded image of the file and copies the bytes of data into the specified buffer.

Applications must call the LZOpenFile, LZSeek, and LZRead functions instead of the OpenFile, _llseek, and _lread functions.

See Also

»LZInit«, »LZOpenFile«, »LZSeek«


  LZSeek

/* see bottom of file for some history

LONG LZSeek(hFile, lOffset, iOrigin)
INT  hFile;   /* handle identifying file  */
LONG  lOffset;   /* number of bytes to move   */
INT  iOrigin;   /* original position  */

The LZSeek function moves a file pointer from the specified origin by the given offset.

Parameters

hFile

Identifies the source file.

lOffset

Specifies the number of bytes by which the file pointer should be moved.

iOrigin

Specifies the starting position of the pointer. This parameter must be one of the following values:

Value	Meaning
0	Moves the file pointer lOffset bytes from the beginning of the file.
1	Moves the file pointer lOffset bytes from the current position.
2	Moves the file pointer lOffset bytes from the end of the file.
Return Value

If the function succeeds, the return value specifies the offset from the beginning of the file to the new pointer position.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZSeek calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZSeek can return upon failure :

Value	Meaning
LZERROR_BADINHANDLE	The handle identifying the source file is not valid. The file cannot be read.
LZERROR_BADVALUE	One of the parameters is outside the range of acceptable values.
LZERROR_GLOBLOCK	The LZ file handle cannot be locked down.
Comments

The handle identified by the hFile parameter must be retrieved by calling either the LZInit or LZOpenFile function.

If the file is compressed, LZSeek emulates the _llseek function on an expanded image of the file.

See Also

»LZInit«, »LZOpenFile«


  LZStart

The LZStart function is obsolete. It is provided only for backwards compatibility. Win32 applications should not use it.


  MakeAbsoluteSD

BOOL MakeAbsoluteSD(psdSelf, psdAbs, lpcbsdAbsolute, paclDiscretionary, lpcbDacl,
paclSystem, lpcbSacl, psidOwner, lpcbsidOwner, psidPrimaryGroup, lpcbsidPrimaryGroup)
PSECURITY_DESCRIPTOR  psdSelf;   /* address self-relative SD  */
PSECURITY_DESCRIPTOR  psdAbs;   /* address of absolute SD  */
LPDWORD  lpcbsdAbsolute;   /* address of size of absolute SD  */
PACL  paclDiscretionary;   /* address of discretionary ACL  */
LPDWORD  lpcbDacl;   /* address of size of discretionary ACL  */
PACL  paclSystem;   /* address of system ACL  */
LPDWORD  lpcbSacl;   /* address of size of system ACL  */
PSID  psidOwner;   /* address of owner SID  */
LPDWORD  lpcbsidOwner;   /* address of size of owner SID  */
PSID  psidPrimaryGroup;   /* address of primary-group SID  */
LPDWORD  lpcbsidPrimaryGroup;   /* address of size of group SID  */

The MakeAbsoluteSD function creates a security descriptor in absolute format by using a security descriptor in self-relative format as a template.

Parameters

psdSelf

Points to a SECURITY_DESCRIPTOR structure in self-relative format. The function creates an absolute-format version of this security descriptor without modifying the original security descriptor.

psdAbs

Points to a buffer that the function fills with the main body of an absolute-format security descriptor. This information is formatted as a SECURITY_DESCRIPTOR structure.

lpcbsdAbsolute

Points to a variable specifying the size of the buffer pointed to by the psdAbs parameter. If the buffer is not large enough for the security descriptor, the function fails and sets this variable to the minimum required size.

paclDiscretionary

Points to a buffer the function fills with the discretionary access-control list (ACL) of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.

The ACL structure has the following form:

typedef struct _ACL { /* acl  */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcbDacl

Points to a variable specifying the size of the buffer pointed to by the paclDiscretionary parameter. If the buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required size.

paclSystem

Points to a buffer the function fills with the system ACL of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.

lpcbSacl

Points to a variable specifying the size of the buffer pointed to by the paclSystem parameter. If the buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required size.

psidOwner

Points to a buffer the function fills with the security identifier (SID) of the owner of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.

lpcbsidOwner

Points to a variable specifying the size of the buffer pointed to by the psidOwner parameter. If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum required size.

psidPrimaryGroup

Points to a buffer the function fills with the SID of the absolute-format security descriptor's primary group. The main body of the absolute-format security descriptor references this pointer.

lpcbsidPrimaryGroup

Points to a variable specifying the size of the buffer pointed to by the psidPrimaryGroup parameter. If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum required size.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A security descriptor in absolute format contains pointers to the information it contains, rather than the information itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the self-relative security descriptor are identified by offsets from the beginning of the security descriptor. This format is useful when an security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.

A server that copies secured objects to various media can use the MakeAbsoluteSD function to create an absolute security descriptor from a self-relative security descriptor and the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor.

See Also

»MakeSelfRelativeSD«


  MakeProcInstance

The MakeProcInstance function is obsolete. Win32 functions can be called directly.

This function is provided in Win32 only for compatibility with earlier versions of Windows. Win32 applications should not use this function.


  MakeSelfRelativeSD

BOOL MakeSelfRelativeSD(psdAbsolute, psdSelfRelative, lpcbsdSelfRelative)
PSECURITY_DESCRIPTOR  psdAbsolute;   /* address of absolute SD  */
PSECURITY_DESCRIPTOR  psdSelfRelative;   /* address self-relative SD   */
LPDWORD  lpcbsdSelfRelative;   /* address of SD size  */

The MakeSelfRelativeSD function creates a security descriptor in self-relative format by using a security descriptor in absolute format as a template.

Parameters

psdAbsolute

Points to a SECURITY_DESCRIPTOR structure in absolute format. The function creates a version of this security descriptor in self-relative format without modifying the original.

psdSelfRelative

Points to a buffer the function fills with a security descriptor in self-relative format.

lpcbsdSelfRelative

Points to a variable specifying the size of the buffer pointed to by the psdSelfRelative parameter. If the buffer is not large enough for the security descriptor, the function fails and sets this variable to the minimum required size.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A security descriptor in absolute format contains pointers to the information it contains, rather than containing the information itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the security descriptor are identified by offsets from the beginning of the security descriptor. This format is useful when an security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.

A server that copies secured objects to various media can use the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor and the MakeAbsoluteSD function to create an absolute security descriptor from a self-relative security descriptor.

See Also

»MakeAbsoluteSD«


  MapDialogRect

BOOL MapDialogRect(hwndDlg, lprc)
HWND  hwndDlg;   /* handle of dialog box  */
LPRECT  lprc;   /* address of structure with rectangle  */

The MapDialogRect function converts (maps) the specified dialog box units to screen units (pixels). The function replaces the coordinates in the specified RECT structure with the converted coordinates, which allows the structure to be used to create a dialog box or position a control within a dialog box.

Parameters

hwndDlg

Identifies a dialog box. This function accepts only handles for dialog boxes created by one of the dialog box creation functions; handles for other windows are not valid.

lprc

Points to a RECT structure that contains the dialog box coordinates to be converted. The RECT structure has the following form:

typedef struct tagRECT {    /* rc  */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The MapDialogRect function assumes that the initial coordinates in the RECT structure represent dialog units. To convert these coordinates from dialog box units to pixels, the function retrieves the current horizontal and vertical base units for the dialog box, then applies the following formulas:

left   = (left   * baseunitX) / 4

right  = (right  * baseunitX) / 4

top    = (top    * baseunitY) / 8

bottom = (bottom * baseunitY) / 8

In most cases, the base units for the dialog box are the same as those retrieved by using the GetDialogBaseUnits function. If the dialog box template has the DS_SETFONT style, however, the base units are the average width and height, in pixels, of the characters in the font given by the template.

See Also

»CreateDialog«, »CreateDialogIndirect«, »CreateDialogIndirectParam«, »CreateDialogParam«, »DialogBox«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »DialogBoxParam«, »GetDialogBaseUnits«


  MapGenericMask

VOID MapGenericMask(pdwAccessMask, pgm)
PDWORD  pdwAccessMask;   /* address of access mask  */
PGENERIC_MAPPING  pgm;   /* address of GENERIC_MAPPING structure  */

The MapGenericMask function maps the generic access rights in an access mask to specific and standard access rights. The function applies a mapping supplied in a GENERIC_MAPPING structure.

Parameters

pdwAccessMask

Points to an access mask receiving the specific and standard rights mapped from generic access rights.

pgm

Points to a GENERIC_MAPPING structure specifying a mapping of generic access types to specific and standard access types.

The GENERIC_MAPPING structure has the following form:

typedef struct _GENERIC_MAPPING { /* gm  */

    ACCESS_MASK GenericRead;

    ACCESS_MASK GenericWrite;

    ACCESS_MASK GenericExecute;

    ACCESS_MASK GenericAll;

} GENERIC_MAPPING;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

This function does not return a value.

Comments

After calling the MapGenericMask function, the access mask pointed to by the pdwAccessMask parameter has none of its generic bits (GenericRead, GenericWrite, GenericExecute, or GenericAll) or undefined bits set, although it can have other bits set. If bits other than the generic bits are provided on input, this function does not clear them.

See Also

»AccessCheck«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«


  MapViewOfFile

LPVOID MapViewOfFile(hMapObject, fdwAccess, dwOffsetHigh, dwOffsetLow, cbMap)
HANDLE  hMapObject;   /* file-mapping object to map into address space  */
DWORD  fdwAccess;   /* access mode  */
DWORD  dwOffsetHigh;   /* high-order 32 bits of file offset  */
DWORD  dwOffsetLow;   /* low-order 32 bits of file offset   */
DWORD  cbMap;   /* number of bytes to map  */

The MapViewOfFile function maps a view of a file into the address space of the calling process.

Parameters

hMapObject

Identifies an open handle of a file-mapping object. The CreateFileMapping and OpenFileMapping functions return this handle.

fdwAccess

Specifies the type of access to the file view and, therefore, the protection of the pages mapped by the file. This parameter can be one of the following values:

Value	Meaning
FILE_MAP_WRITE	Read-and-write access. The hMapObject parameter must have been created with PAGE_READWRITE protection. A read-and-write view of the file is mapped.
FILE_MAP_READ	Read-only access. The hMapObject parameter must have been created with PAGE_READWRITE or PAGE_READ protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS	Same as FILE_MAP_WRITE.
FILE_MAP_COPY	Copy on write access. The hMapObject parameter must have been created with PAGE_WRITECOPY protection. A copy on write view of the file is mapped.
dwOffsetHigh

Specifies the high-order 32 bits of the file offset where mapping is to begin.

dwOffsetLow

Specifies the low-order 32 bits of the file offset where mapping is to begin. The combination of the high and low offsets must specify a 64K-aligned offset within the file, or the function fails.

cbMap

Specifies the number of bytes of the file to map. If cbMap is zero, the entire file is mapped.

Return Value

If the function succeeds, the return value is the starting address of the mapped view; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

Multiple views of a file (or a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a given time. This occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle into another process by using the DuplicateHandle function, or another process can open a file-mapping object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile or WriteFile function.

See Also

»CreateFileMapping«, »DuplicateHandle«, »MapViewOfFileEx«, »OpenFileMapping«, »UnmapViewOfFile«


  MapViewOfFileEx

LPVOID MapViewOfFileEx(hMapObject, fdwAccess, dwOffsetHigh, dwOffsetLow,
cbMap, lpvBase)
HANDLE  hMapObject;   /* file-mapping object to map into address space  */
DWORD  fdwAccess;   /* access mode  */
DWORD  dwOffsetHigh;   /* high-order 32 bits of file offset  */
DWORD  dwOffsetLow;   /* low-order 32 bits of file offset  */
DWORD  cbMap;   /* number of bytes to map  */
LPVOID  lpvBase;   /* suggested starting address for mapped view  */

The MapViewOfFileEx function maps a view of a file into the address space of the calling process. This extended function allows the calling process to specify a suggested memory address for the mapped view.

This function is available only in Windows NT.

Parameters

hMapObject

Identifies an open handle to a file-mapping object. The CreateFileMapping and OpenFileMapping functions return this handle.

fdwAccess

Specifies the type of access to the file-mapping object and, therefore, the page protection of the pages mapped by the file. This parameter can be one of the following values:

Value	Meaning
FILE_MAP_WRITE	Read-and-write access. The hMapObject parameter must have been created with PAGE_READWRITE protection. A read-and-write view of the file is mapped.
FILE_MAP_READ	Read-only access. The hMapObject parameter must have been created with PAGE_READWRITE or PAGE_READ protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS	Same as FILE_MAP_WRITE.
FILE_MAP_COPY	Copy on write access. The hMapObject parameter must have been created with PAGE_WRITECOPY protection. A copy on write view of the file is mapped.
dwOffsetHigh

Specifies the high-order 32 bits of the file offset where mapping is to begin.

dwOffsetLow

Specifies the low-order 32 bits of the file offset where mapping is to begin. The combination of the high and low offsets must specify a 64K-aligned offset within the file, or the function fails.

cbMap

Specifies the number of bytes of the file to map. If cbMap is zero, the entire file is mapped.

lpvBase

Points to the memory address in the calling process's address space where mapping should begin. The operating system rounds this address down to the nearest 64K boundary. If there is not enough address space at the specified address, the function fails.

If lpvBase is NULL, the operating system chooses the mapping address. In this case, this function is equivalent to the MapViewOfFile function.

Return Value

If the function succeeds, the return value is the starting address of the mapped view; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

If a suggested mapping address is supplied, the file is mapped at the specified address (rounded down to the nearest 64K boundary) if there is enough address space at the specified address. If there is not, the function fails.

Typically, the suggested address is used to specify that a file should be mapped at the same address in multiple processes. This requires the region of address space to be available in all involved processes. No other memory allocation, including use of the VirtualAlloc function to reserve memory, can take place in the region used for mapping.

Multiple views of a file (or a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a given time. This occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle into another process by using the DuplicateHandle function, or another process can open a file-mapping object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile or WriteFile function.

See Also

»CreateFileMapping«, »DuplicateHandle«, »MapViewOfFile«, »OpenFileMapping«, »UnmapViewOfFile«


  MapVirtualKey

UINT MapVirtualKey(uCode, fuMapType)
UINT  uCode;   /* virtual-key code or scan code   */
UINT  fuMapType;   /* translation to perform  */

The MapVirtualKey function translates (maps) a virtual-key code into a scan code or character value, or translates a scan code into a virtual-key code.

Parameters

uCode

Specifies the virtual-key code or scan code for a key. How this value is interpreted depends on the value of the fuMapType parameter.

fuMapType

Specifies the translation to perform. The value of this parameter depends on the value of the uCode parameter:

Value	Meaning
0	uCode is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, 0 is returned.
1	uCode is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If there is no translation, 0 is returned.
2	uCode is a virtual-key code and is translated into an unshifted character value in the low order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If no translation exists, the function returns −1.
3	uCode is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is no translation, the function returns 0.
Return Value

The return value depends on the value of the uCode and fuMapType parameters. For more information, see the description of the fuMapType parameter.

Comments

An application can use MapVirtualKeyCode to translate scan codes to the virtual-key code constants VK_SHIFT, VK_CONTROL, and VK_MENU, and vice versa. These translations do not distinguish between the left and right instances of the SHIFT, CTRL, or ALT keys. An application can get the scan code corresponding to the left or right instance of one of these keys by calling MapVirtualKey with uCode set to one of the following virtual-key code constants:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU
These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions.

For a complete table of virtual key codes, see Appendix B, "Virtual-Key Codes," in Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»GetAsyncKeyState«, »GetKeyboardState«, »GetKeyState«, »SetKeyboardState«


  MapWindowPoints

int MapWindowPoints(hwndFrom, hwndTo, lppt, cPoints)
HWND  hwndFrom;   /* handle of window to be mapped from  */
HWND  hwndTo;   /* handle of window to be mapped to  */
LPPOINT  lppt;   /* address of structure array with points to map   */
UINT  cPoints;   /* number of structures in array  */

The MapWindowPoints function converts (maps) a set of points from a coordinate space relative to one window to a coordinate space relative to another window.

Parameters

hwndFrom

Identifies the window from which points are converted. If this parameter is NULL or HWND_DESKTOP, the points are presumed to be in screen coordinates.

hwndTo

Identifies the window to which points are converted. If this parameter is NULL or HWND_DESKTOP, the points are converted to screen coordinates.

lppt

Points to an array of POINT structures that contain the set of points to be converted. This parameter can also point to a RECT structure, in which case the cPoints parameter should be set to 2. The POINT structure has the following form:

typedef struct tagPOINT { /* pt  */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The RECT structure has the following form:

typedef struct tagRECT {    /* rc  */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cPoints

Specifies the number of POINT structures in the array pointed to by the lppt parameter.

Return Value

If the function succeeds, the low-order word of the return value is the number of pixels added to the horizontal coordinate of each source point in order to compute the horizontal coordinate of each destination point; the high-order word is the number of pixels added to the vertical coordinate of each source point in order to compute the vertical coordinate of each destination point.

See Also

»ClientToScreen«, »ScreenToClient«


  MaskBlt

BOOL MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc,
hbmMask, xMask, yMask, dwRop)
HDC  hdcDest;   /* handle of destination device context  */
int  nXDest;   /* x-coord. of upper left corner of destination rectangle  */
int  nYDest;   /* y-coord. of upper left corner of destination rectangle  */
int  nWidth;   /* width of source and destination rectangles  */
int  nHeight;   /* height of source and destination rectangles  */
HDC  hdcSrc;   /* handle of source device context  */
int  nXSrc;   /* x-coord. of upper left corner of source rectangle  */
int  nYSrc;   /* y-coord. of upper left corner of source rectangle  */
HBITMAP  hbmMask;   /* handle of monochrome bit mask  */
int  xMask;   /* horizontal pixel offset into the mask bitmap  */
int  yMask;   /* vertical pixel offset into the mask bitmap   */
DWORD  dwRop;   /* raster operation code  */

The MaskBlt function combines the color data for the source and destination bitmaps using the given mask and raster operation.

Parameters

hdcDest

Identifies the destination device context.

nXDest

Specifies the logical x-coordinate of the upper left corner of the destination rectangle.

nYDest

Specifies the logical y-coordinate of the upper left corner of the destination rectangle.

nWidth

Specifies the width, in logical units, of the destination rectangle and source bitmap.

nHeight

Specifies the height, in logical units, of the destination rectangle and source bitmap.

hdcSrc

Identifies the device context from which the bitmap is to be copied. It must be zero if the dwRop parameter specifies a raster operation that does not include a source.

nXSrc

Specifies the logical x-coordinate of the upper left corner of the source bitmap.

nYSrc

Specifies the logical y-coordinate of the upper left corner of the source bitmap.

hbmMask

Identifies the monochrome mask bitmap combined with the color bitmap in the source device context.

xMask

Specifies the horizontal pixel offset for the mask bitmap specified by the hbmMask parameter.

yMask

Specifies the vertical pixel offset for the mask bitmap specified by the hbmMask parameter.

dwRop

Specifies both foreground and background ternary raster operation codes that the function uses to control the combination of source and destination data. The background raster operation code is stored in the high byte of the high word of this value; the foreground raster operation code is stored in the low byte of the high word of this value; the low word of this value is ignored, and should be zero. The macro MAKEROP4 creates such combinations of foreground and background raster operation codes.

See the Comments section below for a discussion of foreground and background in the context of this function.

See the »BitBlt« function for a list of common raster operation codes.

For further information on raster operations, and complete lists of all the raster operation codes, see Appendix F, "Raster Operation Codes," in Microsoft Win32 Programmer's Reference, Volume 2.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A value of 1 in the mask specified by hbmMask indicates that the foreground raster operation code specified by dwRop should be applied at that location. A value of 0 in the mask indicates that the background raster operation code specified by dwRop should be applied at that location.

If the raster operations require a source, the mask rectangle must cover the source rectangle. If it does not, the function will fail. If the raster operations do not require a source, the mask rectangle must cover the destination rectangle. If it does not, the function will fail.

If a rotation or shear transformation is in effect for the source device context when this function is called, an error occurs. However, other types of transformation are allowed.

If the color formats of the source, pattern, and destination bitmaps differ, this function converts the pattern or source format, or both, to match the destination format.

If the mask bitmap is not a monochrome bitmap, an error occurs.

When an enhanced metafile is being recorded, an error occurs (and the function returns FALSE) if the source device context identifies an enhanced-metafile device context.

Not all devices support the MaskBlt function. An application should call the GetDeviceCaps function to determine whether a device supports this function.

If no mask bitmap is supplied, this function behaves exactly like BitBlt, using the foreground raster operation code.

The pixel offsets in the mask bitmap map to the point (0,0) in the source device context's bitmap. This is useful in cases where a mask bitmap contains a set of masks;  an application can easily apply any one of them to a mask-blitting task by adjusting the pixel offsets and rectangle sizes sent to MaskBlt.

See Also

»BitBlt«, »GetDeviceCaps«, »PlgBlt«, »StretchBlt«


  MCI_HMS_HOUR

BYTE MCI_HMS_HOUR(dwHMS)
DWORD  dwHMS;   /* time in HMS format  */

The MCI_HMS_HOUR macro returns the hours field from a doubleword argument containing packed hours/minutes/seconds (HMS) information.

Parameters

dwHMS

Specifies the time in HMS format.

Return Value

The return value is the hours field of the given argument.

Comments

Time in HMS format is expressed as a doubleword value with the least significant byte containing hours, the next least significant byte containing minutes, and the next least significant byte containing seconds. The most significant byte is unused.

See Also

»MCI_HMS_MINUTE«, »MCI_HMS_SECOND«, »MCI_MAKE_HMS«


  MCI_HMS_MINUTE

BYTE MCI_HMS_MINUTE(dwHMS)
DWORD  dwHMS;   /* time in HMS format  */

The MCI_HMS_MINUTE macro returns the minutes field from a doubleword argument containing packed hours/minutes/seconds (HMS) information.

Parameters

dwHMS

Specifies the time in HMS format.

Return Value

The return value is the minutes field of the given argument.

Comments

Time in HMS format is expressed as a doubleword value with the least significant byte containing hours, the next least significant byte containing minutes, and the next least significant byte containing seconds. The most significant byte is unused.

See Also

»MCI_HMS_HOUR«, »MCI_HMS_SECOND«, »MCI_MAKE_HMS«


  MCI_HMS_SECOND

BYTE MCI_HMS_SECOND(dwHMS)
DWORD  dwHMS;   /* time in HMS format  */

The MCI_HMS_SECOND macro returns the seconds field from a doubleword argument containing packed hours/minutes/seconds (HMS) information.

Parameters

dwHMS

Specifies the time in HMS format.

Return Value

The return value is the seconds field of the given argument.

Comments

Time in HMS format is expressed as a doubleword value with the least significant byte containing hours, the next least significant byte containing minutes, and the next least significant byte containing seconds. The most significant byte is unused.

See Also

»MCI_HMS_HOUR«, »MCI_HMS_MINUTE«, »MCI_MAKE_HMS«


  MCI_MAKE_HMS

DWORD MCI_MAKE_HMS(hours, minutes, seconds)
BYTE  hours;   /* hours  */
BYTE  minutes;   /* minutes  */
BYTE  seconds;   /* seconds  */

The MCI_MAKE_HMS macro returns a time value in packed hours/minutes/seconds (HMS) format from the given hours, minutes, and seconds values.

Parameters

hours

Specifies the number of hours.

minutes

Specifies the number of minutes.

seconds

Specifies the number of seconds.

Return Value

The return value is a doubleword value containing the time in packed HMS format.

Comments

Time in HMS format is expressed as a doubleword value with the least significant byte containing hours, the next least significant byte containing minutes, and the next least significant byte containing seconds. The most significant byte is unused.

See Also

»MCI_HMS_MINUTE«, »MCI_HMS_SECOND«, »MCI_MSF_FRAME«


  MCI_MAKE_MSF

DWORD MCI_MAKE_MSF(minutes, seconds, frames)
BYTE  minutes;   /* minutes  */
BYTE  seconds;   /* seconds  */
BYTE  frames;   /* number of frames  */

The MCI_MAKE_MSF macro returns a time value in packed minutes/seconds/frames (MSF) format from the given minutes, seconds, and frame values.

Parameters

minutes

Specifies the number of minutes.

seconds

Specifies the number of seconds.

frames

Specifies the number of frames.

Return Value

The return value is a doubleword value containing the time in packed MSF format.

Comments

Time in MSF format is expressed as a doubleword value with the least significant byte containing minutes, the next least significant byte containing seconds, and the next least significant byte containing frames. The most significant byte is unused.

See Also

»MCI_HMS_MINUTE«, »MCI_MSF_SECOND«, »MCI_MSF_FRAME«


  MCI_MAKE_TMSF

DWORD MCI_MAKE_TMSF(tracks, minutes, seconds, frames)
BYTE  tracks;   /* number of tracks  */
BYTE  minutes;   /* minutes  */
BYTE  seconds;   /* seconds  */
BYTE  frames;   /* number of frames  */

The MCI_MAKE_TMSF macro returns a time value in packed tracks/minutes/seconds/frames (TMSF) format from the given tracks, minutes, seconds, and frames values.

Parameters

tracks

Specifies the number of tracks.

minutes

Specifies the number of minutes.

seconds

Specifies the number of seconds.

frames

Specifies the number of frames.

Return Value

The return value is a doubleword value containing the time in packed TMSF format.

Comments

Time in TMSF format is expressed as a doubleword value with the least significant byte containing tracks, the next least significant byte containing minutes, the next least significant byte containing seconds, and the most significant byte containing frames.

See Also

»MCI_TMSF_MINUTE«, »MCI_TMSF_SECOND«, »MCI_TMSF_FRAME«


  MCI_MSF_FRAME

BYTE MCI_MSF_FRAME(dwMSF)
DWORD  dwMSF;   /* time in MSF format */

The MCI_MSF_FRAME macro returns the frames field from a doubleword argument containing packed minutes/seconds/frames (MSF) information.

Parameters

dwMSF

Specifies the time in MSF format.

Return Value

The return value is the frames field of the given argument.

Comments

Time in MSF format is expressed as a doubleword value with the least significant byte containing minutes, the next least significant byte containing seconds, and the next least significant byte containing frames. The most significant byte is unused.

See Also

»MCI_MSF_MINUTE«, »MCI_MSF_SECOND«, »MCI_MAKE_MSF«


  MCI_MSF_MINUTE

BYTE MCI_MSF_MINUTE(dwMSF)
DWORD  dwMSF;   /* time in MSF format */

The MCI_MSF_MINUTE macro returns the minutes field from a doubleword argument containing packed minutes/seconds/frames (MSF) information.

Parameters

dwMSF

Specifies the time in MSF format.

Return Value

The return value is the minutes field of the given argument.

Comments

Time in MSF format is expressed as a doubleword value with the least significant byte containing minutes, the next least significant byte containing seconds, and the next least significant byte containing frames. The most significant byte is unused.

See Also

»MCI_MSF_SECOND«, »MCI_MSF_FRAME«, »MCI_MAKE_MSF«


  MCI_MSF_SECOND

BYTE MCI_MSF_SECOND(dwMSF)
DWORD  dwMSF;   /* time in MSF format */

The MCI_MSF_SECOND macro returns the seconds field from a doubleword argument containing packed minutes/seconds/frames (MSF) information.

Parameters

dwMSF

Specifies the time in MSF format.

Return Value

The return value is the seconds field of the given argument.

Comments

Time in MSF format is expressed as a doubleword value with the least significant byte containing minutes, the next least significant byte containing seconds, and the next least significant byte containing frames. The most significant byte is unused.

See Also

»MCI_HMS_MINUTE«, »MCI_MSF_FRAME«, »MCI_MAKE_MSF«


  MCI_TMSF_FRAME

BYTE MCI_TMSF_FRAME(dwTMSF)
DWORD  dwTMSF;   /* time in TMSF format */

The MCI_TMSF_FRAME macro returns the frames field from a doubleword argument containing packed tracks/minutes/seconds/frames (TMSF) information.

Parameters

dwTMSF

Specifies the time in TMSF format.

Return Value

The return value is the frames field of the given argument.

Comments

Time in TMSF format is expressed as a doubleword value with the least significant byte containing tracks, the next least significant byte containing minutes, the next least significant byte containing seconds, and the most significant byte containing frames.

See Also

»MCI_TMSF_TRACK«, »MCI_TMSF_MINUTE«, »MCI_TMSF_SECOND«, »MCI_MAKE_TMSF«


  MCI_TMSF_MINUTE

BYTE MCI_TMSF_MINUTE(dwTMSF)
DWORD  dwTMSF;   /* time in TMSF format */

The MCI_TMSF_MINUTE macro returns the minutes field from a doubleword argument containing packed tracks/minutes/seconds/frames (TMSF) information.

Parameters

dwTMSF

Specifies the time in TMSF format.

Return Value

The return value is the minutes field of the given argument.

Comments

Time in TMSF format is expressed as a doubleword value with the least significant byte containing tracks, the next least significant byte containing minutes, the next least significant byte containing seconds, and the most significant byte containing frames.

See Also

»MCI_TMSF_TRACK«, »MCI_TMSF_SECOND«, »MCI_TMSF_FRAME«, »MCI_MAKE_TMSF«


  MCI_TMSF_SECOND

BYTE MCI_TMSF_SECOND(dwTMSF)
DWORD  dwTMSF;   /* time in TMSF format */

The MCI_TMSF_SECOND macro returns the seconds field from a doubleword argument containing packed tracks/minutes/seconds/frames (TMSF) information.

Parameters

dwTMSF

Specifies the time in TMSF format.

Return Value

The return value is the seconds field of the given argument.

Comments

Time in TMSF format is expressed as a doubleword value with the least significant byte containing tracks, the next least significant byte containing minutes, the next least significant byte containing seconds, and the most significant byte containing frames.

See Also

»MCI_TMSF_TRACK«, »MCI_TMSF_MINUTE«, »MCI_TMSF_FRAME«, »MCI_MAKE_TMSF«


  MCI_TMSF_TRACK

BYTE MCI_TMSF_TRACK(dwTMSF)
DWORD  dwTMSF;   /* time in TMSF format */

The MCI_TMSF_TRACK macro returns the tracks field from a doubleword argument containing packed tracks/minutes/seconds/frames (TMSF) information.

Parameters

dwTMSF

Specifies the time in TMSF format.

Return Value

The return value is the tracks field of the given argument.

Comments

Time in TMSF format is expressed as a doubleword value  with the least significant byte containing tracks, the next least significant byte containing minutes, the next least significant byte containing seconds, and the most significant byte containing frames.

See Also

»MCI_TMSF_MINUTE«, »MCI_TMSF_SECOND«, »MCI_TMSF_FRAME«, »MCI_MAKE_TMSF«


  mciGetCreatorTask

HANDLE mciGetCreatorTask(IDDevice)
MCIDEVICEID  IDDevice;   /* device to get creator task for */

The mciGetCreatorTask function retrieves the creator task for the specified device.

Parameters

IDDevice

Identifies the device whose creator task is to be returned.

Return Value

If the function succeeds, the return value is the handle of the creator task responsible for opening the device. If the device identifier is invalid, the return value is NULL.


  mciGetDeviceID

MCIDEVICEID mciGetDeviceID(lpszDevice)
LPCTSTR  lpszDevice;   /* address of device name */

The mciGetDeviceID function returns the device identifier corresponding to the name of an open device.

Parameters

lpszDevice

Points to a null-terminated string that specifies the device name or the alias name by which the device is known.

Return Value

If the function succeeds, the return value is the device identifier assigned to the device when it was opened. It is used in the mciSendCommand function.

The return value is zero if the device name is not known, if the device is not open, or if there was not enough memory to complete the operation.

Comments

Each compound device element has a unique device identifier. The identifier of the "all" device is MCI_ALL_DEVICE_ID.


  mciGetErrorString

BOOL mciGetErrorString(fdwError, lpszErrorText, cchErrorText)
DWORD  fdwError;   /* error code */
LPTSTR  lpszErrorText;   /* address of buffer for error string  */
UINT  cchErrorText;   /* size of buffer, in characters */

The mciGetErrorString function retrieves a string that describes the specified Media Control Interface (MCI) error code.

Parameters

fdwError

Specifies the error code returned by the mciSendCommand or mciSendString function.

lpszErrorText

Points to a buffer that receives a null-terminated string describing the specified error.

cchErrorText

Specifies the length of the buffer, in characters, pointed to by the lpszErrorText parameter .

Return Value

If the function succeeds, the return value is TRUE. If the error code is not known, the return value is FALSE.


  mciGetYieldProc

YIELDPROC mciGetYieldProc(IDDevice, lpdwYieldData)
MCIDEVICEID  IDDevice;   /* device being monitored */
LPDWORD  lpdwYieldData;   /* address of yield data to be passed */

The mciGetYieldProc function returns the address of the callback function associated with the mci WAIT flag; the callback function is called periodically while an MCI device waits for a command specified with the WAIT flag to finish.

Parameters

IDDevice

Specifies the MCI device being monitored (the device performing an MCI command).

lpdwYieldData

Points to a buffer containing yield data to be passed to the callback function. This parameter can be NULL if there is no yield data.

Return Value

If the function succeeds, the return value is the address of the current yield callback function. If the device identifier is invalid, the return value is NULL.

See Also

»mciSetYieldProc«


  mciSendCommand

MCIERROR mciSendCommand(IDDevice, uMsg, fdwCommand, dwParam)
MCIDEVICEID  IDDevice;   /* device to send message to */
UINT  uMsg;   /* message to send */
DWORD  fdwCommand;   /* message-specific parameter  */
DWORD  dwParam;   /* message-specific parameter */

The mciSendCommand function sends a command message to the specified Media Control Interface (MCI) device.

Parameters

IDDevice

Specifies the device identifier of the MCI device that is to receive the command message. This parameter is not used with the MCI_OPEN command message.

uMsg

Specifies the command message.

fdwCommand

Specifies flags for the command message.

dwParam

Specifies a pointer to a structure that contains parameters for the command message.

Return Value

If the function succeeds, the return value is zero. Otherwise, the return value is an error code. The low-order word of the return value is the error return value. If the error is device-specific, the high-order word of the return value is the driver identifier; otherwise the high-order word is zero. For more information about possible error values, see the Comments section in this entry.

To get a text description of mciSendCommand return values, pass the return value to the mciGetErrorString function.

Comments

Error values that are returned when a device is being opened are listed with the MCI_OPEN command message. In addition to the MCI_OPEN error return values, this function can return the following values:

Value	Meaning
MCIERR_BAD_TIME_FORMAT	The value for the time format is illegal.
MCIERR_CANNOT_USE_ALL	The device name "all" is not allowed for this command.
MCIERR_CREATEWINDOW	The window could not be created or used.
MCIERR_DEVICE_LOCKED	The device is locked until it is closed automatically.
MCIERR_DEVICE_NOT_READY	The device is not ready.
MCIERR_DEVICE_TYPE_REQUIRED	The device name must be a valid device type.
MCIERR_DRIVER	There was an unspecified device error.
MCIERR_DRIVER_INTERNAL	There was an internal driver error.
MCIERR_FILE_NOT_FOUND	The requested file was not found.
MCIERR_FILE_NOT_SAVED	The file was not saved.
MCIERR_FILE_READ	A read operation from the file failed.
MCIERR_FILE_WRITE	A write operation to the file failed.
MCIERR_FLAGS_NOT_COMPATIBLE	Incompatible parameters were specified.
MCIERR_HARDWARE	There was a hardware error on the media device.
MCIERR_INTERNAL	There was an internal error.
MCIERR_INVALID_DEVICE_ID	The device identifier is invalid.
MCIERR_INVALID_DEVICE_NAME	The device is not open or is not known.
MCIERR_INVALID_FILE	The file format is invalid.
MCIERR_MULTIPLE	Errors occurred in more than one device.
MCIERR_NO_WINDOW	There is no display window.
MCIERR_NULL_PARAMETER_BLOCK	The pointer to the structure containing the command-message parameters was NULL.
MCIERR_OUT_OF_MEMORY	There is not enough memory for the requested operation.
MCIERR_OUTOFRANGE	The parameter value is out of range.
MCIERR_UNNAMED_RESOURCE	The file to be saved was unnamed.
MCIERR_UNRECOGNIZED_COMMAND	The requested command is unknown.
MCIERR_UNSUPPORTED_FUNCTION	The action is not available for this device.
The following additional return values are defined for MCI sequencers:

Value	Meaning
MCIERR_SEQ_DIV_INCOMPATIBLE	The set song pointer is incompatible with SMPTE files.
MCIERR_SEQ_PORT_INUSE	The specified port is in use.
MCIERR_SEQ_PORT_MAPNODEVICE	The current map uses nonexistent device.
MCIERR_SEQ_PORT_MISCERROR	A miscellaneous error occurred with specified port.
MCIERR_SEQ_PORT_NONEXISTENT	The specified port does not exist.
MCIERR_SEQ_PORTUNSPECIFIED	No current MIDI port is specified.
MCIERR_SEQ_NOMIDIPRESENT	No MIDI ports are present.
MCIERR_SEQ_TIMER	A timer error occurred.
The following additional return values are defined for MCI waveform audio devices:

Value	Meaning
MCIERR_WAVE_INPUTSINUSE	No compatible waveform recording device is free.
MCIERR_WAVE_INPUTSUNSUITABLE	No compatible waveform recording devices are available.
MCIERR_WAVE_INPUTUNSPECIFIED	Any compatible waveform recording device may be used.
MCIERR_WAVE_OUTPUTSINUSE	No compatible waveform playback device is free.
MCIERR_WAVE_OUTPUTSUNSUITABLE	No compatible waveform playback devices are available.
MCIERR_WAVE_OUTPUTUNSPECIFIED	Any compatible waveform playback device may be used.
MCIERR_WAVE_SETINPUTINUSE	The set waveform recording device is in use.
MCIERR_WAVE_SETINPUTUNSUITABLE	The set waveform recording device is incompatible with the set format.
MCIERR_WAVE_SETOUTPUTINUSE	The set waveform playback device is in use.
MCIERR_WAVE_SETOUTPUTUNSUITABLE	The set waveform playback device is incompatible with the set format.
Use the MCI_OPEN command message to obtain the device identifier specified by the IDDevice parameter.

See Also

»mciGetErrorString«, »mciSendString«


  mciSendString

MCIERROR mciSendString(lpszCommand, lpszReturnString, cchReturn, hwndCallback)
LPCTSTR  lpszCommand;   /* address of MCI command string */
LPTSTR  lpszReturnString;   /* address of return buffer */
UINT  cchReturn;   /* size of return buffer, in characters  */
HANDLE  hwndCallback;   /* callback-window handle */

The mciSendString function sends a command string to a Media Control Interface (MCI) device. The device that the command is sent to is specified in the command string.

Parameters

lpszCommand

Points to a null-terminated string that specifies an MCI command string of the following form:

    [command] [device] [parameters]

lpszReturnString

Points to a buffer that receives return information. If no return information is needed, this parameter can be NULL.

cchReturn

Specifies the size, in characters, of the return buffer specified by the lpszReturnString parameter.

hwndCallback

Specifies a handle of a callback window if "notify" was specified in the command string.

Return Value

If the function succeeds, the return value is zero. Otherwise, the return value is an error code. The low-order word of the returned doubleword contains the error return value. For more information about possible error values, see the Comments section in this entry.

To get a text description of mciSendString return values, pass the return value to the mciGetErrorString function.

Comments

The error values listed for the mciSendCommand function also apply to mciSendString. The following error values are unique to mciSendString:

Value	Meaning
MCIERR_BAD_CONSTANT	The value specified for a parameter is unknown.
MCIERR_BAD_INTEGER	An integer in the command was invalid or missing.
MCIERR_DUPLICATE_FLAGS	A flag or value was specified twice.
MCIERR_MISSING_COMMAND_STRING	No command was specified.
MCIERR_MISSING_DEVICE_NAME	No device name was specified.
MCIERR_MISSING_STRING_ARGUMENT	A string value was missing from the command.
MCIERR_NEW_REQUIRES_ALIAS	An alias must be used with the "new" device name.
MCIERR_NO_CLOSING_QUOTE	A closing quotation mark is missing.
MCIERR_NOTIFY_ON_AUTO_OPEN	The "notify" flag is illegal with auto-open.
MCIERR_PARAM_OVERFLOW	The output string was not long enough.
MCIERR_PARSER_INTERNAL	An internal parser error occurred.
MCIERR_UNRECOGNIZED_KEYWORD	An unknown command parameter was specified.
See Also

»mciGetErrorString«, »mciSendCommand«


  mciSetYieldProc

UINT mciSetYieldProc(IDDevice, yp, dwYieldData)
MCIDEVICEID  IDDevice;   /* device to set yield procedure for */
YIELDPROC  yp;   /* address of yield procedure */
DWORD  dwYieldData;   /* yield-procedure data */

The mciSetYieldProc function sets the address of a procedure to be called periodically when a Media Control Interface (MCI) device is waiting for a command to finish because the WAIT flag was specified.

Parameters

IDDevice

Specifies the identifier of the device to assign a procedure to.

yp

Specifies the address of the procedure to call when yielding for the given device. If this parameter is NULL, the function disables any existing yield procedure.

dwYieldData

Specifies the data to be sent to the yield procedure when it is called for the given device.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function overrides any previous yield procedure for this device.

See Also

»mciGetYieldProc«


  MessageBeep

BOOL MessageBeep(fuType)
UINT  fuType;   /* sound type */

The MessageBeep function plays a waveform sound. The waveform sound for each sound type is identified by an entry in the [sounds] section of the registry.

Parameters

fuType

Specifies the sound type, as identified by an entry in the [sounds] section of the registry. This parameter can be one of the following values:

Value	Sound
0xFFFFFFFF	Standard beep using the computer speaker
MB_ICONASTERISK	SystemAsterisk
MB_ICONEXCLAMATION	SystemExclamation
MB_ICONHAND	SystemHand
MB_ICONQUESTION	SystemQuestion
MB_OK	SystemDefault
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

After queuing the sound, the MessageBeep function returns control to the calling function and plays the sound asynchronously.

If it cannot play the specified alert sound, MessageBeep attempts to play the system default sound. If it cannot play the system default sound, the function produces a standard beep sound by using the computer speaker.

The user can disable the warning beep by using the Control Panel Sound application.

See Also

»FlashWindow«, »MessageBox«


  MessageBox

int MessageBox(hwndOwner, lpszText, lpszTitle, fuStyle)
HWND  hwndOwner;   /* handle of owner window */
LPCTSTR  lpszText;   /* address of text in message box */
LPCTSTR  lpszTitle;   /* address of title of message box  */
UINT  fuStyle;   /* style of message box */

The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, plus any combination of predefined icons and push buttons.

Parameters

hwndOwner

Identifies the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.

lpszText

Points to a null-terminated string containing the message to be displayed.

lpszTitle

Points to a null-terminated string used for the dialog box title. If this parameter is NULL, the default title Error is used.

fuStyle

Specifies the contents and behavior of the dialog box. This parameter can be a combination of the following values:

Value	Meaning
MB_ABORTRETRYIGNORE	The message box contains three push buttons: Abort, Retry, and Ignore.
MB_APPLMODAL	The user must respond to the message box before continuing work in the window identified by the hwndOwner parameter. However, the user can move to the windows of other applications and work in those windows. MB_APPLMODAL is the default if neither MB_SYSTEMMODAL nor MB_TASKMODAL is specified.
MB_DEFAULT_DESKTOP_ONLY	The desktop currently receiving input must be a default desktop; otherwise, the function fails. A default desktop is one an application runs on after the user has logged on.
MB_DEFBUTTON1	The first button is the default. Note that the first button is always the default unless MB_DEFBUTTON2 or MB_DEFBUTTON3 is specified.
MB_DEFBUTTON2	The second button is the default.
MB_DEFBUTTON3	The third button is the default.
MB_ICONASTERISK	Same as MB_ICONINFORMATION.
MB_ICONEXCLAMATION	An exclamation-point icon appears in the message box.
MB_ICONHAND	Same as MB_ICONSTOP.
MB_ICONINFORMATION	An icon consisting of a lowercase letter i in a circle appears in the message box.
MB_ICONQUESTION	A question-mark icon appears in the message box.
MB_ICONSTOP	A stop-sign icon appears in the message box.
MB_OK	The message box contains one push button: OK.
MB_OKCANCEL	The message box contains two push buttons: OK and Cancel.
MB_RETRYCANCEL	The message box contains two push buttons: Retry and Cancel.
MB_SETFOREGROUND	The message box becomes the foreground window. Internally, Windows calls the SetForegroundWindow function for the message box.
MB_SYSTEMMODAL	All applications are suspended until the user responds to the message box. Unless the application specifies MB_ICONHAND, the message box does not become modal until after it is created; consequently, the owner window and other windows continue to receive messages resulting from its activation. Use system-modal message boxes to notify the user of serious, potentially damaging errors that require immediate attention (for example, running out of memory).
MB_TASKMODAL	Same as MB_APPLMODAL except that all the top-level windows belonging to the current task are disabled if the hwndOwner parameter is NULL. Use this flag when the calling application or library does not have a window handle available but still needs to prevent input to other windows in the current application without suspending other applications.
MB_YESNO	The message box contains two push buttons: Yes and No.
MB_YESNOCANCEL	The message box contains three push buttons: Yes, No, and Cancel.
Return Value

The return value is zero if there is not enough memory to create the message box. Otherwise, it is one of the following menu-item values returned by the dialog box:

Value	Meaning
IDABORT	Abort button was selected.
IDCANCEL	Cancel button was selected.
IDIGNORE	Ignore button was selected.
IDNO	No button was selected.
IDOK	OK button was selected.
IDRETRY	Retry button was selected.
IDYES	Yes button was selected.
If a message box has a Cancel button, the function returns the IDCANCEL value if either the ESC key is pressed or the Cancel button is selected. If the message box has no Cancel button, pressing ESC has no effect.

Comments

When you use a system-modal message box to indicate that the system is low on memory, the strings pointed to by the lpszText and lpszTitle parameters should not be taken from a resource file, because an attempt to load the resource may fail.

When an application calls the MessageBox function and specifies the MB_ICONHAND and MB_SYSTEMMODAL flags for the fuStyle parameter, Windows displays the resulting message box regardless of available memory. When these flags are specified, Windows limits the length of the message box text to three lines. Windows does not automatically break the lines to fit in the message box, however, so the message string must contain carriage returns to break the lines at the appropriate places.

If you create a message box while a dialog box is present, use the handle of the dialog box as the hwndOwner parameter. The hwndOwner parameter should not identify a child window, such as a control in a dialog box.

See Also

»FlashWindow«, »MessageBeep«, »MessageBoxEx«, »SetForegroundWindow«


  MessageBoxEx

int MessageBoxEx(hwndOwner, lpszText, lpszCaption, fuStyle, wLanguageID)
HWND  hwndOwner;   /* handle of owner window */
LPCTSTR  lpszText;   /* address of text in message box */
LPCTSTR  lpszTitle;   /* address of title of message box */
UINT  fuStyle;   /* style of message box */
WORD  wLanguageID;   /* language identifier */

The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, plus any combination of predefined icons and push buttons. The wLanguageId parameter specifies which set of language resources is used for the predefined push buttons. For full descriptions of the other parameters of MessageBoxEx, see the description of the »MessageBox« function.

Parameters

hwndOwner

Identifies the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.

lpszText

Points to a null-terminated string containing the message to be displayed.

lpszTitle

Points to a null-terminated string used for the dialog box title. If this parameter is NULL, the default title Error is used.

fuStyle

Specifies the contents and behavior of the dialog box. This parameter can be a combination of the following values:

Value	Meaning
MB_ABORTRETRYIGNORE	The message box contains three push buttons: Abort, Retry, and Ignore.
MB_APPLMODAL	The user must respond to the message box before continuing work in the window identified by the hwndOwner parameter. However, the user can move to the windows of other applications and work in those windows. MB_APPLMODAL is the default if neither MB_SYSTEMMODAL nor MB_TASKMODAL is specified.
MB_DEFAULT_DESKTOP_ONLY	The desktop currently receiving input must be a default desktop; otherwise, the function fails. A default desktop is one an application runs on after the user has logged on.
MB_DEFBUTTON1	The first button is the default. Note that the first button is always the default unless MB_DEFBUTTON2 or MB_DEFBUTTON3 is specified.
MB_DEFBUTTON2	The second button is the default.
MB_DEFBUTTON3	The third button is the default.
MB_ICONASTERISK	Same as MB_ICONINFORMATION.
MB_ICONEXCLAMATION	An exclamation-point icon appears in the message box.
MB_ICONHAND	Same as MB_ICONSTOP.
MB_ICONINFORMATION	An icon consisting of a lowercase letter i in a circle appears in the message box.
MB_ICONQUESTION	A question-mark icon appears in the message box.
MB_ICONSTOP	A stop-sign icon appears in the message box.
MB_OK	The message box contains one push button: OK.
MB_OKCANCEL	The message box contains two push buttons: OK and Cancel.
MB_RETRYCANCEL	The message box contains two push buttons: Retry and Cancel.
MB_SETFOREGROUND	The message box becomes the foreground window. Internally, Windows calls the SetForegroundWindow function for the message box.
MB_SYSTEMMODAL	All applications are suspended until the user responds to the message box. Unless the application specifies MB_ICONHAND, the message box does not become modal until after it is created; consequently, the owner window and other windows continue to receive messages resulting from its activation. Use system-modal message boxes to notify the user of serious, potentially damaging errors that require immediate attention (for example, running out of memory).
MB_TASKMODAL	Same as MB_APPLMODAL except that all the top-level windows belonging to the current task are disabled if the hwndOwner parameter is NULL. Use this flag when the calling application or library does not have a window handle available but still needs to prevent input to other windows in the current application without suspending other applications.
MB_YESNO	The message box contains two push buttons: Yes and No.
MB_YESNOCANCEL	The message box contains three push buttons: Yes, No, and Cancel.
wLanguageId

Specifies the language in which to display the text contained in the predefined push buttons. This value must be in the form returned by the MAKELANGID macro. For a description of the possible primary language identifiers and sublanguage identifiers, see the Comments section.

Return Value

If the function fails, the return value is zero, in which case extended error information can be obtained by calling the GetLastError function.

If the function succeeds, the return value is a nonzero menu-item value returned by the dialog box.

Value	Meaning
IDABORT	Abort button was selected.
IDCANCEL	Cancel button was selected.
IDIGNORE	Ignore button was selected.
IDNO	No button was selected.
IDOK	OK button was selected.
IDRETRY	Retry button was selected.
IDYES	Yes button was selected.
If a message box has a Cancel button, the function returns the IDCANCEL value when either the ESC key or Cancel button is pressed. If the message box has no Cancel button, pressing the ESC key has no effect.

Comments

When you create a system-modal message box to indicate that the system is low on memory, the strings passed as the lpszText and lpszCaption parameters should not be taken from a resource file, because an attempt to load the resource may fail.

When an application calls the MessageBox function and specifies the MB_ICONHAND and MB_SYSTEMMODAL flags for the fuStyle parameter, the Win32 API displays the resulting message box regardless of available memory. When you specify these flags, Windows limits the length of the message-box text to one line.

If you create a message box while a dialog box is present, use the handle of the dialog box as the hwndOwner parameter. The hwndOwner parameter should not identify a child window, such as a dialog box.

The following table shows the possible language identifiers and sublanguage identifiers, along with a description of each.

Primary Language Identifiers and Sublanguage Identifiers

Primary language	Sublanguage	Description
LANG_ NEUTRAL	SUBLANG_ DEFAULT	Default sublanguage
LANG_ ALBANIAN		Albanian
LANG_ ARABIC		Arabic
LANG_ BAHASA		Bahasa (Indonesian)
LANG_ BULGARIAN		Bulgarian
LANG_ CATALAN		Catalan
LANG_ CHINESE	SUBLANG_ CHINESE_SIMPLIFIED	Simplified Chinese
LANG_ CHINESE	SUBLANG_ CHINESE_TRADITIONAL	Traditional Chinese
LANG_ CZECH		Czech
LANG_ DANISH		Danish
LANG_ DUTCH	SUBLANG_ DUTCH	Dutch
LANG_ DUTCH	SUBLANG_ DUTCH_BELGIAN	Belgian Dutch
LANG_ ENGLISH	SUBLANG_ ENGLISH_AUS	Australian English
LANG_ ENGLISH	SUBLANG_ ENGLISH_UK	UK English
LANG_ ENGLISH	SUBLANG_ ENGLISH_US	US English
LANG_ FINNISH		Finnish
LANG_ FRENCH	SUBLANG_ FRENCH	French
LANG_ FRENCH	SUBLANG_ FRENCH_BELGIAN	Belgian French
LANG_ FRENCH	SUBLANG_ FRENCH_CANADIAN	Canadian French
LANG_ FRENCH	SUBLANG_ FRENCH_SWISS	Swiss French
LANG_ GERMAN	SUBLANG_ GERMAN	German
LANG_ GERMAN	SUBLANG_ GERMAN_SWISS	Swiss German
LANG_ GREEK		Greek
LANG_ HEBREW		Hebrew
LANG_ HUNGARIAN		Hungarian
LANG_ ICELANDIC		Icelandic
LANG_ ITALIAN	SUBLANG_ ITALIAN	Italian
LANG_ ITALIAN	SUBLANG_ ITALIAN_SWISS	Swiss Italian
LANG_ JAPANESE		Japanese
LANG_ KOREAN		Korean
LANG_ NORWEGIAN	SUBLANG_ NORWEGIAN_BOKMAL	Norwegian − Bokmal
LANG_ NORWEGIAN	SUBLANG_ NORWEGIAN_NYNORSK	Norwegian − Nynorsk
LANG_ POLISH		Polish
LANG_ PORTUGUESE	SUBLANG_ PORTUGUESE	Portuguese
LANG_ PORTUGUESE	SUBLANG_ PORTUGUESE_BRAZILIAN	Brazilian Portuguese
LANG_ RHAETO_ROMAN		Rhaeto-Romanic
LANG_ ROMANIAN		Romanian
LANG_ RUSSIAN		Russian
LANG_ SERBO_CROATIAN	SUBLANG_ SERBO_CROATIAN_CYRILLIC	Serbo-Croatian (Cyrillic)
LANG_ SERBO_CROATIAN	SUBLANG_ SERBO_CROATIAN_LATIN	Croato-Serbian (Latin)
LANG_ SLOVAK		Slovak
LANG_ SPANISH	SUBLANG_ SPANISH	Spanish
LANG_ SPANISH	SUBLANG_ SPANISH_MEXICAN	Spanish Mexican
LANG_ SWEDISH		Swedish
LANG_ THAI		Thai
LANG_ TURKISH		Turkish
LANG_URDU		Urdu
See Also

»MessageBox«, »MessageBeep«


  MessageProc

LRESULT CALLBACK MessageProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* undefined */
LPARAM  lParam;   /* address of structure with message data */

The MessageProc hook procedure is an application-defined callback function the system calls after an input event occurs in a dialog box, message box, menu, or scroll bar, but before the message generated by the input event is processed. The hook procedure can monitor messages for a dialog box, message box, menu, or scroll bar created by a particular application or all applications.

Parameters

nCode

Specifies the type of input event that generated the message. This parameter can be one of the following values:

Value	Meaning
MSGF_DDEMGR	The input event occurred while the Dynamic Data Exchange Management Library (DDEML) was waiting for a synchronous transaction to finish. For more information about DDEML, see Chapter 77, "Dynamic Data Exchange Management Library."
MSGF_DIALOGBOX	The input event occurred in a message box or dialog box.
MSGF_MENU	The input event occurred in a menu.
MSGF_NEXTWINDOW	The input event occurred as a result of the user's pressing the ALT+TAB key combination to activate a different window.
MSGF_SCROLLBAR	The input event occurred in a scroll bar.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and return the value returned by CallNextHookEx.

wParam

Specifies a NULL value.

lParam

Points to an MSG structure. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the hook procedure processes the message, the return value must be a nonzero value. Otherwise, it must be zero.

Comments

An application installs the hook procedure by specifying the WH_MSGFILTER hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

If an application that uses the DDEML and performs synchronous transactions must process messages before they are dispatched, it must use the WH_MSGFILTER hook.

MessageProc is a placeholder for the application-defined function name.

See Also

»CallNextHookEx«, »SetWindowsHookEx«


  midiInAddBuffer

MMRESULT midiInAddBuffer(hMidiIn, lpmidiih, cbMidiIh)
HMIDIIN  hMidiIn;   /* MIDI input device */
LPMIDIHDR  lpmidiih;   /* address of MIDI header structure  */
UINT  cbMidiIh;   /* size of MIDI header structure, in bytes */

The midiInAddBuffer function sends an input buffer to a specified open Musical Instrument Digital Interface (MIDI) input device. When the buffer is filled, its address is sent back to the application. Input buffers are used only for system-exclusive messages.

Parameters

hMidiIn

Identifies to the MIDI input device.

lpmidiih

Points to a MIDIHDR structure that identifies the buffer. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbMidiIh

Specifies the size, in bytes, of the MIDIHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, the return value is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	Specified device handle is invalid.
MIDIERR_UNPREPARED	lpmidiih hasn't been prepared.
Comments

The data buffer must be prepared with the midiInPrepareHeader function before it is passed to midiInAddBuffer. The MIDIHDR  structure and the data buffer pointed to by its lpData member must be allocated by using the GlobalAlloc function and the GMEM_MOVEABLE and GMEM_SHARE flags, and must be locked using the GlobalLock function.

See Also

»midiInPrepareHeader«


  midiInClose

MMRESULT midiInClose(hMidiIn)
HMIDIIN  hMidiIn;   /* handle of input device to close */

The midiInClose function closes the specified Musical Instrument Digital Interface (MIDI) input device.

Parameters

hMidiIn

Identifies the MIDI input device. If the function succeeds, the handle is no longer valid after this call.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
Musical Instrument Digital Interface (MIDI)ERR_STILLPLAYING	There are still buffers in the queue.
Comments

If there are input buffers that have been sent using the midiInAddBuffer function and have not been returned to the application, the close operation will fail. Call the midiInReset function to mark all pending buffers as done.

See Also

»midiInOpen«, »midiInReset«


  midiInGetDevCaps

MMRESULT midiInGetDevCaps(IDDevice, lpmic, cbmic)
UINT  IDDevice;   /* identifier of device to query */
LPMIDIINCAPS  lpmic;   /* address of structure for capabilities  */
UINT  cbmic;   /* size of structure, in bytes */

The midiInGetDevCaps function queries a specified Musical Instrument Digital Interface (MIDI) input device to determine its capabilities.

Parameters

IDDevice

Identifies the MIDI input device.

lpmic

Points to a MIDIINCAPS structure that will receive information about the capabilities of the device. The MIDIINCAPS structure has the following form:

typedef struct midiincaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

} MIDIINCAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmic

Specifies the size, in bytes, of the MIDIINCAPS structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	Specified device identifier is out of range.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Use the midiInGetNumDevs function to determine the number of MIDI input devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. The MIDI_MAPPER constant may also be used as a device identifier. Only cbmic (or fewer) bytes of information are copied to the location pointed to by lpmic. If cbmic is zero, nothing is copied, and the function returns zero.

See Also

»midiInGetNumDevs«


  midiInGetErrorText

MMRESULT midiInGetErrorText(mmrError, lpszDesc, cchDesc)
MMRESULT  mmrError;   /* error code to get description for */
LPTSTR  lpszDesc;   /* address of buffer for description  */
UINT  cchDesc;   /* length of buffer, in characters */

The midiInGetErrorText function retrieves a text description of the specified error.

Parameters

mmrError

Specifies the error number.

lpszDesc

Points to a buffer that receives a null-terminated string that describes the error.

cchDesc

Specifies the length, in characters, of the buffer pointed to by lpszDesc.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code that can be MMYSYSERR_BADERRNUM, indicating that the specified error number is out of range.

Comments

If the text error description is longer than the specified buffer, the description is truncated. The returned error string is always null-terminated. If cchDesc is zero, nothing is copied, and the function returns zero. All error descriptions are less than MAXERRORLENGTH characters long.


  midiInGetID

MMRESULT midiInGetID(hMidiIn, lpIDDevice)
HMIDIIN  hMidiIn;   /* identifier of MIDI input device to query */
PUINT  lpIDDevice;   /* address of buffer for device identifier */

The midiInGetID function gets the device identifier for a Musical Instrument Digital Interface (MIDI) input device.

Parameters

hMidiIn

Identifies a handle of the MIDI input device.

lpIDDevice

Points to a variable that will receive the device identifier.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code that can be MMSYSERR_INVALHANDLE, indicating that the hMidiIn parameter specifies an invalid handle.


  midiInGetNumDevs

UINT midiInGetNumDevs(VOID)

The midiInGetNumDevs function retrieves the number of Musical Instrument Digital Interface (MIDI) input devices in the system.

Parameters

This function has no parameters.

Return Value

If the return succeeds, the value is the number of MIDI input devices present in the system.

See Also

»midiInGetDevCaps«


  midiInMessage

MMRESULT midiInMessage(hMidiIn, uMsg, dwParam1, dwParam2)
HMIDIIN  hMidiIn;   /* handle of MIDI device to receive message */
UINT  uMsg;   /* message */
DWORD  dwParam1;   /* application-defined parameter */
DWORD  dwParam2;   /* application-defined parameter */

The midiInMessage function sends a message to a Musical Instrument Digital Interface (MIDI) input device.

Parameters

hMidiIn

Identifies the MIDI device.

uMsg

Specifies the message to send.

dwParam1

Application-defined parameter.

dwParam2

Application-defined parameter.

Return Value

If the function succeeds, the return value is the value of the message sent.


  midiInOpen

MMRESULT midiInOpen(lphMidiIn, IDDevice, dwCallback, dwCallbackInstance, fdwCallback)
LPHMIDIIN  lphMidiIn;   /* address of variable for device handle */
UINT  IDDevice;   /* device identifier */
DWORD  dwCallback;   /* address of callback function */
DWORD  dwCallbackInstance;   /* callback instance data  */
DWORD  fdwCallback;   /* callback type */

The midiInOpen function opens the specified Musical Instrument Digital Interface (MIDI) input device.

Parameters

lphMidiIn

Points to a variable that will receive a handle identifying the opened MIDI input device. Use the handle of identify the device when calling other MIDI input functions.

IDDevice

Identifies the MIDI input device to be opened.

dwCallback

Specifies either the address of a fixed callback function or a handle of a window called with information about incoming MIDI messages. This parameter can be NULL if no callback is required.

For more information about the callback function, see the description of the »MidiProc« callback function.

dwCallbackInstance

Specifies user instance data passed to the callback function. This parameter is not used with window callbacks.

fdwCallback

Specifies a callback flag for opening the device. This parameter can be one of the following values:

Value	Meaning
CALLBACK_WINDOW	The dwCallback parameter is assumed to be a window handle.
CALLBACK_FUNCTION	The dwCallback parameter is assumed to be a callback procedure address.
CALLBACK_NULL	The dwCallback parameter is assumed to be NULL.
Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_ALLOCATED	The specified resource is already allocated.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
Comments

Use the midiInGetNumDevs function to determine the number of MIDI input devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present.

The MIDI_MAPPER constant may not be used with this function.

If a window is chosen to receive callback information, the following messages are sent to the window procedure function to indicate the progress of MIDI input:

MM_MIM_OPEN
MM_MIM_CLOSE
MM_MIM_DATA
MM_MIM_LONGDATA
MM_MIM_ERROR
MM_MIM_LONGERROR

If a function is chosen to receive callback information, the following messages are sent to the function to indicate the progress of MIDI input:

MIM_OPEN
MIM_CLOSE
MIM_DATA
MIM_LONGDATA
MIM_ERROR
MIM_LONGERROR

The callback function must reside in a DLL.

See Also

»midiInClose«, »MidiProc«


  midiInPrepareHeader

MMRESULT midiInPrepareHeader(hMidiIn, lpmidih, cbmidih)
HMIDIIN  hMidiIn;   /* handle of MIDI input device */
LPMIDIHDR  lpmidih;   /* address of structure for buffer to prepare  */
UINT  cbmidih;   /* size of structure in bytes */

The midiInPrepareHeader function prepares a buffer for Musical Instument Digital Interface (MIDI) input.

Parameters

hMidiIn

Identifies the MIDI input device.

lpmidih

Points to a MIDIHDR structure that identifies the buffer to be prepared. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmidih

Specifies the size, in bytes, of the MIDIHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
Comments

The MIDIHDR structure and the data block pointed to by its lpData member must be allocated by using the GlobalAlloc function and the GMEM_MOVEABLE and GMEM_SHARE flags, and must be locked by using the GlobalLock function. Preparing a header that has already been prepared has no effect, and the function returns zero.

See Also

»midiInUnprepareHeader«


  midiInReset

MMRESULT midiInReset(hMidiIn)
HMIDIIN  hMidiIn;   /* handle of device to reset */

The midiInReset function stops input on a given Musical Instument Digital Interface (MIDI) input device and marks all pending input buffers as done.

Parameters

hMidiIn

Identifies the MIDI input device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_INVALHANDLE, indicating that the specified device handle is invalid.

See Also

»midiInStart«, »midiInStop«, »midiInAddBuffer«, »midiInClose«


  midiInStart

MMRESULT midiInStart(hMidiIn)
HMIDIIN  hMidiIn;   /* handle of device to start */

The midiInStart function starts Musical Instument Digital Interface (MIDI) input on the specified input device.

Parameters

hMidiIn

Identifies the MIDI input device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_INVALHANDLE, indicating that the specified device handle is invalid.

Comments

This function resets the time-stamps to zero; time-stamp values for subsequently received messages are relative to the time this function was called.

All messages other than system-exclusive messages are sent directly to the client when received. System-exclusive messages are placed in the buffers supplied by the midiInAddBuffer function; if there are no buffers in the queue, the data is thrown away without notification to the client, and input continues.

Buffers are returned to the client when full, when a complete system-exclusive message has been received, or when the midiInReset function is called. The dwBytesRecorded member in the header will contain the actual length of data received.

Calling this function when input is already started has no effect, and the function returns zero.

See Also

»midiInReset«, »midiInStop«


  midiInStop

MMRESULT midiInStop(hMidiIn)
HMIDIIN  hMidiIn;   /* handle of device to stop */

The midiInStop function stops Musical Instument Digital Interface (MIDI) input on the specified MIDI input device.

Parameters

hMidiIn

Identifies the MIDI input device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_INVALHANDLE, indicating that thew speicified handle is invalid.

Comments

Current status (running status, parsing state, etc.) is maintained across calls to the midiInStop and midiInStart functions. If there are any system-exclusive message buffers in the queue, the current buffer is marked as done. (The dwBytesRecorded member in the header will contain the actual length of data.) However, any empty buffers in the queue remain there. Calling this function when input is not started has no effect, and the function returns zero.

See Also

»midiInReset«, »midiInStart«


  midiInUnprepareHeader

MMRESULT midiInUnprepareHeader(hMidiIn, lpmidih, cbmidih)
HMIDIIN  hMidiIn;   /* handle of the MIDI input device */
LPMIDIHDR  lpmidih;   /* address of structure for data buffer  */
UINT  cbmidih;   /* size of structure, in bytes */

The midiInUnprepareHeader function cleans up the preparation performed by the midiInPrepareHeader function. The midiInUnprepareHeader function must be called after the device driver fills a data buffer and returns it to the application. You must call this function before freeing the data buffer.

Parameters

hMidiIn

Identifies the Musical Instument Digital Interface (MIDI) input device.

lpmidih

Points to a MIDIHDR structure that identifies the data buffer to be cleaned up. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmidih

Specifies the size, in bytes, of the MIDIHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MIDIERR_STILLPLAYING	The lpmidih buffer is still in the queue.
Comments

This function complements the midiInPrepareHeader function. You must call this function before freeing the data buffer by using the GlobalFree function. After passing a buffer to the device driver by using the midiInAddBuffer function, you must wait until the driver is finished with the buffer before calling midiInUnprepareHeader. Unpreparing a buffer that has not been prepared has no effect, and the function returns zero.

See Also

»midiInPrepareHeader«


  midiOutCacheDrumPatches

MMRESULT midiOutCacheDrumPatches(hMidiOut, uPatch, lpwkya, fuCache)
HMIDIOUT  hMidiOut;   /* handle of MIDI output device */
UINT  uPatch;   /* patch number */
LPWORD  lpwkya;   /* address of key array  */
UINT  fuCache;   /* cache options */

The midiOutCacheDrumPatches function requests that an internal Musical Instument Digital Interface (MIDI) synthesizer device preload a specified set of key-based percussion patches. Some synthesizers are not capable of keeping all percussion patches loaded simultaneously. Caching patches ensures specified patches are available.

Parameters

hMidiOut

Identifies the open MIDI output device. This device must be an internal MIDI synthesizer.

uPatch

Specifies which drum patch number to use. Set this parameter to zero to cache the default drum patch.

lpwkya

Points to a KEYARRAY array (an array of unsigned integer values) indicating the key numbers of the specified percussion patches to be cached or uncached.

fuCache

Specifies options for the cache operation. Only one of the following flags can be specified:

Value	Meaning
MIDI_CACHE_ALL	Cache all of the specified patches. If they can't all be cached, cache none, clear the KEYARRAY array, and return MMSYSERR_NOMEM.
MIDI_CACHE_BESTFIT	Cache all of the specified patches. If all patches can't be cached, cache as many patches as possible, change the KEYARRAY array to reflect which patches were cached, and return MMSYSERR_NOMEM.
MIDI_CACHE_QUERY	Change the KEYARRAY array to indicate which patches are currently cached.
MIDI_UNCACHE	Uncache the specified patches and clear the KEYARRAY array.
Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The specified device does not support patch caching.
MMSYSERR_NOMEM	The device does not have enough memory to cache all of the requested patches.
Comments

The KEYARRAY data type is defined as:

typedef WORD KEYARRAY[MIDIPATCHSIZE];

Each element of the array represents one of the 128 key-based percussion patches and has bits set for each of the 16 MIDI channels that use that particular patch. The least-significant bit represents physical channel 0; the most-significant bit represents physical channel 15. For example, if the patch on key number 60 is used by physical channels 9 and 15, element 60 would be set to 0x8200.

This function applies only to internal MIDI synthesizer devices. Not all internal synthesizers support patch caching. Use the MIDICAPS_CACHE flag to test the dwSupport  member of the MIDIOUTCAPS structure filled by the midiOutGetDevCaps function to see if the device supports patch caching.

See Also

»midiOutCachePatches«


  midiOutCachePatches

MMRESULT midiOutCachePatches(hMidiOut, uBank, lpwpa, fuCache)
HMIDIOUT  hMidiOut;   /* handle of MIDI output device */
UINT  uBank;   /* patch bank number */
LPWORD  lpwpa;   /* address of patch array  */
UINT  fuCache;   /* cache options */

The midiOutCachePatches function requests that an internal Musical Instument Digital Interface (MIDI) synthesizer device preload a specified set of patches. Some synthesizers are not capable of keeping all patches loaded simultaneously and must load data from disk when they receive MIDI program-change messages. Caching patches ensures specified patches are immediately available.

Parameters

hMidiOut

Identifies the open MIDI output device. This device must be an internal MIDI synthesizer.

uBank

Specifies which bank of patches should be used. This parameter should be set to zero to cache the default patch bank.

lpwpa

Points to a PATCHARRAY array indicating the patches to be cached or uncached.

fuCache

Specifies options for the cache operation. Only one of the following flags can be specified:

Value	Meaning
MIDI_CACHE_ALL	Cache all of the specified patches. If they can't all be cached, cache none, clear the PATCHARRAY array, and return MMSYSERR_NOMEM.
MIDI_CACHE_BESTFIT	Cache all of the specified patches. If all patches can't be cached, cache as many patches as possible, change the PATCHARRAY array to reflect which patches were cached, and return MMSYSERR_NOMEM.
MIDI_CACHE_QUERY	Change the PATCHARRAY array to indicate which patches are currently cached.
MIDI_UNCACHE	Uncache the specified patches and clear the PATCHARRAY array.
Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The specified device does not support patch caching.
MMSYSERR_NOMEM	The device does not have enough memory to cache all of the requested patches.
Comments

The PATCHARRAY data type is defined as follows:

typedef WORD PATCHARRAY[MIDIPATCHSIZE];

Each element of the array represents one of the 128 patches and has bits set for each of the 16 MIDI channels that use that particular patch. The least-significant bit represents physical channel 0; the most-significant bit represents physical channel 15 (0x0F). For example, if patch 0 is used by physical channels 0 and 8, element 0 would be set to 0x0101.

This function only applies to internal MIDI synthesizer devices. Not all internal synthesizers support patch caching. Use the MIDICAPS_CACHE flag to test the dwSupport member of the MIDIOUTCAPS structure filled by the midiOutGetDevCaps function to see if the device supports patch caching.

See Also

»midiOutCacheDrumPatches«


  midiOutClose

MMRESULT midiOutClose(hMidiOut)
HMIDIOUT  hMidiOut;   /* handle of device to close */

The midiOutClose function closes the specified Musical Instument Digital Interface (MIDI) output device.

Parameters

hMidiOut

Identifies the MIDI output device. If the function is successful, the handle is no longer valid after the function returns.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the follow:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MIDIERR_STILLPLAYING	There are still buffers in the queue.
Comments

If there are output buffers that have been sent with the midiOutLongMsg function and haven't been returned to the application, the close operation will fail. Call the midiOutReset function to mark all pending buffers as done.

See Also

»midiOutOpen«, »midiOutReset«


  midiOutGetDevCaps

MMRESULT midiOutGetDevCaps(IDDevice, lpmidioc, cbmidioc)
UINT  IDDevice;   /* device identifier to query */
LPMIDIOUTCAPS  lpmidioc;   /* address of structure for device caps  */
UINT  cbmidioc;   /* size of structure, in bytes */

The midiOutGetDevCaps function queries a specified Musical Instument Digital Interface (MIDI) output device to determine its capabilities.

Parameters

IDDevice

Identifies the MIDI output device to query.

lpmidioc

Points to a MIDIOUTCAPS structure that receives information about the capabilities of the device. The MIDIOUTCAPS structure has the following form:

typedef struct midioutcaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    WORD  wTechnology;

    WORD  wVoices;

    WORD  wNotes;

    WORD  wChannelMask;

    DWORD  dwSupport;

} MIDIOUTCAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmidioc

Specifies the size, in bytes, of the MIDIOUTCAPS structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the follow:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device ID is out of range.
MMSYSERR_NODRIVER	The driver was not installed.
MMSYSERR_NOMEM	The system is unable to load the mapper string description.
Comments

Use the midiOutGetNumDevs function to determine the number of MIDI output devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. The MIDI_MAPPER constant may also be used as a device identifier. Only cbmidioc (or fewer) bytes of information are copied to the location pointed to by lpmidioc. If cbmidioc is zero, nothing is copied, and the function returns zero.

See Also

»midiOutGetNumDevs«


  midiOutGetErrorText

MMRESULT midiOutGetErrorText(mmrError, lpszDesc, cchDesc)
MMRESULT  mmrError;   /* error code */
LPTSTR  lpszDesc;   /* address of buffer for description  */
UINT  cchDesc;   /* size of buffer, in characters */

The midiOutGetErrorText function retrieves a text description of the specified error.

Parameters

mmrError

Specifies the error number.

lpszDesc

Points to a buffer that will receive the error-description text.

cchDesc

Specifies the length, in characters, of the buffer at lpszDesc.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_BADERRNUM, indicating that the specified error number is out of range.

Comments

If the text error description is longer than the specified buffer, the description is truncated. The returned error string is always null-terminated. If cchDesc is zero, nothing is copied, and the function returns MMSYSERR_NOERROR. All error descriptions are less than MAXERRORLENGTH characters long.


  midiOutGetID

MMRESULT midiOutGetID(hMidiOut, lpIDDevice)
HMIDIOUT  hMidiOut;   /* handle of device to return ID for  */
PUINT  lpIDDevice;   /* address of buffer for device ID */

The midiOutGetID function retrieves the device identifier for the specified Musical Instument Digital Interface (MIDI) output device.

Parameters

hMidiOut

Identifies the MIDI output device.

lpIDDevice

Points to a variable that will receive the the device identifier.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_INVALHANDLE, indicating that the hMidiOut parameter specifies an invalid handle.


  midiOutGetNumDevs

UINT midiOutGetNumDevs(VOID)

The midiOutGetNumDevs function retrieves the number of Musical Instument Digital Interface (MIDI) output devices present in the system.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of MIDI output devices present in the system.

See Also

»midiOutGetDevCaps«


  midiOutGetVolume

MMRESULT midiOutGetVolume(IDDevice, lpdwVolume)
UINT  IDDevice;   /* identifier of device to get volume for */
LPDWORD  lpdwVolume;   /* address of buffer for volume setting */

The midiOutGetVolume function returns the current volume setting of a Musical Instument Digital Interface (MIDI) output device.

Parameters

IDDevice

Identifies the MIDI output device.

lpdwVolume

Points to a location to be filled with the current volume setting. The low-order word of this location contains the left channel volume setting, and the high-order word contains the right channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.

If a device does not support both left and right volume control, the low-order word of the specified location contains the mono volume level.

The full 16-bit settings set with the midiOutSetVolume function is returned, regardless of whether the device supports the full 16 bits of volume-level control.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function is not supported.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Not all devices support volume control. To determine whether the device supports volume control, use the MIDICAPS_VOLUME flag to test the dwSupport member of the MIDIOUTCAPS structure (filled by the midiOutGetDevCaps function).

To determine whether the device supports volume control on both the left and right channels, use the MIDICAPS_LRVOLUME flag to test the dwSupport member of the MIDIOUTCAPS structure (filled by midiOutGetDevCaps).

See Also

»midiOutSetVolume«


  midiOutLongMsg

MMRESULT midiOutLongMsg(hMidiOut, lpmidih, cbmidih)
HMIDIOUT  hMidiOut;   /* handle of device to send message to */
LPMIDIHDR  lpmidih;   /* structure with data buffer  */
UINT  cbmidih;   /* size of structure, in bytes */

The midiOutLongMsg function sends a system-exclusive Musical Instument Digital Interface (MIDI) message to the specified MIDI output device.

Parameters

hMidiOut

Identifies the MIDI output device.

lpmidih

Points to a MIDIHDR structure that identifies the MIDI data buffer. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmidih

Specifies the size, in bytes, of the MIDIHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MIDIERR_UNPREPARED	The lpmidih buffer has not been prepared.
MIDIERR_NOTREADY	The hardware is busy with other data.
Comments

The data buffer must be prepared by using the midiOutPrepareHeader function before it is passed to midiOutLongMsg. The MIDIHDR structure and the data buffer pointed to by its lpData member must be allocated by using the GlobalAlloc function and using the GMEM_MOVEABLE and GMEM_SHARE flags, and must be locked by using the GlobalLock function. The MIDI output device driver determines whether the data is sent synchronously or asynchronously.

See Also

»midiOutPrepareHeader«, »midiOutShortMsg«


  midiOutMessage

MMRESULT midiOutMessage(hMidiOut, uMsg, dwParam1, dwParam2)
HMIDIOUT  hMidiOut;   /* handle of device to send message to */
UINT  uMsg;   /* message */
DWORD  dwParam1;   /* application-defined parameter */
DWORD  dwParam2;   /* application-defined parameter */

The midiOutMessage function sends a message to a Musical Instument Digital Interface (MIDI) device driver.

Parameters

hMidiOut

Identifies the MIDI device to send a message to.

uMsg

Specifies the message to send.

dwParam1

Application-defined parameter.

dwParam2

Application-defined parameter.

Return Value

If the function succeeds, the Return the value is the message sent.


  midiOutOpen

MMRESULT midiOutOpen(lphMidiOut, IDDevice, dwCallback, dwCallbackInstance,
fdwCallback)
LPHMIDIOUT  lphMidiOut;   /* variable to receive output device handle */
UINT  IDDevice;   /* device ID */
DWORD  dwCallback;   /* address of callback function */
DWORD  dwCallbackInstance;   /* callback instance data  */
DWORD  fdwCallback;   /* callback type */

The midiOutOpen function opens a specified Musical Instument Digital Interface (MIDI) output device for playback.

Parameters

lphMidiOut

Points to a variable that receives a handle identifying the opened MIDI output device. Use the handle of identify the device when calling other MIDI output functions.

IDDevice

Identifies the MIDI output device to be opened.

dwCallback

Specifies the address of a fixed callback function or a handle of a window called with information about incoming MIDI messages. This parameter can be NULL if no callback is required.

For more information about the callback function, see the description of the »MidiProc« callback function.

dwCallbackInstance

Specifies user instance data passed to the callback function. This parameter is not used with window callbacks.

fdwCallback

Specifies a callback flag for opening the device. This parameter can have one of the following values:

Value	Meaning
CALLBACK_WINDOW	The dwCallback parameter is assumed to be a window handle.
CALLBACK_FUNCTION	The dwCallback parameter is assumed to be a callback procedure address.
CALLBACK_NULL	The dwCallback parameter is assumed to be NULL.
Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_ALLOCATED	The specified resource is already allocated.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
MIDIERR_NOMAP	There is no current MIDI map. This occurs only when opening the mapper.
MIDIERR_NODEVICE	A port in the current MIDI map doesn't exist. This occurs only when opening the mapper.
Comments

Use the midiOutGetNumDevs function to determine the number of MIDI output devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. You can also specify MIDI_MAPPER as the device identifier to open the MIDI mapper.

If a window is chosen to receive callback information, the following messages are sent to the window procedure function to indicate the progress of MIDI output: MM_MOM_OPEN, MM_MOM_CLOSE, MM_MOM_DONE.

If a function is chosen to receive callback information, the following messages are sent to the function to indicate the progress of MIDI output: MOM_OPEN, MOM_CLOSE, MOM_DONE. The callback function must reside in a dynamic-link library (DLL).

See Also

»midiOutClose«


  midiOutPrepareHeader

MMRESULT midiOutPrepareHeader(hMidiOut, lpmidih, cbmidih)
HMIDIOUT  hMidiOut;   /* handle of MIDI output device */
LPMIDIHDR  lpmidih;   /* address of structure for buffer to prepare  */
UINT  cbmidih;   /* size of structure in bytes */

The midiInPrepareHeader function prepares a buffer for Musical Instument Digital Interface (MIDI) output.

Parameters

hMidiOut

Identifies the MIDI output device.

lpmidih

Points to a MIDIHDR structure that identifies the buffer to be prepared. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmidih

Specifies the size, in bytes, of the MIDIHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
Comments

The MIDIHDR structure and the data block pointed to by its lpData member must be allocated by using the GlobalAlloc function and the GMEM_MOVEABLE and GMEM_SHARE flags and must be locked using the GlobalLock function. Preparing a header that has already been prepared has no effect, and the function returns zero.

See Also

»midiOutUnprepareHeader«


  midiOutReset

MMRESULT midiOutReset(hMidiOut)
HMIDIOUT  hMidiOut;   /* handle of output device to stop */

The midiOutReset function turns off all notes on all Musical Instument Digital Interface (MIDI) channels for the specified MIDI output device. Any pending system-exclusive output buffers are marked as done and returned to the application.

Parameters

hMidiOut

Identifies the MIDI output device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_INVALHANDLE, indicating that the specified device handle is invalid.

Comments

To turn off all notes, a note-off message for each note for each channel is sent. In addition, the sustain controller is turned off for each channel.

See Also

»midiOutClose«, »midiOutLongMsg«


  midiOutSetVolume

MMRESULT midiOutSetVolume(IDDevice, dwVolume)
UINT  IDDevice;   /* identifier of MIDI device to set volume for  */
DWORD  dwVolume;   /* new volume setting */

The midiOutSetVolume function sets the volume of a Musical Instument Digital Interface (MIDI) output device.

Parameters

IDDevice

Identifies the MIDI output device.

dwVolume

Specifies the new volume setting. The low-order word specifies the left channel volume setting, and the high-order word specifies the right channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.

If a device does not support both left and right volume control, the low-order word of the dwVolume parameter specifies the volume level, and the high-order word is ignored.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Not all devices support volume changes. To determine whether the device supports volume control, use the MIDICAPS_VOLUME flag to test the dwSupport member of the MIDIOUTCAPS structure (filled by the midiOutGetDevCaps function).

To determine whether the device supports volume control on both the left and right channels, use the MIDICAPS_LRVOLUME flag to test the dwSupport member of the MIDIOUTCAPS structure (filled by midiOutGetDevCaps).

Most devices do not support the full 16 bits of volume level control and will use only the high-order bits of the requested volume setting. For example, for a device that supports 4 bits of volume control, requested volume level values of 0x4000, 0x4fff, and 0x43be will all produce the same physical volume setting, 0x4000. The midiOutGetVolume function will return the full 16-bit setting set with midiOutSetVolume.

Volume settings are interpreted logarithmically. This means the perceived increase in volume is the same from 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

See Also

»midiOutGetVolume«


  midiOutShortMsg

MMRESULT midiOutShortMsg(hMidiOut, dwMsg)
HMIDIOUT  hMidiOut;   /* handle of output device to send message to  */
DWORD  dwMsg;   /* message to send */

The midiOutShortMsg function sends a short Musical Instument Digital Interface (MIDI) message to the specified MIDI output device. Use this function to send any MIDI message except for system-exclusive messages.

Parameters

hMidiOut

Identifies the MIDI output device.

dwMsg

Specifies the MIDI message. The message is packed into a doubleword with the first byte of the message in the low-order byte.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MIDIERR_NOTREADY	The hardware is busy with other data.
Comments

This function may not return until the message has been sent to the output device.

See Also

»midiOutLongMsg«


  midiOutUnprepareHeader

MMRESULT midiOutUnprepareHeader(hMidiOut, lpmidih, cbmidih)
HMIDIOUT  hMidiOut;   /* handle of the MIDI output device */
LPMIDIHDR  lpmidih;   /* address of structure for data buffer  */
UINT  cbmidih;   /* size of structure, in bytes */

The midiOutUnprepareHeader function cleans up the preparation performed by the midiOutPrepareHeader function. The midiOutUnprepareHeader function must be called after the device driver fills a data buffer and returns it to the application. You must call this function before freeing the data buffer.

Parameters

hMidiOut

Identifies the Musical Instument Digital Interface (MIDI) output device.

lpmidih

Points to a MIDIHDR structure that identifies the data buffer to be cleaned up. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmidih

Specifies the size of the MIDIHDR structure in bytes.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MIDIERR_STILLPLAYING	The lpMidiOutHdr buffer is still in the queue.
Comments

This function complements the midiOutPrepareHeader function. You must call this function before freeing the data buffer using the GlobalFree function. After passing a buffer to the device driver by using the midiOutLongMsg function, you must wait until the driver is finished with the buffer before calling midiOutUnprepareHeader.

Unpreparing a buffer that has not been prepared has no effect, and the function returns zero.

See Also

»midiOutPrepareHeader«


  MidiProc

void CALLBACK MidiProc(hMidiIn, uMsg, dwInstance, dwParam1, dwParam2)
HMIDIIN  hMidiIn;   /* handle of MIDI device */
UINT  uMsg;   /* MIDI message */
DWORD  dwInstance;   /* callback instance data */
DWORD  dwParam1;   /* application-defined parameter */
DWORD  dwParam2;   /* application-defined parameter */

The MidiProc function is an application-defined callback function that processes Musical Instument Digital Interface (MIDI) device messages. An application can specify the address of this function when it calls the midiInOpen or midiOutOpen function.

Parameters

hMidiIn

Identifies the MIDI device.

uMsg

Specifies a MIDI message.

dwInstance

Specifies the instance data supplied by using the midiInOpen or midiOutOpen function.

dwParam1

Specifies a parameter for the message.

dwParam2

Specifies a parameter for the message.

Return Value

This function does not return a value.

Comments

MidiProc is a placeholder for the application-defined function name.

There are several differences between MidiProc functions under Windows NT and under Windows 3.1 :

•	Under Windows 3.1, a MidiProc function is called at interrupt time. The call to a MidiProc function occurs on a separate thread under Windows NT.

•	Under Windows 3.1, a MidiProc function has to be in a dynamic link library. Under Windows NT, there is no such restriction.

•	Under Windows 3.1, a MidiProc function must be exported in a .DEF file. Under Windows NT, that is not necessary.

If source code must be compatible with Windows 3.1, it should follow the Windows 3.1 rules as noted briefly above and specified more fully in the Windows 3.1 documentation.

One other item should be noted carefully. There is a limited set of APIs that a Windows 3.1 MidiProc function may call. In Win32, that strict limitation has been removed. However, it is strongly recommended that a Windows NT MidiProc function restrain its calls to APIs in the same set, with the addition of the API SetEvent. Here is the Windows NT recommended list:

EnterCriticalSection	PostThreadMessage
LeaveCriticalSection	SetEvent
midiOutLongMsg	timeGetSystemTime
midiOutShortMsg	timeGetTime
OutputDebugStr	timeKillEvent
PostMessage	timeSetEvent
If an application's MidiProc function does stray from this list, it should be careful not to call APIs that take a long time to complete.

If a Win32 MidiProc shares data with other code, a Critical Section or similar mutual exclusion mechanism should be used to protect the integrity of the data.

See Also

»midiInOpen«, »TimeProc«, »WaveProc«, »MMIOProc«


  mmioAdvance

MMRESULT mmioAdvance(hmmio, lpmmioinfo, fuOperation)
HMMIO  hmmio;   /* file handle */
LPMMIOINFO  lpmmioinfo;   /* address of structure for file operation  */
UINT  fuOperation;   /* specifies operation */

The mmioAdvance function advances the input/output (I/O) buffer of a file set up for direct I/O buffer access with the mmioGetInfo function. If the file is opened for reading, the I/O buffer is filled from the disk. If the file is opened for writing and the MMIO_DIRTY flag is set in the dwFlags member of the MMIOINFO structure, the buffer is written to disk. The pchNext, pchEndRead, and pchEndWrite members of the MMIOINFO structure are updated to reflect the new state of the I/O buffer.

Parameters

hmmio

Identifies the file. This handle is returned by the mmioOpen function.

lpmmioinfo

Points to an MMIOINFO structure obtained with mmioGetInfo. The structure is used to set the current file information, then updated after the buffer is advanced. The MMIOINFO structure has the following form:

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuOperation

Specifies the operation to perform. This parameter must be one of the following values:

Value	Meaning
MMIO_READ	The buffer is filled from the file.
MMIO_WRITE	The buffer is written to the file.
Return Value

If the function is succeeds, the return value is zero; otherwise, it is an error code than can be one of the following:

Value	Meaning
MMIOERR_CANNOTWRITE	The contents of the buffer could not be written to disk.
MMIOERR_CANNOTREAD	An error occurred while re-filling the buffer.
MMIOERR_UNBUFFERED	The specified file is not opened for buffered I/O.
MMIOERR_CANNOTEXPAND	The specified memory file cannot be expanded, probably because the adwInfo[0] member was set to zero in the initial call to the mmioOpen function.
MMIOERR_OUTOFMEMORY	There was not enough memory to expand a memory file for further writing.
Comments

The mmioAdvance function advances the buffer by (pchNext − pchBuffer) bytes. All data in the buffer before pchNext is assumed to have already been read, while all data from pchNext to pchEndRead will be considered unread. So, when mmioAdvance is called, all data before pchNext will be overwritten. The buffer must not be treated as an array and pchNext must be incremented until pchNext equals pchEndRead.

If the specified file is opened for writing or for both reading and writing, the I/O buffer will be flushed to disk before the next buffer is read. If the I/O buffer cannot be written to disk because the disk is full, then mmioAdvance will return MMIOERR_CANNOTWRITE.

If the specified file is only open for writing, the MMIO_WRITE flag must be specified.

If you have written to the I/O buffer, you must set the MMIO_DIRTY flag in the dwFlags member of the MMIOINFO structure before calling mmioAdvance. Otherwise, the buffer will not be written to disk.

If the end of file is reached, mmioAdvance will still return successfully, even though no more data can be read. Thus, to check for the end of the file, it is necessary to see if the pchNext and pchEndRead members of the MMIOINFO structure are equal after calling mmioAdvance.

See Also

»mmioGetInfo«


  mmioAscend

MMRESULT mmioAscend(hmmio, lpmmcki, uReserved)
HMMIO  hmmio;   /* handle of RIFF file */
LPMMCKINFO  lpmmcki;   /* address of chunk information structure  */
UINT  uReserved;   /* reserved; must be zero */

The mmioAscend function ascends out of a chunk in a RIFF file descended into by using the mmioDescend function or created using the mmioCreateChunk function.

Parameters

hmmio

Identifies an open RIFF file.

lpmmcki

Points to a MMCKINFO structure previously filled by mmioDescend or mmioCreateChunk. The MMCKINFO structure has the following form:

typedef struct _MMCKINFO {

    FOURCC  ckid;

    DWORD  cksize;

    FOURCC  fccType;

    DWORD  dwDataOffset;

    DWORD  dwFlags;

} MMCKINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

uReserved

Reserved. Must be zero.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code than can be one of the following:

Value	Meaning
MMIOERR_CANNOTWRITE	The contents of the buffer could not be written to disk.
MMIOERR_CANNOTSEEK	There was an error while seeking to the end of the chunk.
Comments

If the chunk was descended into using the mmioDescend function, then the mmioAscend function seeks to the location following the end of the chunk (past the extra pad byte, if any).

If the chunk was created and descended into using the mmioCreateChunk function, or if the MMIO_DIRTY flag is set in the dwFlags member of the MMCKINFO structure referenced by lpmmcki, then the current file position is assumed to be the end of the data portion of the chunk. If the chunk size is not the same as the value stored in the cksize member when mmioCreateChunk was called, then mmioAscend corrects the chunk size in the file before ascending from the chunk. If the chunk size is odd, mmioAscend writes a null pad byte at the end of the chunk. After ascending from the chunk, the current file position is the location following the end of the chunk (past the extra pad byte, if any).

See Also

»mmioDescend«, »mmioCreateChunk«


  mmioClose

MMRESULT mmioClose(hmmio, fuOption)
HMMIO  hmmio;   /* handle of file to close */
UINT  fuOption;   /* specifies optional operation */

The mmioClose function closes a file opened by using the mmioOpen function.

Parameters

hmmio

Indentifies the file to close.

fuOption

Specifies options for the close operation.

Value	Meaning
MMIO_FHOPEN	If the file was opened by passing the Windows file handle of an already-opened file to mmioOpen, then using this flag tells mmioClose to close the MMIO file handle, but not the Windows file handle. (This is done by the I/O Proc).
Return Value

The return value is zero if the function is successful. Otherwise, the return value is an error code either from the mmioFlush function or from the I/O procedure. The error code can be one of the following:

Value	Meaning
MMIOERR_CANNOTWRITE	The contents of the buffer could not be written to disk.
MMIOERR_CANNOTCLOSE	There was a Windows file system error when the I/O Proc attempted to close the Windows file.
See Also

»mmioOpen«, »mmioFlush«


  mmioCreateChunk

MMRESULT mmioCreateChunk(hmmio, lpmmcki, fuOptions)
HMMIO  hmmio;   /* identifies file */
LPMMCKINFO  lpmmcki;   /* address of chunk information structure  */
UINT  fuOptions;   /* chunk creation options */

The mmioCreateChunk function creates a chunk in a RIFF file opened with the mmioOpen function. The new chunk is created at the current file position. After the new chunk is created, the current file position is the beginning of the data portion of the new chunk.

Parameters

hmmio

Identifies an open RIFF file.

lpmmcki

Points to a caller-supplied MMCKINFO structure that contains information about the chunk to be created. For information about how the MMCKINFO structure should be set up, see the Comments section. The MMCKINFO structure has the following form:

typedef struct _MMCKINFO {

    FOURCC  ckid;

    DWORD  cksize;

    FOURCC  fccType;

    DWORD  dwDataOffset;

    DWORD  dwFlags;

} MMCKINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuOptions

Specifies flags to optionally create either a "RIFF" chunk or a "LIST" chunk. Can contain one of the following flags:

Value	Meaning
MMIO_CREATERIFF	Creates a "RIFF" chunk.
MMIO_CREATELIST	Creates a "LIST" chunk.
Return Value

If the function is succeeds, the return value is zero; otherwise, it is an error code than can be one of the following:

Value	Meaning
MMIOERR_CANNOTWRITE	Unable to write the chunk header.
MMIOERR_CANNOTSEEK	Unable to determine offset of data portion of the chunk.
Comments

The MMCKINFO structure pointed to lpmmcki should be set up as follows:

•	The ckid member specifies the chunk identifier of the chunk. If fuOptions includes MMIO_CREATERIFF or MMIO_CREATELIST, this member will be filled by mmioCreateChunk.

•	The cksize member specifies the size of the data portion of the chunk, including the form type or list type (if any). If this value is not correct when the mmioAscend function is called to mark the end of the chunk, them mmioAscend will correct the chunk size.

•	The fccType member specifies the form type or list type if the chunk is a "RIFF" or "LIST" chunk. If the chunk is not a "RIFF" or "LIST" chunk, this member need not be filled in.

•	The dwDataOffset member need not be filled in. The mmioCreateChunk function will fill this member with the file offset of the data portion of the chunk.

•	The dwFlags member need not be filled in. The mmioCreateChunk function will set the MMIO_DIRTY flag in dwFlags.

This function cannot insert a chunk into the middle of a file. If a chunk is created anywhere but the end of a file, mmioCreateChunk will overwrite existing information in the file.


  mmioDescend

MMRESULT mmioDescend(hmmio, lpmmcki, lpmmckiParent, fuSearch)
HMMIO  hmmio;   /* handle of open RIFF file */
LPMMCKINFO  lpmmcki;   /* address of chunk information structure */
LPMMCKINFO  lpmmckiParent;   /* address of optional parent structure  */
UINT  fuSearch;   /* search-option flags */

The mmioDescend function descends into a chunk of a RIFF file opened by using the mmioOpen function. It can also search for a given chunk.

Parameters

hmmio

Identifies an open RIFF file.

lpmmcki

Points to an MMCKINFO structure that mmioDescend fills with the following information:

•	The ckid member is the chunk identifier of the chunk.

•	The cksize member is the size of the data portion of the chunk. The data size includes the form type or list type (if any), but does not include the 8-byte chunk header or the pad byte at the end of the data (if any).

•	The fccType member is the form type if ckid is "RIFF", or the list type if ckid is "LIST". Otherwise, it is NULL.

•	The dwDataOffset member is the file offset of the beginning of the data portion of the chunk. If the chunk is a "RIFF" chunk or a "LIST" chunk, then dwDataOffset is the offset of the form type or list type.

•	The dwFlags member contains other information about the chunk. Currently, this information is not used and is set to zero.

If the MMIO_FINDCHUNK, MMIO_FINDRIFF, or MMIO_FINDLIST flag is specified for fuSearch, then the MMCKINFO structure is also used to pass parameters to mmioDescend.

The ckid member specifies the four-character code of the chunk identifier, form type, or list type to search for.

lpmmckiParent

Points to an MMCKINFO structure identifying the parent of the chunk being searched for. A parent of a chunk is the enclosing chunk — only "RIFF" and "LIST" chunks can be parents. If lpmmckiParent is not NULL, then mmioDescend assumes the MMCKINFO structure it refers to was filled when mmioDescend was called to descend into the parent chunk, and mmioDescend will only search for a chunk within lpmmckiParent.

If lpmmckiParent is NULL, no parent chunk is being specified.

fuSearch

Specifies search options. Contains up to one of the following flags. If no flags are specified, mmioDescend descends into the chunk beginning at the current file position.

Value	Meaning
MMIO_FINDCHUNK	Searches for a chunk with the specified chunk identifier.
MMIO_FINDRIFF	Searches for a chunk with chunk identifier "RIFF" and with the specified form type.
MMIO_FINDLIST	Searches for a chunk with chunk identifier "LIST" and with the specified form type.
Return Value

The return value is zero if the function succeeds. Otherwise, the return value specifies an error code. If the end of the file (or the end of the parent chunk, if given) is reached before the desired chunk is found, the return value is MMIOERR_CHUNKNOTFOUND. Other error return values are possible, for instance MMIOERR_CANNOTSEEK.

Comments

A RIFF chunk consists of a four-byte chunk identifier (type FOURCC), followed by a four-byte chunk size (type DWORD), followed by the data portion of the chunk, followed by a null pad byte if the size of the data portion is odd. If the chunk identifier is "RIFF" or "LIST", the first four bytes of the data portion of the chunk are a form type or list type (type FOURCC).

If mmioDescend is used to search for a chunk, the file position should be at the beginning of a chunk before calling mmioDescend. The search begins at the current file position and continues to the end of the file. If a parent chunk is specified, the file position should be somewhere within the parent chunk before calling mmioDescend. In this case,the search begins at the current file position and continues to the end of the parent chunk.

If mmioDescend is unsuccessful in searching for a chunk, the current file position is undefined. If mmioDescend is successful, the current file position is changed. If the chunk is a "RIFF" or "LIST" chunk, the new file position will be just after the form type or list type (12 bytes from the beginning of the chunk). For other chunks, the new file position will be the start of the data portion of the chunk (8 bytes from the beginning of the chunk).

For efficient RIFF file input/output (I/O), use buffered I/O.

See Also

»mmioAscend«


  mmioFlush

MMRESULT mmioFlush(hmmio, uReserved)
HMMIO  hmmio;   /* handle of file to flush to */
UINT  uReserved;   /* reserved; must be zero */

The mmioFlush function writes the input/output (I/O) buffer of a file to disk, if the I/O buffer has been written to.

Parameters

hmmio

Identifies a file opened by using the mmioOpen function.

uReserved

Reserved. Must be zero.

Return Value

If the function is succeeds, the return value is zero; otherwise, it is an error code than can be MMIOERR_CANNOTWRITE, indicating that the contents of the buffer could not be written to disk.

Comments

Closing a file by using the mmioClose function will automatically flush the file's buffer.

If there is insufficient disk space to write the buffer, mmioFlush will fail, even if the preceding calls to the mmioWrite function were successful.


  mmioFOURCC

FOURCC mmioFOURCC(ch0, ch1, ch2, ch3)
CHAR  ch0;   /* character one */
CHAR  ch1;   /* character two */
CHAR  ch2;   /* character three  */
CHAR  ch3;   /* character four */

This macro converts four characters to a four-character code.

Parameters

ch0

The first character of the four-character code.

ch1

The second character of the four-character code.

ch2

The third character of the four-character code.

ch3

The fourth character of the four-character code.

Return Value

The return value is the four-character code created from the given characters.

Comments

This macro does not check to see if the four character code follows any conventions regarding which characters to include in a four-character code.

See Also

»mmioStringToFOURCC«


  mmioGetInfo

MMRESULT mmioGetInfo(hmmio, lpmmioi, uReserved)
HMMIO  hmmio;   /* handle of file to get information for */
LPMMIOINFO  lpmmioi;   /* address of structure for file information  */
UINT  uReserved;   /* reserved; must be zero */

The mmioGetInfo function retrieves information about a file opened by using the mmioOpen function. This information allows the caller to access the input/output (I/O) buffer directly, if the file is open for buffered I/O.

Parameters

hmmio

Identifies the file.

lpmmioi

Points to an MMIOINFO structure that receives information about the file. The MMIOINFO structure has the following form:

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

uReserved

Reserved. Must be zero.

Return Value

The return value is zero if the function is successful.

Comments

To directly access the I/O buffer of a file opened for buffered I/O, use the following members of the MMIOINFO structure filled by mmioGetInfo:

•	The pchNext member points to the next byte in the buffer that can be read or written. When you read or write, increment pchNext by the number of bytes read or written.

•	The pchEndRead member points to one byte past the last valid byte in the buffer that can be read.

•	The pchEndWrite member points to one byte past the last location in the buffer that can be written.

Once you read or write to the buffer and modify pchNext, do not call any MMIO function except mmioAdvance until you call the mmioSetInfo function. Call mmioSetInfo when you are finished directly accessing the buffer.

When you reach the end of the buffer specified by pchEndRead or pchEndWrite, call the mmioAdvance function to fill the buffer from the disk, or write the buffer to the disk. The mmioAdvance function will update the pchNext, pchEndRead, and pchEndWrite members in the MMIOINFO structure for the file.

Before calling mmioAdvance or mmioSetInfo to flush a buffer to disk, set the MMIO_DIRTY flag in the dwFlags member of the MMIOINFO structure for the file. Otherwise, the buffer will not be written to disk.

Do not decrement pchNext or modify any members in the MMIOINFO structure other than pchNext and dwFlags. Do not set any flags in dwFlags except MMIO_DIRTY.

See Also

»mmioSetInfo«


  mmioInstallIOProc

LPMMIOPROC mmioInstallIOProc(fccProc, lpmmioproc, fdwInstall)
FOURCC  fccProc;   /* four-character code for procedure */
LPMMIOPROC  lpmmioproc;   /* address of procedure to install  */
DWORD  fdwInstall;   /* install option flags */

The mmioInstallIOProc function installs or removes a custom I/O procedure. It will also locate an installed I/O procedure, given its corresponding four-character code.

Parameters

fccProc

Specifies a four-character code identifying the I/O procedure to install, remove, or locate. All characters in this four-character code should be uppercase characters.

lpmmioproc

Points to the I/O procedure to install. To remove or locate an I/O procedure, set this parameter to NULL. For more information about the I/O procedure, see the description of the »MMIOProc« function.

fdwInstall

Specifies one of the following flags indicating whether the I/O procedure is being installed, removed, or located:

Value	Meaning
MMIO_INSTALLPROC	Installs the specified I/O procedure.
MMIO_GLOBALPROC	This flag is a modifier to the install flag, and indicates the I/O procedure should be installed for global use. This flag is ignored in removal or find operations.
MMIO_REMOVEPROC	Removes the specified I/O procedure.
MMIO_FINDPROC	Searches for the specified I/O procedure.
Return Value

The return value is the address of the I/O procedure installed, removed, or located. If there is an error, the return value is NULL.

See Also

»mmioOpen«, »MMIOProc«


  mmioOpen

HMMIO mmioOpen(lpszFilename, lpmmioinfo, fdwOpen)
LPTSTR  lpszFilename;   /* specifies name of file to open */
LPMMIOINFO  lpmmioinfo;   /* address of structure for file information  */
DWORD  fdwOpen;   /* open option flags */

The mmioOpen function opens a file for unbuffered or buffered input/output (I/O). The file can be a Windows-based file, a memory file, or an element of a custom storage system.

Parameters

lpszFilename

Points to a null-terminated string that specifies the name of the file to open. If no I/O procedure is specified to open the file, then the filename determines how the file is opened, as follows:

•	If the filename does not contain "+", then it is assumed to be the name of a Windows file.

•	If the filename is of the form "foo.ext+bar" the extension EXT is assumed to identify an installed I/O procedure that is called to perform I/O on the file (see the description of the »mmioInstallIOProc« function).

•	If lpszFilename is NULL and no I/O procedure is given, then adwInfo[0] is assumed to be the file handle of a currently open Windows-based file.

When opening a memory file, set lpszFilename to NULL.

lpmmioinfo

Points to an MMIOINFO structure containing extra parameters used by mmioOpen. The MMIOINFO structure has the following form:

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Unless you are opening a memory file, specifying the size of a buffer for buffered I/O, or specifying an uninstalled I/O procedure to open a file, this parameter should be NULL.

If lpmmioinfo is not NULL, all unused members of the MMIOINFO structure it references must be set to zero, including the reserved members.

fdwOpen

Specifies option flags for the open operation. The MMIO_READ, MMIO_WRITE, and MMIO_READWRITE flags are mutually exclusive — only one should be specified.

Value	Meaning
MMIO_READ	Opens the file for reading only. This is the default if MMIO_WRITE and MMIO_READWRITE are not specified.
MMIO_WRITE	Opens the file for writing. Do not read from a file opened in this mode.
MMIO_READWRITE	Opens the file for both reading and writing.
MMIO_CREATE	Creates a new file. If the file already exists, it is truncated to zero length. For memory files, MMIO_CREATE indicates the end of the file is initially at the start of the buffer.
MMIO_DELETE	Deletes a file. If this flag is specified, lpszFilename should not be NULL. The return value will be TRUE (cast to HMMIO) if the file was deleted successfully, FALSE otherwise. Do not call the mmioClose function for a file that has been deleted. If this flag is specified, all other file-opening flags are ignored.
MMIO_PARSE	Creates a fully qualified filename from the path specified in lpszFileName. The fully qualified filename is placed back into lpszFileName. The return value will be TRUE (cast to HMMIO) if the qualification was successful, FALSE otherwise. The file is not opened, and the function does not return a valid MMIO file handle, so do not attempt to close the file. If this flag is specified, all other file opening flags are ignored.
MMIO_EXIST	Determines whether the specified file exists and creates a fully qualified filename from the path specified in lpszFileName. The fully qualified filename is placed back into lpszFileName. The return value will be TRUE (cast to HMMIO) if the qualification was successful and the file exists, FALSE otherwise. The file is not opened, and the function does not return a valid MMIO file handle, so do not attempt to close the file.
MMIO_ALLOCBUF	Opens a file for buffered I/O. To allocate a buffer larger or smaller than the default buffer size (8K), set the cchBuffer member of the MMIOINFO structure to the desired buffer size. If cchBuffer is zero, then the default buffer size is used. If you are providing your own I/O buffer, the MMIO_ALLOCBUF flag should not be used.
MMIO_COMPAT	Opens the file with compatibility mode, allowing any process on a given machine to open the file any number of times. mmioOpen fails if the file has been opened with any of the other sharing modes.
MMIO_EXCLUSIVE	Opens the file with exclusive mode, denying other processes both read and write access to the file. mmioOpen fails if the file has been opened in any other mode for read or write access, even by the current process.
MMIO_DENYWRITE	Opens the file and denies other processes write access to the file. mmioOpen fails if the file has been opened in compatibility or for write access by any other process.
MMIO_DENYREAD	Opens the file and denies other processes read access to the file. mmioOpen fails if the file has been opened in compatibility mode or for read access by any other process.
MMIO_DENYNONE	Opens the file without denying other processes read or write access to the file. mmioOpen fails if the file has been opened in compatibility mode by any other process.
MMIO_GETTEMP	Creates a temporary filename and places the name in the buffer pointed to by lpszFileName. The filename is hard-coded into the mmioOpen function. The return value is TRUE (cast to HMMIO) if the temporary filename is created successfully; otherwise, it is FALSE. The file is not opened, and the function does not return a valid MMIO file handle, so do not attempt to close the file. This flag overrides all other flags.
Return Value

The return value is a handle of the opened file. This handle is an MMIO file handle — do not use it with any file I/O functions other than MMIO functions.

If the file cannot be opened, the return value is NULL. If lpmmioinfo is not NULL, then its wErrorRet member will contain extended error information returned by the I/O procedure.

Comments

You must call the mmioClose function to close a file opened with mmioOpen. Open files are not automatically closed when an application exits.

If lpmmioinfo references an MMIOINFO structure, set up the members as described below. All unused members must be set to zero, including reserved members.

To request that a file be opened with an installed I/O procedure, set the fccIOProc member to the four-character code of the I/O procedure,and set the pIOProc member to NULL.

To request that a file be opened with an uninstalled I/O procedure, set the pIOProc member to point to the I/O procedure, and set fccIOProc to NULL.

To request that mmioOpen determine which I/O procedure to use to open the file based on the filename contained in lpszFilename, set both fccIOProc and pIOProc to NULL. This is the default behavior if no MMIOINFO structure is specified.

To open a memory file using an internally allocated and managed buffer, set the pchBuffer member to NULL, fccIOProc to FOURCC_MEM, cchBuffer to the initial size of the buffer, and adwInfo[0] to the incremental expansion size of the buffer. This memory file will automatically be expanded in increments of adwInfo[0] bytes when necessary. Specify the MMIO_CREATE flag for the fdwOpen parameter to initially set the end of the file to be the beginning of the buffer.

To open a memory file using a caller-supplied buffer, set the pchBuffer member to point to the memory buffer, fccIOProc to FOURCC_MEM, cchBuffer to the size of the buffer, and adwInfo[0] to the incremental expansion size of the buffer. The expansion size in adwInfo[0] should only be nonzero if pchBuffer is a pointer obtained by calling the GlobalAlloc and GlobalLock functions, since the GlobalReAlloc function will be called to expand the buffer. In particular, if pchBuffer points to a local or global array, a block of memory in the local heap, or a block of memory allocated by the GlobalDosAlloc function, adwInfo[0] must be zero. Specify the MMIO_CREATE flag for the fdwOpen parameter to initially set the end of the file to be the beginning of the buffer; otherwise, the entire block of memory will be considered readable.

To use a currently open Windows-based file handle with MMIO, set the fccIOProc member to FOURCC_DOS, pchBuffer to NULL, and adwInfo[0] to the Windows file handle. Note that offsets within the file will be relative to the beginning of the file, and will not depend on the Wfile position at the time mmioOpen is called; the initial MMIO offset will be the same as the Windows-based offset when mmioOpen is called. Later, to close the MMIO file handle without closing the Windows-based file handle, pass the MMIO_FHOPEN flag to the mmioClose function.

See Also

»mmioClose«


  MMIOProc

LPRESULT CALLBACK MMIOProc(lpmmioinfo, uMsg, lParam1, lParam2)
LPSTR  lpmmioinfo;   /* address of structure with file information */
UINT  uMsg;   /* specifies sent message */
LONG  lParam1;   /* application-defined parameter */
LONG  lParam2;   /* application-defined parameter */

The MMIOProc function is a custom input/output (I/O) procedure installed by the mmioInstallIOProc function.

Parameters

lpmmioinfo

Points to an MMIOINFO structure containing information about the open file. The MMIOINFO structure has the following form:

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5. The I/O procedure must maintain the lDiskOffset member in this structure to indicate the file offset to the next read or write location. The I/O procedure can use the adwInfo[] member to store state information. The I/O procedure should not modify any other members of the MMIOINFO structure.

uMsg

Specifies a message indicating the requested I/O operation. Messages that can be received include MMIOM_OPEN, MMIOM_CLOSE, MMIOM_READ, MMIOM_RENAME, MMIOM_SEEK, MMIOM_WRITE, AND MMIOM_WRITEFLUSH.

lParam1

Specifies an application-defined parameter for the message.

lParam2

Specifies an application-defined parameter for the message.

Return Value

The return value depends on the message specified by uMsg. If the I/O procedure does not recognize a message, it should return zero.

Comments

MMIOProc is a placeholder for the application-defined function name.

The four-character code specified by the fccMMIOProc member in the MMIOINFO structure associated with a file identifies a filename extension for a custom storage system. When an application calls mmioOpen with a filename such as "one.xyz+two", the I/O procedure associated with the four-character code "XYZ " is called to open the "two" element of the file "one.xyz".

The mmioInstallIOProc function maintains a separate list of installed I/O procedures for each Windows-based application. Therefore,different applications can use the same I/O procedure identifier for different I/O procedures without conflict. However, installing an I/O procedure globally however enables any process to use the procedure.

If an application calls mmioInstallIOProc more than once to register the same I/O procedure, then it must call mmioInstallIOProc to remove the procedure once for each time it installed the procedure.

mmioInstallIOProc will not prevent an application from installing two different I/O procedures with the same identifier, or installing an I/O procedure with one of the predefined identifiers ("DOS ", "MEM "). The most recently installed procedure takes precedence, and the most recently installed procedure is the first one to be removed.

When searching for a specified I/O procedure, local procedures are searched first, then global procedures.

See Also

»mmioInstallIOProc«


  mmioRead

LRESULT mmioRead(hmmio, pb, cbRead)
HMMIO  hmmio;   /* handle of file to read from */
LPSTR  pb;   /* address of buffer for read bytes  */
LONG  cbRead;   /* number of bytes to read */

The mmioRead function reads a specified number of bytes from a file opened by using the mmioOpen function.

Parameters

hmmio

Identifies the file to be read.

pb

Points to the buffer that receives the data read from the file.

cbRead

Specifies the number of bytes to read from the file.

Return Value

The return value is the number of bytes actually read. If the end of the file has been reached and no more bytes can be read, the return value is zero. If there is an error reading from the file, the return value is −1.

See Also

»mmioWrite«


  mmioRename

MMRESULT mmioRename(lpszOldName, lpszNewName, lpmmioinfo, dwReserved)
LPCTSTR  lpszOldName;   /* address of old filename */
LPCTSTR  lpszNewName;   /* address of new filename */
LPMMIOINFO  lpmmioinfo;   /* address of structure with additional info  */
DWORD  dwReserved;   /* reserved; must be zero */

The mmioRename function renames the specified file.

Parameters

lpszOldName

Points to a null-terminated string that specifies the name of the file to rename.

lpszNewName

Points to a null-terminated string that specifies the new name for the file.

lpmmioinfo

Points to an MMIOINFO structure containing extra parameters used by mmioRename. The MMIOINFO structure has the following form:

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpmmioinfo is not NULL, all unused members of the MMIOINFO structure it references must be set to zero, including the reserved members.

dwReserved

Reserved. Must be zero.

Return Value

The return value is zero if the file was renamed. Otherwise, the return value is an error code returned by the mmioRename function or from the I/O procedure.


  mmioSeek

LRESULT mmioSeek(hmmio, lOffset, nOrigin)
HMMIO  hmmio;   /* handle of file to seek in */
LONG  lOffset;   /* specifies change in file position */
int  nOrigin;   /* specifies how to change file position */

The mmioSeek function changes the current file position in a file opened by using the mmioOpen function. The current file position is the location in the file where data is read or written.

Parameters

hmmio

Identifies the file to seek in.

lOffset

Specifies an offset to change the file position.

nOrigin

Specifies how the offset specified by lOffset is interpreted. Contains one of the following flags:

Value	Meaning
SEEK_SET	Seeks to lOffset bytes from the beginning of the file.
SEEK_CUR	Seeks to lOffset bytes from the current file position.
SEEK_END	Seeks to lOffset bytes from the end of the file.
Return Value

The return value is the new file position in bytes, relative to the beginning of the file. If there is an error, the return value is −1.

Comments

Seeking to an invalid location in the file, such as past the end of the file, may not cause mmioSeek to return an error but may cause subsequent I/O operations on the file to fail.

To seek to the beginning a file, call mmioSeek with lOffset set to zero and nOrigin set to SEEK_SET.

To locate the end of a file, call mmioSeek with lOffset set to zero and nOrigin set to SEEK_END.


  mmioSendMessage

LRESULT mmioSendMessage(hmmio, uMsg, lParam1, lParam2)
HMMIO  hmmio;   /* handle of file associated with I/O procedure */
UINT  uMsg;   /* message to send */
LONG  lParam1;   /* application-defined parameter */
LONG  lParam2;   /* application-defined parameter */

The mmioSendMessage function sends a message to the input/output (I/O) procedure associated with the specified file.

Parameters

hmmio

Identifies a file opened by using the mmioOpen function.

uMsg

Specifies the message to send to the I/O procedure.

lParam1

Specifies an application-defined parameter for the message.

lParam2

Specifies an application-defined parameter for the message.

Return Value

The return value depends on the message. If the I/O procedure does not recognize the message, the return value is zero.

Comments

Use this function to send custom user-defined messages. Do not use it to send the following messages:

MMIOM_OPEN
MMIOM_CLOSE
MMIOM_READ
MMIOM_RENAME
MMIOM_SEEK
MMIOM_WRITE
MMIOM_WRITEFLUSH

Define custom messages to be greater than or equal to the MMIOM_USER constant.

See Also

»mmioInstallIOProc«


  mmioSetBuffer

MMRESULT mmioSetBuffer(hmmio, pbBuffer, cbBuffer, uReserved)
HMMIO  hmmio;   /* handle of file to set buffer for */
LPSTR  pbBuffer;   /* address of buffer */
LONG  cbBuffer;   /* size of buffer */
UINT  uReserved;   /* reserved; must be zero */

The mmioSetBuffer function enables or disables buffered input/output (I/O), or changes the buffer or buffer size for a file opened by using the mmioOpen function.

Parameters

hmmio

Identifies the file.

pbBuffer

Points to a buffer. If this parameter is NULL, mmioSetBuffer allocates an internal buffer.

cbBuffer

Specifies the size of the buffer, or the size of the buffer to allocate if pbBuffer is NULL.

uReserved

Reserved. Must be zero.

Return Value

If the function is succeeds, the return value is zero; otherwise, it is an error code than can be one of the following:

Value	Meaning
MMIOERR_CANNOTWRITE	The contents of the old buffer could not be written to disk, so the operation was not completed.
MMIOERR_OUTOFMEMORY	The new buffer could not be allocated, probably due to a lack of available memory.
If an error occurs, the file handle remains valid.

Comments

To enable buffering using an internal buffer, set pbBuffer to NULL and cbBuffer to the desired buffer size.

To supply your own buffer, set pbBuffer to point to the buffer,and set cbBuffer to the size of the buffer.

To disable buffered I/O, set pbBuffer to NULL and cbBuffer to zero.

If buffered I/O is already enabled using an internal buffer, you can reallocate the buffer to a different size by setting pbBuffer to NULL and cbBuffer to the new buffer size. The contents of the buffer may be changed after resizing.


  mmioSetInfo

MMRESULT mmioSetInfo(hmmio, lpmmioinfo, uReserved)
HMMIO  hmmio;   /* handle of the file to set */
LPMMIOINFO  lpmmioinfo;   /* address of file-information structure  */
UINT  uReserved;   /* reserved; must be zero */

The mmioSetInfo function updates the information retrieved by mmioGetInfo about a file opened with mmioOpen. Use this function to terminate direct buffer access of a file opened for buffered input/output (I/O).

Parameters

hmmio

Identifies the file.

lpmmioinfo

Points to an MMIOINFO structure filled with information with mmioGetInfo. The MMIOINFO structure has the following form:

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

uReserved

Reserved. Must be zero.

Return Value

The return value is zero if the function is successful.

Comments

If you have written to the file I/O buffer, set the MMIO_DIRTY flag in the dwFlags member of the MMIOINFO structure before calling mmioSetInfo to terminate direct buffer access. Otherwise, the buffer will not be flushed to disk.

See Also

»mmioGetInfo«


  mmioStringToFOURCC

FOURCC mmioStringToFOURCC(lpsz, fuOptions)
LPCTSTR  lpsz;   /* address of string to convert  */
UINT  fuOptions;   /* options flags */

The mmioStringToFOURCC function converts a null-terminated string to a four-character code.

Parameters

lpsz

Points to a null-terminated string to convert to a four-character code.

fuOptions

Specifies options for the conversion.

Value	Meaning
MMIO_TOUPPER	Convert all characters to uppercase.
Return Value

The return value is the four character code created from the given string.

Comments

This function does not check to see if the string referenced by lpsz follows any conventions regarding which characters to include in a four-character code. The string is simply copied to a four-character code and padded with blanks or truncated to four characters if required.

See Also

»mmioFOURCC«


  mmioWrite

LRESULT mmioWrite(hmmio, pb, cbWrite)
HMMIO  hmmio;   /* identifies file to write to */
LPSTR  pb;   /* address of data to write */
LONG  cbWrite;   /* number of bytes to write */

The mmioWrite function writes a specified number of bytes to a file opened by using the mmioOpen function.

Parameters

hmmio

Identifies the file.

pb

Points to the data to be written to the file.

cbWrite

Specifies the number of bytes to write to the file.

Return Value

The return value is the number of bytes actually written. If there is an error writing to the file, the return value is −1.

Comments

The current file position is incremented by the number of bytes written.

See Also

»mmioRead«


  mmsystemGetVersion

UINT mmsystemGetVersion(VOID)

The mmsystemGetVersion function returns the current version number of the Multimedia extensions system software.

Parameters

This function has no parameters.

Return Value

The low-order word of the return value specifies the major and minor version numbers of the Multimedia extensions. The high-order byte specifies the major version number. The low-order byte specifies the minor version number.


  ModifyMenu

BOOL ModifyMenu(hmenu, uItem, fuFlags, idNewItem, lpszNewItem)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item to modify */
UINT  fuFlags;   /* menu item flags */
UINT  idNewItem;   /* menu item identifier or pop-up menu handle  */
LPCTSTR  lpszNewItem;   /* menu item content */

The ModifyMenu function changes an existing menu item. This function is used to specify the content, appearance, and behavior of the menu item.

Parameters

hmenu

Identifies the menu to be changed.

uItem

Specifies the menu item to be changed, as determined by the fuFlags parameter.

fuFlags

Specifies flags that control the interpretation of the uItem parameter and the content, appearance, and behavior of the menu item. This parameter must be a combination of one of the following required values and at least one of the values listed in the Comments section.

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the menu item.
idNewItem

Specifies either the identifier of the modified menu item or, if fuFlags is set to the MF_POPUP flag, the handle of the pop-up menu.

lpszNewItem

Points to the content of the changed menu item. The interpretation of this parameter depends on whether the fuFlags parameter includes the MF_BITMAP, MF_OWNERDRAW, or MF_STRING flag.

Value	Meaning
MF_BITMAP	Contains a bitmap handle.
MF_OWNERDRAW	Contains a 32-bit value supplied by an application that is used to maintain additional data related to the menu item. The value is in the itemData member of the structure pointed to by the lparam parameter of the WM_MEASURE or WM_DRAWITEM messages sent when the menu item is created or its appearance is updated.
MF_STRING	Contains a pointer to a null-terminated string (the default).
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If ModifyMenu replaces a menu item that activates a pop-up menu, the function destroys the old pop-up menu and frees the memory used by it.

The application must call the DrawMenuBar function whenever a menu changes, whether or not the menu is in a displayed window. To change the attributes of existing menu items, it is much faster to use the CheckMenuItem and EnableMenuItem functions.

The following list describes the flags that may be set in the fuFlags parameter:

Value	Meaning
MF_BITMAP	Uses a bitmap as the menu item. The lpszNewItem parameter contains the handle of the bitmap.
MF_BYCOMMAND	Indicates that the uItem parameter specifies the identifier of the menu item (the default).
MF_BYPOSITION	Indicates that the uItem parameter specifies the zero-based relative position of the new menu item.
MF_CHECKED	Places a check mark next to the item. If your application provides check mark bitmaps (see the »SetMenuItemBitmaps« function), this flag displays a checked bitmap next to the menu item.
MF_DISABLED	Disables the menu item so that it cannot be selected, but this flag does not gray it.
MF_ENABLED	Enables the menu item so that it can be selected and restores it from its grayed state.
MF_GRAYED	Disables the menu item and grays it so that it cannot be selected.
MF_MENUBARBREAK	Functions the same as the MF_MENUBREAK flag, except for pop-up menus where the new column is separated from the old column by a vertical line.
MF_MENUBREAK	Places the item on a new line (for menu bars) or in a new column (for pop-up menus) without separating columns.
MF_OWNERDRAW	Specifies that the item is an owner-drawn item. Before the menu is displayed for the first time, the window that owns the menu receives a WM_MEASUREITEM message to retrieve the width and height of the menu item. The WM_DRAWITEM message is then sent to the window procedure of the owner window whenever the appearance of the menu item must be updated.
MF_POPUP	Specifies that the menu item is a pop-up item; that is, selecting it activates a pop-up menu. The idNewItem parameter specifies the handle of the pop-up menu. This flag is used to add a pop-up item to a menu bar or to a pop-up menu.
MF_SEPARATOR	Draws a horizontal dividing line. This flag is used only in a pop-up menu. The dividing line cannot be grayed, disabled, or highlighted. The lpszNewItem and idNewItem parameters are ignored.
MF_STRING	Specifies that the menu item is a text string; the lpszNewItem parameter points to the string.
MF_UNCHECKED	Does not place a check mark next to the item (the default). If your application supplies check mark bitmaps (see the »SetMenuItemBitmaps« function), this flag displays an unchecked bitmap next to the menu item.
The following list shows groups of flags that cannot be used together:

•	MF_BYCOMMAND and MF_BYPOSITION

•	MF_DISABLED, MF_ENABLED, and MF_GRAYED

•	MF_BITMAP, MF_STRING, MF_OWNERDRAW, and MF_SEPARATOR

•	MF_MENUBARBREAK and MF_MENUBREAK

•	MF_CHECKED and MF_UNCHECKED

See Also

»AppendMenu«, »CheckMenuItem«, »DrawMenuBar«, »EnableMenuItem«, »SetMenuItemBitmaps«


  ModifyWorldTransform

BOOL ModifyWorldTransform(hdc, lpXform, iMode)
HDC  hdc;   /* handle of device context */
LPXFORM  lpXform;   /* address of transformation data  */
DWORD  iMode;   /* modification mode */

The ModifyWorldTransform function changes the world transformation for the given device context (DC) using the specified mode.

Parameters

hdc

Specifies the DC.

lpXform

Points to an XFORM structure used to modify the world transformation for the given device context. The XFORM structure has the following form:

typedef struct  tagXFORM {  /* xfrm */

    FLOAT eM11;

    FLOAT eM12;

    FLOAT eM21;

    FLOAT eM22;

    FLOAT eDx;

    FLOAT eDy;

} XFORM;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

iMode

Specifies how the transformation data modifies the current world transformation. This parameter must be one of the following values:

Value	Description
MWT_IDENTITY	Resets the current world transformation by using the identity matrix. If this mode is specified, the XFORM structure pointed to by lpXform is ignored.
MWT_LEFTMULTIPLY	Multiplies the current transformation by the data in the XFORM structure. (The data in the XFORM structure becomes the left multiplicand, and the data for the current transformation becomes the right multiplicand.)
MWT_RIGHTMULTIPLY	Multiplies the current transformation by the data in the XFORM structure. (The data in the XFORM structure becomes the right multiplicand, and the data for the current transformation becomes the left multiplicand.)
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The ModifyWorldTransform function will fail unless graphics mode for the given device context (DC) has been set to GM_ADVANCED by previosly calling the SetGraphicsMode function. Likewise, it will not be possible to reset the graphics mode for the DC to the default GM_COMPATIBLE mode, unless world transform has first been reset to the default identity transform by calling SetWorldTransform or ModifyWorldTransform.

See Also

»GetWorldTransform«, »SetWorldTransform«, »SetGraphicsMode«


  mouse_event

VOID mouse_event(dwFlags, dx, dy, cButtons, dwExtraInfo)
DWORD  dwFlags;   /* flags specifying various motion/click variants */
DWORD  dx;   /* horizontal mouse position or position change */
DWORD  dy;   /* vertical mouse position or position change */
DWORD  cButtons;   /* unused; reserved for future use; set to zero  */
DWORD  dwExtraInfo;   /* 32 bits of caller-defined information */

The mouse_event function synthesizes mouse motion and button clicks.

Parameters

dwFlags

A set of flag bits that specify various aspects of mouse motion and button clicking. The bits in this parameter can be any reasonable combination of the following values:

Value	Meaning
MOUSEEVENTF_MOVE	Specifies that movement occurred.
MOUSEEVENTF_LEFTDOWN	Specifies that the left button changed to down.
MOUSEEVENTF_LEFTUP	Specifies that the left button changed to up.
MOUSEEVENTF_RIGHTDOWN	Specifies that the right button changed to down.
MOUSEEVENTF_RIGHTUP	Specifies that the right button changed to up.
MOUSEEVENTF_MIDDLEDOWN	Specifies that the middle button changed to down.
MOUSEEVENTF_MIDDLEUP	Specifies that the middle button changed to up.
MOUSEEVENTF_ABSOLUTE	Specifies that the dx and dy parameters contain normalized absolute coordinates. If not set, those parameters contain relative data: the change in position since the last reported position. This flag can be set, or not set, irregardless of what kind of mouse or mouse-like device, if any, is connected to the system.
The flag bits that specify mouse button status are set to indicate changes in status, not ongoing conditions. For example, if the left mouse button is pressed and held down, MOUSEEVENTF_LEFTDOWN is set when the left button is first pressed, but not for subsequent motions. Similarly, MOUSEEVENTF_LEFTUP is set only when the button is first released.

dx

Specifies the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is given as the mouse's actual x-coordinate; relative data is given as the number of mickeys moved.

dy

Specifies the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated, depending on the setting of MOUSEEVENTF_ABSOLUTE. Absolute data is given as the mouse's actual y-coordinate; relative data is given as the number of mickeys moved.

cButtons

This parameter is currently unused. It is reserved for future use. It must be set to zero.

dwExtraInfo

Specifies an additional 32-bit value associated with the mouse event. An application calls GetMessageExtraInfo to obtain this extra information.

Return Value

This function has no return value.

Comments

If the mouse has moved, indicated by MOUSEEVENTF_MOVE being set, dx and dy hold information about that motion. The information is given as absolute or relative integer values.

If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper left corner of the display surface, (65535,65535) maps onto the lower right corner.

If the MOUSEEVENTF_ABSOLUTE value is not specified, dx and dy specify relative motions from when the last mouse event was generated (the last reported position). Positive values mean the mouse moved right/down; negative values mean the mouse moved left/up.

The mouse_event function is used to synthesize mouse events by applications that need to do so. It is also used by applications that need to obtain more information from the mouse than its position and button state. For example, if a tablet maker wants to pass pen-windows sorts of extra information to its own applications, it can write a DLL that communicates directly to the tablet hardware, obtains the extra information, and saves it in a queue. The DLL then calls mouse_event with the standard button and x/y position data, along with, in the dwExtraInfo field, some pointer or index to the queued extra information. When the application needs the extra information, it calls the DLL with the pointer/index stored in dwExtraInfo, and the DLL returns the extra information.


  MouseProc

LRESULT CALLBACK MouseProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* message identifier  */
LPARAM  lParam;   /* mouse coordinates */

The MouseProc hook procedure is an application-defined or library-defined callback function the system calls whenever an application calls the GetMessage or PeekMessage function and there is a mouse message to be processed.

Parameters

nCode

Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:

Value	Meaning
HC_ACTION	The wParam and lParam parameters contain information about a mouse message.
HC_NOREMOVE	The wParam and lParam parameters contain information about a mouse message, and the mouse message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies the identifier of the mouse message.

lParam

Points to a MOUSEHOOKSTRUCT structure. The MOUSEHOOKSTRUCT structure has the following form:

typedef struct tagMOUSEHOOKSTRUCT { /* ms */

    POINT pt;

    HWND  hwnd;

    UINT  wHitTestCode;

    DWORD dwExtraInfo;

} MOUSEHOOKSTRUCT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

To enable the system to process the message, the return value must be zero. To discard the message, the return value must be a nonzero value.

Comments

The hook procedure must not install a JournalPlaybackProc callback function.

An application installs the hook procedure by specifying the WH_MOUSE hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

MouseProc is a placeholder for the application-defined or library-defined function name.

See Also

»CallNextHookEx«, »GetMessage«, »PeekMessage«, »SetWindowsHookEx«


  MoveFile

BOOL MoveFile(lpszExisting, lpszNew)
LPTSTR  lpszExisting;   /* address of name of the existing file  */
LPTSTR  lpszNew;   /* address of new name for the file */

The MoveFile function renames an existing file or a directory (including all its children).

Parameters

lpszExisting

Points to a null-terminated string that names an existing file or directory.

lpszNew

Points to a null-terminated string that specifies the new name of a file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE. To get extended error information, use the GetLastError function.

Comments

The MoveFile function will move (rename) either a file or a directory (including all its children) either in the same directory or across directories. The one caveat with this is that the MoveFile function will fail on directory moves when the destination is on a different volume.

See Also

»CopyFile«, »MoveFileEx«


  MoveFileEx

BOOL MoveFileEx(lpszExisting, lpszNew, fdwFlags)
LPTSTR  lpszExisting;   /* address of name of the existing file */
LPTSTR  lpszNew;   /* address of new name for the file */
DWORD  fdwFlags;   /* flag to determine how to move file */

The MoveFileEx function renames an existing file.

Parameters

lpszExisting

Points to a null-terminated string that names an existing file.

lpszNew

Points to a null-terminated string that specifies the new name of a file. The new file can be on a different file system or drive. If this parameter is NULL, the file specified by lpszExisting is deleted.

fdwFlags

Specifies how to move the file. This parameter must be one of the following values:

Value	Meaning
MOVEFILE_REPLACE_EXISTING
	If a file of the name specified by lpszNew already exists, the function replaces its contents with those specified by lpszExisting.
MOVEFILE_COPY_ALLOWED
	If the file is to be moved to a different volume, the function simulates the move by using the CopyFile and DeleteFile functions.
MOVEFILE_DELAY_UNTIL_REBOOT
	The function does not move the file until the operating system is restarted. The system moves the file immediately after AUTOCHK is executed, but before creating any paging files. Therefore, this parameter enables the function to delete paging files from previous startups.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CopyFile«, »DeleteFile«, »MoveFile«


  MoveMemory

VOID MoveMemory (Destination, Source, Length)
PVOID  Destination;   /* address of move destination */
CONST VOID *  Source;   /* address of block to move */
DWORD  Length;   /* size in bytes of block to move */

The MoveMemory function moves a block of memory from one location to another.

Parameters

Destination

Points to the starting address of the destination of the move.

Source

Points to the starting address of the block of memory to move.

Length

Specifies the size in bytes of the block of memory to move.

Return Value

This function has no return value.

Comments

The source and destination blocks may overlap.

See Also

»CopyMemory«, »FillMemory«, »ZeroMemory«


  MoveTo

The MoveTo function has been deleted. Win32 applications should use the MoveToEx function.

See Also

»MoveToEx«


  MoveToEx

BOOL MoveToEx(hdc, X, Y, lpPoint)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of new current position */
int  Y;   /* y-coordinate of new current position */
LPPOINT  lpPoint;   /* address of old current position */

The MoveToEx function updates the current position to the specified point and optionally returns the previous position.

Parameters

hdc

Identifies a device context.

X

Specifies the x-coordinate of the new position, in logical units.

Y

Specifies the y-coordinate of the new position, in logical units.

lpPoint

Points to a POINT structure in which the previous current position is stored. If this parameter is a NULL pointer, the previous position is not returned. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The MoveToEx function affects all drawing functions.

See Also

»AngleArc«, »LineTo«, »PolyBezierTo«, »PolylineTo«


  MoveWindow

BOOL MoveWindow(hwnd, x, y, cx, cy, bRepaint)
HWND  hwnd;   /* handle of window */
int  x;   /* horizontal position */
int  y;   /* vertical position */
int  cx;   /* width */
int  cy;   /* height */
BOOL  bRepaint;   /* repaint flag */

The MoveWindow function changes the position and dimensions of the given window. For a top-level window, the position and dimensions are relative to the upper-left corner of the screen. For a child window, they are relative to the upper-left corner of the parent window's client area.

Parameters

hwnd

Identifies the window.

x

Specifies the new position of the left side of the window.

y

Specifies the new position of the top of the window.

cx

Specifies the new width of the window.

cy

Specifies the new height of the window.

bRepaint

Specifies whether the window is to be repainted. If this parameter is TRUE, the window receives a WM_PAINT message. If the parameter is FALSE, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of moving a child window. If this parameter is FALSE, the application must explicitly invalidate or redraw any parts of the window and parent window that need to be redrawn.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

If the bPaint parameter is TRUE, Windows sends the WM_PAINT message to the window procedure immediately after moving the window (that is, the MoveWindow function calls the UpdateWindow function). If bPaint is FALSE, Windows places the WM_PAINT message in the message queue associated with the window. The message loop dispatches the WM_PAINT message only after dispatching all other messages in the queue.

The MoveWindow function sends a WM_GETMINMAXINFO message to the window being moved, enabling it to modify the default values for the largest and smallest possible windows. If the parameter of MoveWindow exceed these values, they will be replaced by the minimum or maximum values specified in the WM_GETMINMAXINFO message.

The MoveWindow function sends WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, WM_SIZE, and WM_NCCALCSIZE messages to the window.

See Also

»SetWindowPos«


  MsgWaitForMultipleObjects

DWORD MsgWaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout,
fdwWakeMask )
DWORD  cObjects;   /* number of handles in handle array */
LPHANDLE  lphObjects;   /* address of object-handle array */
BOOL  fWaitAll;   /* wait for all or wait for one */
DWORD  dwTimeout;   /* time-out interval in milliseconds */
DWORD  fdwWakeMask;   /* type of input events to wait for */

The MsgWaitForMultipleObjects function returns when one of the following occurs:

•	Either any one or all of the specified objects are in the signaled state.

•	A specified type of input becomes available in the thread's input queue.

•	The time-out interval elapses.

Note that MsgWaitForMultipleObjects doesn't return if there was previously-unread input of the specified type in the queue. It only wakes up when input arrives.

Parameters

cObjects

Specifies the number of object handles in the array pointed to by lphObjects. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.

lphObjects

Points to an array of object handles. For a list of the object types whose handles can be specified, see the Comments section. The array can contain handles of objects of different types. The handles must have SYNCHRONIZE access.

fWaitAll

Specifies the wait type. If TRUE, the function returns when all objects in the lphObjects array are signaled at the same time. If FALSE, the function returns when any one of the objects is signaled. In the latter case, the return value indicates the object whose state caused the function to return.

dwTimeout

Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the conditions specified by the fWaitAll or fdwWakeMask parameter are not satisfied. If dwTimeout is zero, the function tests the states of the specified objects and returns immediately. If dwTimeout is INFINITE, the function's time-out interval never elapses.

fdwWakeMask

Specifies the types of input that will cause the function to return. This parameter can be any combination of the following values:

Value	Meaning
QS_ALLINPUT	Any message is in the queue.
QS_HOTKEY	A WM_HOTKEY message is in the queue.
QS_INPUT	An input message is in the queue.
QS_KEY	A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.
QS_MOUSE	A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEBUTTON	A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEMOVE	A WM_MOUSEMOVE message is in the queue.
QS_PAINT	A WM_PAINT message is in the queue.
QS_POSTMESSAGE	A posted message (other than those just listed) is in the queue.
QS_SENDMESSAGE	A message sent by another thread or application is in the queue.
QS_TIMER	A WM_TIMER message is in the queue.
Return Value

If the function succeeds, the return value indicates the event that caused the function to return; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

The successful return value is one of the following:

Value	Meaning
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + cObjects − 1)
	If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If fWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lphObjects array index of the object that satisfied the wait.
WAIT_OBJECT_0 + cObjects
	Input of the type specified in the fdwWakeMask parameter is available in the thread's input queue.
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + cObjects − 1)
	If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object. If fWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lphObjects array index of an abandoned mutex object that satisfied the wait.
WAIT_TIMEOUT
	The time-out interval elapsed and the conditions specified by the fWaitAll and fdwWakeMask parameters were not satisfied.
Comments

The MsgWaitForMultipleObjects function determines whether the conditions exist that satisfy the wait. If the wait is not satisfied, the calling thread enters an efficient wait state, consuming very little processor time while waiting for one of the conditions of the wait to be satisfied.

When fWaitAll is TRUE, the function's wait condition is satisfied only when the state of all objects is signaled at the same time. The function does not modify the state of the specified objects until all objects are simultaneously signaled. For example, a mutex can be signaled, but the thread does not get ownership until the other objects are also signaled. In the meantime, some other thread may get ownership of the mutex, thereby delaying satisfaction of the condition.

The system adjusts the state of some types of objects after the object's signaled state satisfies a wait condition. For example, the count of a semaphore object is decreased by one.

The MsgWaitForMultipleObjects function can specify handles of any of the following object types in the lphObjects array:

Object	Description
change notification	The handle is returned by the FindFirstChangeNotification function. A change notification object's state is signaled when a specified type of change occurs within a specified directory or directory tree.
console input	The handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. The object's state is signaled when there is unread input in the console's input buffer, and it is nonsignaled when the input buffer is empty.
event	The handle is returned by the CreateEvent or OpenEvent function. An event object's state is set explicitly to signaled by the SetEvent or PulseEvent function. A manual-reset event object's state must be reset explicitly to nonsignaled by the ResetEvent function. For an auto-reset event object, the wait function resets the object's state to nonsignaled before returning. Event objects are also used in overlapped operations, in which the state is set by the system.
mutex	The handle is returned by the CreateMutex or OpenMutex function. A mutex object's state is signaled when it is not owned by any thread. The wait function requests ownership of the mutex for the calling thread, changing the mutex's state to nonsignaled when ownership is granted.
process	The handle is returned by the CreateProcess or OpenProcess function. A process object's state is signaled when the process terminates.
thread	The handle is returned by the CreateProcess, CreateThread, or CreateRemoteThread function. A thread object's state is signaled when the thread terminates.
semaphore	The handle is returned by the CreateSemaphore or OpenSemaphore function. A semaphore object maintains a count between zero and some maximum value. Its state is signaled when its count is greater than zero and nonsignaled when its count is zero. If the current state is signaled, the wait function decreases the count by one.
In some circumstances, you can specify a handle of a file, named pipe, or communications device as a synchronization object in a wait function. However, their use for this purpose is discouraged. For more information, see Chapter 44, "Synchronization."

The following code fragment illustrates the use of MsgWaitForMultipleObjects in a main message loop that also needs to wait for one or more objects to become signalled :

int MessageLoop (

  HANDLE* lphObjects,  // handles that need to be waited on

  int     cObjects     // number of handles to wait on

  ){

  // message loop lasts until we get a WM_QUIT message

  // upon which we shall return from the function

  while (TRUE) {

    // block-local variable

    DWORD result ;

    // wait for any message sent or posted to this queue

    // or for one of the passed handles to become signalled

      result = MsgWaitForMultipleObjects(cObjects, lphObjects,

                                 FALSE, INFINITE, QS_ALLINPUT);

      // result tells us the type of event we have:

      // a message or a signalled handle

      // if there are one or more messages in the queue ...

      if (result == (WAIT_OBJECT_0 + 1)) {

         // block-local variable

         MSG msg ;

         // read all of the messages in this next loop

         // removing each message as we read it

         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {

            /* if it's a quit message we're out of here

            if (msg.message == WM_QUIT)  return 1;

            /* otherwise dispatch it */

            DispatchMessage(&msg);

         } // end of PeekMessage while loop

      } else {

         // one of the handles became signalled

         // deal with that

         DoStuff (result - WAIT_OBJECT_0) ;

      } // end of else-clause

   } // end of the always while-loop

} // end of function

See Also

»Sleep«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«


  MulDiv

int MulDiv(nMultiplicand, nMultiplier, nDivisor)
int  nMultiplicand;   /* 32-bit signed multiplicand */
int  nMultiplier;   /* 32-bit signed multiplier  */
int  nDivisor;   /* 32-bit signed divisor */

The MulDiv function multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value. The return value is rounded up or down to the nearest integer.

Parameters

nMultiplicand

Specifies the multiplicand.

nMultiplier

Specifies the multiplier.

nDivisor

Specifies the number by which the result of the multiplication (nMultiplicand * nMultiplier) is to be divided.

Return Value

If the function succeeds, the return value is the result of the multiplication and division. If either an overflow occurred or nDivisor was 0, the return value is −1.


  MultiByteToWideChar

int MultiByteToWideChar(uCodePage, dwFlags, lpMultiByteStr, cchMultiByte,
lpWideCharStr, cchWideChar)
UINT  uCodePage;   /* code page */
DWORD  dwFlags;   /* character-type options */
LPCSTR  lpMultiByteStr;   /* address of string to map */
int  cchMultiByte;   /* number of characters in string */
LPWSTR  lpWideCharStr;   /* address of wide-character buffer  */
int  cchWideChar;   /* size of buffer */

The MultiByteToWideChar function maps a character string to a wide-character string. The character string mapped by this function is not necessarily from a multibyte character set.

Parameters

uCodePage

Specifies the code page to be used to perform the conversion. This parameter can be given the value of any codepage that is installed or available in the system. The following two values have special meanings:

Value	Meaning
CP_ACP	ANSI code page
CP_OEMCP	OEM code page
dwFlags

Specifies flags that indicate whether to translate to precomposed or composite wide characters (if a composite form exists), or to indicate whether to use glyph characters or control codes. The parameter can be one of the following values:

Value	Meaning
MB_PRECOMPOSED	Always use precomposed characters — that is, characters in which a base character and a nonspacing character have a single character value. This is the default translation option.
MB_COMPOSITE	Always use composite characters — that is, characters in which a base character and a nonspacing character have different values.
MB_USEGLYPHCHARS	Use glyph characters instead of control characters.
A base character is a character followed by a nonspacing character. For example, in the character è, the e is the base character and the accent mark is the nonspacing character.

lpMultiByteStr

Points to the character string to be converted.

cchMultiByte

Specifies the size in bytes of the string pointed to by the lpMultiByteStr parameter. If this value is −1, the string is assumed to be null terminated and the length is calculated automatically.

lpWideCharStr

Points to a buffer that receives the translated string.

cchWideChar

Specifies the size, in wide characters, of the buffer pointed to by the lpWideCharStr parameter. If this value is zero, the function returns the number of wide characters required for the buffer, and makes no use of the lpWideCharStr buffer.

Return Value

If the function succeeds, and cchWideChar is non-zero, the return value is the number of wide characters written to the buffer pointed to by lpWideCharStr.

If the function succeeds, and cchWideChar is zero, the return value is the required size, in wide characters, for a buffer that can receive the translated string.

If the function fails, the return value is FALSE. Call GetLastError for extended error information.

Comments

The lpMultiByteStr and lpWideCharStr pointers must not be the same. If they are the same, the function fails, and GetLastError returns the value ERROR_INVALID_PARAMETER.

See Also

»WideCharToMultiByte«


  NDdeGetErrorString

UINT NDdeGetErrorString (uErrorCode, lpszErrorString, cBufSize)
UINT  uErrorCode;   /* Error code to get string for */
LPTSTR  lpszErrorString;   /* buffer to hold error string  */
DWORD  cBufSize;   /* sizeof buffer */

The NDdeGetErrorString function is called to convert an error code returned by the NetDDE DSDM interface API into an error string explaining the reason for the returned error.

Parameters

uErrorCode

Error code to be converted.

lpszErrorString

Address of a buffer to accept the tranlated error string. Must not be null. If the buffer is not large enough to store the complete error string, the string will be truncated.

cBufSize

Defines the size of the buffer allocated to receive the error string.

Return Value

If the function succeeds, it returns the value 0.

If the function fails, it returns a non-zero error code. If the lpszErrorString buffer is not large enought to accept the complete error string, and the string is truncated, the function returns the value NDDE_BUF_TOO_SMALL.


  NDdeGetShareSecurity

UINT NDdeGetShareSecurity(lpszServer, lpszShareName, si, pSD, cbSD, lpcbsdRequired)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share to delete */
SECURITY_INFORMATION  si;   /* requested information */
PSECURITY_DESCRIPTOR  pSD;   /* address of SD buffer */
DWORD  cbSD;   /* size of SD buffer */
LPDWORD  lpcbsdRequired;   /* address of required size for SD buffer */

The NDdeGetShareSecurity function is called to get the SECURITY_DESCRIPTOR  associated with the DDE share. This is done usually for editing.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name whose security descriptor is to be retrieved from the DSDM. This parameter should not be null.

si

Identifies the SECURITY_INFORMATION to be retrieved from the SECURITY_DESCRIPTOR associated with the share.

pSD

Address of a buffer that will accept the retrieved self-relative SECURITY_DESCRIPTOR. This parameter can be null. If this parameter is null, the DSDM determines the size of the requested security information and returns the number of bytes needed in the lpcbsdRequired parameter along with NDDE_BUF_TOO_SMALL error code.

cbSD

Specifies the size of the buffer provided and referenced by the pSD parameter to accept the retrieved security descritptor. It must be 0 if pSD is null.

lpcbsdRequired

Address of the variable into which the actual size of the retrieved security descriptor is stored. Must not be null.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString. If the pSD parameter was null, it returns NDDE_BUF_TOO_SMALL.


  NDdeGetTrustedShare

UINT NDdeGetTrustedShare (lpszServer, lpszShareName, lpdwTrustOptions, lpdwShareModId1)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share to query */
LPDWORD  lpdwTrustOptions;   /* trust options in effect */
LPDWORD  lpdwShareModId1;   /* second word of share mod id */

The NDdeGetTrustedShare function is called to retrieve the options associated with a currently 'trusted' DDE share.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name whose trusted status is being queried. This parameter should not be null.

lpdwTrustOptions

Address of a variable into which the TRUST_SHARE_OPTIONS will be stored. Must not be null.

lpdwShareModId0

Address of a variable into which the first word of the trusted share modify id will be stored. Must not be null.

lpdwShareModId1

Address of a variable into which the second word of the trusted share modify id will be stored. Must not be null.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString.

Comments

The trusted share modify id reflects the version of DDE share in the NetDDE DSDM at the time the DDE share was initially promoted to trust status. It is primarily used to purge obsolete trusted shares; however, the user does not need to do that proactively. the NetDDE Agent purges obsolete shares on the user's behalf.


  NDdeIsValidAppTopicList

BOOL NDdeIsValidAppTopicList (targetTopic)
LPTSTR targetTopic  ;   /* points to app and topic string */

The NDdeIsValidAppTopicList function is called to validate an application and topic string ("AppName|TopicName")  for proper syntax.

Parameters

targetTopic

Address of the application and topic string  to validate. Must not be null.

Return Value

If the targetTopic has valid syntax the function returns TRUE; otherwise, FALSE.


  NDdeIsValidShareName

BOOL NDdeIsValidShareName (shareName)
LPTSTR  shareName;   /* points to share name to validate */

The NDdeIsValidShareName function is called to validate a share name for proper syntax.

Parameters

shareName

Address of a share name to validate. Must not be null.

Return Value

If the share name has valid syntax, the function returns TRUE; otherwise, FALSE.


  NDdeSetShareSecurity

UINT NDdeSetShareSecurity(lpszServer, lpszShareName, si, pSD)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share to delete */
SECURITY_INFORMATION  si;   /* type of information */
PSECURITY_DESCRIPTOR  pSD;   /* address of security descriptor to set */

The NDdeSetShareSecurity function is called to set the SECURITY_DESCRIPTOR associated with the DDE share. This is done usually after editing the DACL assigned to the DDE share.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name whose security descriptor is to be modified in the DSDM. This parameter should not be null.

si

Identifies the SECURITY_INFORMATION to be modified in the SECURITY_DESCRIPTOR associated with the DDE share.

pSD

Address of the SECURITY_DESCRIPTOR that will be the source of the security information modified in the DDE share. This parameter must not be null and should point to valid absolute or self-relative security descriptor.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString.

Comments

To modify the SECURITY_DESCRIPTOR associated with  a DDE share in the DSDM, the user must have appropriate priviledges, e.g., the share creator has such rights.


  NDdeSetTrustedShare

UINT NDdeSetTrustedShare (lpszServer, lpszShareName, dwTrustOptions)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share to delete  */
DWORD  dwTrustOptions;   /* trust options to apply */

The NDdeSetTrustedShare function is called to promote the referenced DDE share to trusted status within the current user's context.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name being promoted to trusted status. This parameter should not be null.

dwTrustOptions

Specifies the options affecting the trusted status of the DDE share. The following TRUST_SHARE_OPTIONS options are available:

Option	Meaning
NDDE_TRUST_SHARE_START	Allow the application to be started in the user's context.
NDDE_TRUST_SHARE_INIT	Allow a client to initiate to the application if it is already executing in the user's context.
NDDE_TRUST_SHARE_DEL	Delete the trusted share.
NDDE_TRUST_CMD_SHOW	Start the application with CmdShow field defined here overriding the CmdShow specified in the DDE share DSDM.
NDDE_CMD_SHOW_MASK	CmdShow value used to override the DDE share CmdShow if the NDDE_TRUST_CMD_SHOW is set.
Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString.

Comments

If NDdeSetTrustedShare is called with dwTrustOptions set to 0, the trusted share will be deleted.


  NDdeShareAdd

UINT NDdeShareAdd (lpszServer, nLevel, pSD, lpBuffer, cBufSize)
LPTSTR  lpszServer;   /* server to execute on */
UINT  nLevel;   /* info level must be 2 */
PSECURITY_DESCRIPTOR  pSD;   /* initial security descriptor */
LPBYTE  lpBuffer;   /* address of NDDESHAREINFO  */
DWORD  cBufSize;   /* sizeof supplied buffer */

The NDdeShareAdd function is called to create and add a new DDE share to the NetDDE DSDM.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

nLevel

Must always be 2.

pSD

Address of the SECURITY_DESCRIPTOR that will be associated with this share and against which access checks will be performed on subsequent initiates to this share. This parameter can optionally be null, in which case the DSDM creates a default SECURITY_DESCRIPTOR that grants "Full Control" to the CREATOR_OWNER and "Read and Link" to everyone.

lpBuffer

Address of the NDDESHAREINFO structure that defines the ApplicationTopic list associated with the DDE share being created as well as other parameters. This parameter must not be null.

cBufSize

Size of the structure identified by lpBuffer. It must not be 0.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString.

Comments

NDdeAddShare is usually the first and only function that needs to be called in the creation of a DDE share.


  NDdeShareDel

UINT NDdeShareDel (lpszServer, lpszShareName, wReserved)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share to delete  */
UINT  wReserved;   /* must be 0 */

The NDdeShareDel function is called to delete a DDE share from the NetDDE DSDM.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name that is to be deleted from the DSDM. This parameter should not be null.

wReserved

Must be 0.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString.

Comments

To delete a DDE share from the DSDM the user must have appropriate privileges. The share creator has delete rights.


  NDdeShareEnum

UINT NDdeShareEnum (lpszServer, nLevel, lpBuffer, cBufSize, lpnEntriesRead,
lpcbTotalAvailable)
LPTSTR  lpszServer;   /* server to execute on */
UINT  nLevel;   /* Must be 0 */
LPBYTE  lpBuffer;   /* pointer to buffer */
DWORD  cBufSize;   /* size of buffer */
LPDWORD  lpnEntriesRead;   /* number of names returned */
LPDWORD  lpcbTotalAvailable;   /* number of bytes available */

The NDdeShareEnum function is called to list the available DDE shares in the NetDDE DSDM.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

nLevel

Must be 0.

lpBuffer

Address of a buffer supplied to accept the list of DDE shares. The list of DDE shares is stored as a sequence of null separated strings terminating with a double null at the end. This parameter can be null. If lpBuffer is null, the DSDM returns the size of buffer required to hold the list of shares in the lpcbTotalAvailable field.

cBufSize

Specifies the size of the supplied buffer addressed by lpBuffer. Must be 0 if lpBuffer is null.

lpnEntriesRead

Address of a variable to receive the total number of shares being enumerated. Must not be null.

lpcbTotalAvailable

Address of a variable to receive the total number of bytes needed in the buffer to store the list of DDE shares. Must not be null.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString. If the lpBuffer parameter is null, it returns NDDE_BUF_TOO_SMALL.

Comments

As a default, Everyone has permission to list the DDE shares


  NDdeShareGetInfo

UINT NDdeShareGetInfo ( lpszServer, lpszShareName, nLevel, lpBuffer, cBufSize,
lpnTotalAvailable, lpnItems)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share */
UINT  nLevel;   /* info level must be 2 */
LPBYTE  lpBuffer;   /* contains (NDDESHAREINFO) + data */
DWORD  cBufSize;   /* sizeof buffer */
LPDWORD  lpnTotalAvailable;   /* number of bytes available  */
LPWORD  lpnItems;   /* item mask for partial getinfo */

The NDdeShareGetInfo function is called to retrieve DDE share information from the NetDDE DSDM. This is usally done for editing.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name whose information is to be retrieved from the DSDM. This parameter should not be null.

nLevel

Must be 2.

lpBuffer

Address of a buffer that is to accept the NDDESHAREINFO structure and associated data pointed to by NDDESHAREINFO pointer fields. This field can be null. If lpBuffer is null, then the DSDM calculates the number of bytes required to store the requested share information and returns that value in the lpnTotalAvailable field along with the NDDE_BUF_TOO_SMALL error.

cBufSize

Defines the size of the buffer addressed by the lpBuffer field. If lpBuffer is null, then cBufSize should be 0.

lpnTotalAvailable

Address of a varaible that receives the count of the total number of bytes needed to store the requested share information. Must not be null.

lpnItems

Address of an item selection mask for partial share information retrieval. Current implementation requires that it be 0.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString. If the lpBuffer parameter is null, it returns NDDE_BUF_TOO_SMALL.


  NDdeShareSetInfo

UINT NDdeShareSetInfo (lpszServer, lpszShareName, nLevel, lpBuffer, cBufSize, sParmNum)
LPTSTR  lpszServer;   /* server to execute on */
LPTSTR  lpszShareName;   /* name of share */
UINT  nLevel;   /* info level must be 2 */
LPBYTE  lpBuffer;   /* address of NDDESHAREINFO */
DWORD  cBufSize;   /* sizeof buffer */
WORD  sParmNum;   /* Parameter index */

The NDdeShareSetInfo function is called to modify DDE share information stored in the NetDDE DSDM. This is usually done after editing.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

lpszShareName

Address of the share name whose information is to be modified in the DSDM. This parameter should not be null.

nLevel

Must be 2.

lpBuffer

Address of the NDDESHAREINFO structure that defines the new DDE share information to be stored in the DSDM. Currently the DDE share information is modified as a whole, i.e., no partial edits. Must not be null.

cBufSize

Size of the DDE share information addressed by lpBuffer.

sParmNum

Parameter index being modified. Current implementation does not support partial modification and, hence, it must be 0.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString.

Comments

To modify the DDE share information in the DSDM the user must have appropriate privileges. The share creator has such rights.


  NDdeTrustedShareEnum

UINT NDdeTrustedShareEnum (lpszServer, nLevel, lpBuffer, cBufSize, lpnEntriesRead,
lpcbTotalAvailable)
LPTSTR  lpszServer;   /* server to execute on */
UINT  nLevel;   /* must be 0 */
LPBYTE  lpBuffer;   /* pointer to buffer */
DWORD  cBufSize;   /* size of buffer */
LPDWORD  lpnEntriesRead;   /* number of names returned */
LPDWORD  lpcbTotalAvailable;   /* number of bytes available */

The NDdeTrustedShareEnumfunction is called to list the DDE shares trusted in the current user's context.

Parameters

lpszServer

Address of the server name on which the DSDM will be modified.

nLevel

Must be 0.

lpBuffer

Address of a buffer supplied to accept the list of trusted DDE shares. The list of trusted DDE shares is stored as a sequence of null separated strings terminating with a double null at the end. This parameter can be null. If the lpBuffer is null, the DSDM returns the size of buffer required to hold the list of shares in the lpcbTotalAvailable field.

cBufSize

Specifies the size of the supplied buffer addressed by lpBuffer. Must be 0 if lpBuffer is null.

lpnEntriesRead

Address of a variable to receive the total number of trusted shares being enumerated. Must not be null.

lpcbTotalAvailable

Address of a variable to receive the total number of bytes needed in the buffer to store the list of trusted DDE shares. Must not be null.

Return Value

If the function succeeds, it returns NDDE_NO_ERROR. Otherwise, it returns an error code which can be translated into a text error message by calling NDdeGetErrorString. If the lpBuffer parameter is null, it returns NDDE_BUF_TOO_SMALL.

Comments

The list of trusted DDE shares can only be viewed from a specific user's context.


  Netbios

UCHAR Netbios(pncb)
PNCB  pncb;   /* address of the network-control block */

The Netbios function interprets and executes the specified network-control block (NCB).

Parameters

pncb

Points to an NCB structure describing the network-control block to process. The NCB structure has the following format:

typedef struct _NCB { /* ncb */

    UCHAR  ncb_command;

    UCHAR  ncb_retcode;

    UCHAR  ncb_lsn;

    UCHAR  ncb_num;

    PUCHAR ncb_buffer;

    WORD   ncb_length;

    UCHAR  ncb_callname[NCBNAMSZ];

    UCHAR  ncb_name[NCBNAMSZ];

    UCHAR  ncb_rto;

    UCHAR  ncb_sto;

    void (*ncb_post) (struct _NCB *);

    UCHAR  ncb_lana_num;

    UCHAR  ncb_cmd_cplt;

    UCHAR  ncb_reserve[10];

    HANDLE ncb_event;

} NCB;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

For synchronous requests, the return value is the completion code of the NCB. That value is also returned in the ncb_retcode member of the NCB structure.

There are two return value possibilites for accepted asynchronous requests. If the asynchronous command has already completed when the Netbios call returns to its caller, the return value is the completion code of the NCB, just as if it were a synchronous NCB. If the asynchronous command is still pending when the Netbios call returns to its caller, the return value is 0.

If the address specified by the pncb parameter is invalid, the return value is NRC_BADNCB.

Comments

The Netbios function is primarily for applications written for the IBM NetBIOS system that need to be ported to Windows. Applications that do not have this requirement typically use other interfaces, such as mailslots and named pipes, instead of Netbios.

The Netbios function contains extensions to the standard IBM NetBIOS 3.0 specification to allow POST routines to be called from C and to operate efficiently in the Windows environment.

When an asynchronous network-control block finishes and ncb_post is nonzero, the routine specified in ncb_post is called with a single parameter of type PNCB. This parameter contains the address of the finishing network-control block. (In the standard IBM NetBIOS 3.0, the address of the network-control block is supplied in a nonportable interface.)

Another extension to the NCB structure is a handle of an event (ncb_event). The event is set to the non-signalled state by the system when an asynchronous NetBIOS command is accepted, and is set to the signalled state when the asynchronous NetBIOS command finishes.

Using ncb_event to submit asynchronous requests requires fewer system resources than using ncb_post. Also, when ncb_event is nonzero, the pending request is canceled if the thread terminates before the request is processed. This is not true for requests sent by using ncb_post.

Only manual reset events should be used with Netbios. A given event should not be associated with more than one active asynchronous NetBIOS command.


  ObjectCloseAuditAlarm

BOOL ObjectCloseAuditAlarm(lpszSubsystem, lpvHandleId, fGenerateOnClose)
LPTSTR  lpszSubsystem;   /* address of string for subsystem name */
LPVOID  lpvHandleId;   /* address of handle identifier */
BOOL  fGenerateOnClose;   /* flag for audit generation */

The ObjectCloseAuditAlarm function generates audit messages when a handle of an object is deleted. Alarms are not supported in the current version of Windows NT.

Parameters

lpszSubsystem

Points to a null-terminated string specifying the name of the subsystem calling the function; for example, "DEBUG" or "WIN32".

lpvHandleId

Specifies a unique 32-bit value representing the client's handle of the object. This should be the same value that was passed to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function.

fGenerateOnClose

Specifies a flag set by a call to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function when the object handle is created.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ObjectCloseAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege. The test for this privilege is always performed against the primary token of the calling process, allowing the calling process to impersonate a client.

The ObjectCloseAuditAlarm function may send many messages to port objects. This can result in a significant delay before the function returns. The design of applications calling ObjectCloseAuditAlarm can take this potential delay into account. For example, this consideration may affect the design of an application that uses mutexes to lock structures.

See Also

»AccessCheck«, »AccessCheckAndAuditAlarm«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »MapGenericMask«, »ObjectOpenAuditAlarm«, »ObjectPrivilegeAuditAlarm«, »PrivilegeCheck«, »PrivilegedServiceAuditAlarm«


  ObjectOpenAuditAlarm

BOOL ObjectOpenAuditAlarm(lpszSubsystem, lpvHandleId, lpszObjectType, lpszObject,
psd, hClientToken, dwDesiredAccess, dwGrantedAccess, pps, fObjectCreation, fAccessGranted,
lpfGenerateOnClose)
LPTSTR  lpszSubsystem;   /* address of string for subsystem name */
LPVOID  lpvHandleId;   /* address of handle identifier */
LPTSTR  lpszObjectType;   /* address of string for object type */
LPTSTR  lpszObject;   /* address of string for object name */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
HANDLE  hClientToken;   /* handle of client's access token */
DWORD  dwDesiredAccess;   /* mask for desired access rights */
DWORD  dwGrantedAccess;   /* mask for granted access rights */
PPRIVILEGE_SET  pps;   /* address of privileges */
BOOL  fObjectCreation;   /* flag for object creation */
BOOL  fAccessGranted;   /* flag for results */
LPBOOL  lpfGenerateOnClose;   /* address of flag for audit generation */

The ObjectOpenAuditAlarm function generates audit messages when a client application attempts to gain access to an object or to create a new one. Alarms are not supported in the current version of Windows NT.

Parameters

lpszSubsystem

Points to a null-terminated string specifying the subsystem calling this function; for example, "DEBUG" or "WIN32".

lpvHandleId

Points to a unique 32-bit value representing the client's handle of the object. If the access is denied, this parameter is ignored.

lpszObjectType

Points to a null-terminated string specifying the type of object to which the client is requesting access. This string appears in the audit log for the object.

lpszObject

Points to a null-terminated string specifying the name of the object to which the client gained access or attempted to gain access. This string appears in the audit log for the object.

psd

Points to the SECURITY_DESCRIPTOR structure for the object being accessed.

hClientToken

Identifies an access token representing the client requesting the operation. This handle must be obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.

dwDesiredAccess

Specifies the desired access mask. This mask must have been previously mapped by the MapGenericMask function to contain no generic access rights.

dwGrantedAccess

Specifies an access mask indicating which access rights are granted. This access mask is intended to be the same value set by one of the access-checking functions in its dwGrantedAccess parameter. Examples of access-checking functions include AccessCheckAndAuditAlarm and AccessCheck.

pps

Points to a PRIVILEGE_SET structure that specifies the set of privileges required for the access attempt. This parameter can be NULL.

The PRIVILEGE_SET structure has the following form:

typedef struct _PRIVILEGE_SET { /* ps */

    DWORD PrivilegeCount;

    DWORD Control;

    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];

} PRIVILEGE_SET;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fObjectCreation

Specifies a flag that determines whether the application creates a new object when access is granted. When this flag is TRUE, the application creates a new object; when it is FALSE, the application opens an existing object.

fAccessGranted

Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function, such as AccessCheck. If access was granted, this flag is TRUE. If not, it is FALSE.

lpfGenerateOnClose

Points to a flag set by the audit-generation routine when the function returns. This flag must be passed to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ObjectOpenAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege. The test for this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. This allows the calling process to impersonate a client during the call.

The ObjectOpenAuditAlarm function may send many messages to port objects. This can result in a significant delay before the function returns. The design of applications calling ObjectOpenAuditAlarm can take this potential delay into account. For example, this consideration may affect the design of an application using mutexes to lock structures.

See Also

»AccessCheck«, »AccessCheckAndAuditAlarm«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »MapGenericMask«, »ObjectCloseAuditAlarm«, »ObjectPrivilegeAuditAlarm«, »PrivilegeCheck«, »PrivilegedServiceAuditAlarm«


  ObjectPrivilegeAuditAlarm

BOOL ObjectPrivilegeAuditAlarm(lpszSubsystem, lpvHandleId, hClientToken,
dwDesiredAccess, pps, fAccessGranted)
LPTSTR  lpszSubsystem;   /* address of string for subsystem name */
LPVOID  lpvHandleId;   /* address of handle identifier */
HANDLE  hClientToken;   /* handle of client's access token */
DWORD  dwDesiredAccess;   /* mask for desired access rights */
PPRIVILEGE_SET  pps;   /* address of privileges  */
BOOL  fAccessGranted;   /* flag for results */

The ObjectPrivilegeAuditAlarm function generates audit messages as a result of a client's attempt to perform a privileged operation on a server application object using an already opened handle of that object. Alarms are not supported in the current version of Windows NT.

Parameters

lpszSubsystem

Points to a null-terminated string specifying the name of the subsystem calling the function; for example, "DEBUG" or "WIN32".

lpvHandleId

Points to a unique 32-bit value representing the client's handle of the object.

hClientToken

Identifies an access token representing the client requesting the operation. This handle must be obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.

dwDesiredAccess

Specifies an access mask indicating the privileged access types being used or whose use is being attempted. The access mask can be mapped by the MapGenericMask function so it does not contain any generic access types.

pps

Points to a PRIVILEGE_SET structure specifying the set of privileges required for the requested operation. The information in this structure is supplied by a call to the PrivilegeCheck function. This parameter can be NULL.

The PRIVILEGE_SET structure has the following form:

typedef struct _PRIVILEGE_SET { /* ps */

    DWORD PrivilegeCount;

    DWORD Control;

    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];

} PRIVILEGE_SET;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fAccessGranted

Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function such as PrivilegeCheck. If access was granted, this flag is TRUE. If not, it is FALSE.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ObjectPrivilegeAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege. The test for this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. This allows the calling process to impersonate a client during the call.

The ObjectPrivilegeAuditAlarm function can send many messages to port objects. This can result in a significant delay before the function returns. The design of applications calling ObjectPrivilegeAuditAlarm can take this potential delay into account. For example, this consideration may affect the design of an application using mutexes to lock structures.

See Also

»AccessCheck«, »AccessCheckAndAuditAlarm«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »MapGenericMask«, »ObjectCloseAuditAlarm«, »ObjectOpenAuditAlarm«, »PrivilegeCheck«, »PrivilegedServiceAuditAlarm«


  OemKeyScan

DWORD OemKeyScan(wOemChar)
WORD  wOemChar;   /* ASCII value of OEM character */

The OemKeyScan function maps OEM ASCII codes 0 through 0x0FF into the OEM scan codes and shift states. The function provides information that allows a program to send OEM text to another program by simulating keyboard input.

Parameters

wOemChar

Specifies the ASCII value of the OEM character.

Return Value

If the function succeeds, the low-order word of the return value contains the scan code of the given OEM character, and the high-order word contains the shift state, which can be a combination of the following flag bits:

Bit	Meaning
1	Either SHIFT key is pressed.
2	Either CTRL key is pressed.
4	Either ALT key is pressed.
If the character cannot be produced by a single keystroke using the current keyboard layout, the return value is 0xFFFFFFFF.

Comments

This function does not provide translations for characters that require CTRL+ALT or dead keys. Characters not translated by this function must be copied by simulating input using the ALT+ keypad mechanism. The NUMLOCK key must be off.

This function does not provide translations for characters that cannot be typed with one keystroke using the current keyboard layout, such as characters with diacritics requiring dead keys. Characters not translated by this function may be simulated using the ALT+ keypad mechanism. The NUMLOCK key must be on.

This function is implemented using the VkKeyScan function.

See Also

»VkKeyScan«


  OemToAnsi

The OemToAnsi function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the OemToChar function.


  OemToAnsiBuff

The OemToAnsiBuff function is obsolete.

For compatibility with earlier versions of Windows, this function is implemented as a macro that calls the OemToCharBuff function.


  OemToChar

BOOL OemToChar(lpszOemStr, lpszStr)
LPCSTR  lpszOemStr;   /* address of string to translate */
LPTSTR  lpszStr;   /* address of buffer for translated string */

The OemToChar function translates a string from the OEM-defined character set into either an ANSI or a wide-character string. (OEM stands for original equipment manufacturer.)

Parameters

lpszOemStr

Points to a null-terminated string of characters from the OEM-defined character set.

lpszStr

Points to the buffer for the translated string. If the string buffer is large enough and the OemToChar function is being used as an ANSI function, the string can be translated in place by setting the lpszStr parameter to the same address as the lpszOemStr parameter. This cannot be done if OemToChar is being used as a wide-character function.

Return Value

The return value is always TRUE.

See Also

»CharToOem«, »CharToOemBuff«, »OemToCharBuff«


  OemToCharBuff

BOOL OemToCharBuff(lpOemStr, lpszStr, cchString)
LPCSTR  lpOemStr;   /* address of string to translate */
LPTSTR  lpszStr;   /* address of buffer for translated string  */
DWORD  cchString;   /* size of buffer */

The OemToCharBuff function translates a specified number of characters in a string from the OEM-defined character set into either an ANSI or a wide-character string. (OEM stands for original equipment manufacturer.)

Parameters

lpOemStr

Points to a buffer containing one or more characters from the OEM-defined character set.

lpszStr

Points to the buffer for the translated string. If the string buffer is large enough and the OemToCharBuff function is being used as an ANSI function, the string can be translated in place by setting the lpszStr parameter to the same address as the lpOemStr parameter. This cannot be done if the OemToCharBuff function is being used as a wide-character function.

cchString

Specifies the number of characters to translate in the buffer identified by the lpOemStr parameter.

Return Value

The return value is always TRUE.

See Also

»CharToOem«, »CharToOemBuff«, »OemToChar«


  OffsetClipRgn

int OffsetClipRgn(hdc, nXOffset, nYOffset)
HDC  hdc;   /* handle of device context */
int  nXOffset;   /* offset along x-axis */
int  nYOffset;   /* offset along y-axis */

The OffsetClipRgn function moves the clipping region of the given device context by the specified offsets.

Parameters

hdc

Identifies the device context.

nXOffset

Specifies the number of logical units to move left or right.

nYOffset

Specifies the number of logical units to move up or down.

Return Value

If the function succeeds, the return value specifies the new region's complexity. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred. (The current clipping region is not affected.)
See Also

»SelectClipRgn«


  OffsetRect

BOOL OffsetRect(lprc, x, y)
LPRECT  lprc;   /* address of structure with rectangle */
int  x;   /* horizontal offset  */
int  y;   /* vertical offset */

The OffsetRect function moves the specified rectangle by the specified offsets.

Parameters

lprc

Points to a RECT structure that contains the logical coordinates of the rectangle to be moved. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

x

Specifies the amount to move the rectangle left or right. This parameter must be a negative value to move the rectangle to the left.

y

Specifies the amount to move the rectangle up or down. This parameter must be a negative value to move the rectangle up.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»InflateRect«, »IntersectRect«, »UnionRect«


  OffsetRgn

int OffsetRgn(hrgn, nXOffset, nYOffset)
HRGN  hrgn;   /* handle of region */
int  nXOffset;   /* offset along x-axis */
int  nYOffset;   /* offset along y-axis */

The OffsetRgn function moves a region by the specified offsets.

Parameters

hrgn

Identifies the region to be moved.

nXOffset

Specifies the number of logical units to move left or right.

nYOffset

Specifies the number of logical units to move up or down.

Return Value

The return value specifies the new region's complexity. It can be one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred; region is unaffected.


  OffsetViewportOrg

The OffsetViewportOrg function has been deleted. Win32 applications should use the OffsetViewportOrgEx function.

See Also

»OffsetViewportOrgEx«


  OffsetViewportOrgEx

BOOL OffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint)
HDC  hdc;   /* handle of device context */
int  nXOffset;   /* horizontal offset */
int  nYOffset;   /* vertical offset */
LPPOINT  lpPoint;   /* address of structure receiving original origin */

The OffsetViewportOrgEx function modifies the viewport origin for the given device context (DC) using the specified horizontal and vertical offsets.

Parameters

hdc

Identifies the DC.

nXOffset

Specifies the horizontal offset, in device units.

nYOffset

Specifies the vertical offset, in device units.

lpPoint

Points to a POINT structure. The previous viewport origin in device units is placed in this structure. If lpPoint is NULL the previous viewport origin is not returned. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The new origin is the sum of the current origin and the horizontal and vertical offsets.

See Also

»GetViewportOrgEx«, »OffsetWindowOrgEx«, »SetViewportOrgEx«


  OffsetWindowOrg

The OffsetWindowOrg function has been deleted. Win32 applications should use the OffsetWindowOrgEx function.

See Also

»OffsetWindowOrgEx«


  OffsetWindowOrgEx

BOOL OffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint)
HDC  hdc;   /* handle of device context */
int  nXOffset;   /* horizontal offset */
int  nYOffset;   /* vertical offset */
LPPOINT  lpPoint;   /* address of structure receiving the original origin */

The OffsetViewportOrgEx function modifies the window origin for the given device context (DC) using the specified horizontal and vertical offsets.

Parameters

hdc

Identifies the DC.

nXOffset

Specifies the horizontal offset, in logical units.

nYOffset

Specifies the vertical offset, in logical units.

lpPoint

Points to a POINT structure. The logical coordinates of the previous window origin are placed in this structure. If lpPoint is NULL, the previous origin is not returned. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

»GetViewportOrgEx«, »OffsetViewportOrgEx«


  OpenBackupEventLog

HANDLE OpenBackupEventLog(lpszUNCServerName, lpszFileName)
LPTSTR  lpszUNCServerName;   /* backup file server name  */
LPTSTR  lpszFileName;   /* backup filename */

The OpenBackupEventLog function opens a handle of a backup event log. This handle can be used with the BackupEventLog function.

Parameters

lpszUNCServerName

Points to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which this operation is to be performed. If this parameter is NULL, the operation is performed on the local computer.

lpszFileName

Points to a null-terminated string that specifies the name of the backup file. The backup filename may contain a server name to open a backup file on a remote server (in this case, lpszUNCServerName must be NULL).

Return Value

If the function succeeds, the return value is a handle of the backup event log; otherwise, the return value is NULL.

Comments

If the backup filename specifies a remote server, lpszUNCServerName must be NULL. You cannot use this function to open a file on a remote server.

See Also

»BackupEventLog«


  OpenClipboard

BOOL OpenClipboard(hwnd)
HWND  hwnd;   /* handle of window opening clipboard */

The OpenClipboard function opens the clipboard for examination and prevents other applications from modifying the clipboard contents.

Parameters

hwnd

Identifies the window to be associated with the open clipboard. If this parameter is NULL, the open clipboard is associated with the current task.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The OpenClipboard function fails if another window has the clipboard open.

An application should call the CloseClipboard function after every successful call to the OpenClipboard function.

The window identified by the hwnd parameter does not become the clipboard owner unless the EmptyClipboard function is called.

See Also

»CloseClipboard«, »EmptyClipboard«


  OpenEvent

HANDLE OpenEvent(fdwAccess, fInherit, lpszEventName)
DWORD  fdwAccess;   /* access flag */
BOOL  fInherit;   /* inherit flag */
LPTSTR  lpszEventName;   /* address of event-object name */

The OpenEvent function returns a handle of an existing named event object.

Parameters

fdwAccess

Specifies the requested access to the event object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:

Access	Description
EVENT_MODIFY_STATE	Enables use of the event handle in the SetEvent and ResetEvent functions to modify the event's state.
SYNCHRONIZE	Enables use of the event handle in any of the wait functions to wait for the event's state to be signaled.
EVENT_ALL_ACCESS	Specifies all possible access flags for the event object.
fInherit

Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.

lpszEventName

Points to a null-terminated string that names the event to be opened. Name comparisons are case sensitive.

Return Value

If the function succeeds, the return value is a handle of the event object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The OpenEvent function enables multiple processes to open handles of the same event object. The function succeeds only if some process has already created the event by using the CreateEvent function. The calling process can use the returned handle in any function that requires a handle of an event object, subject to the limitations of the access specified in the fdwAccess parameter.

The handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The event object is destroyed when its last handle has been closed.

See Also

»CloseHandle«, »CreateEvent«, »DuplicateHandle«, »MsgWaitForMultipleObjects«, »PulseEvent«, »ResetEvent«, »SetEvent«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  OpenEventLog

HANDLE OpenEventLog(lpszUNCServerName, lpszSourceName)
LPTSTR  lpszUNCServerName;   /* address of server name  */
LPTSTR  lpszSourceName;   /* address of source name */

The OpenEventLog function opens a handle of an event log.

Parameters

lpszUNCServerName

Points to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which the event log is to be opened. If this parameter is NULL, the log is opened on the local computer.

lpszSourceName

Points to a null-terminated string that specifies the name of the source that the returned handle will reference. The source name must be a subkey of a logfile entry under the EventLog key in the registry. For example, the source name WinApp would be valid if the registry had the following form:

HKEY_LOCAL_MACHINE

  System

    CurrentControlSet

      Services

        EventLog

          Application

            WinApp

          Security

          System

If the source name cannot be found, the event logging service uses the Application logfile with no message files for the event identifier or category.

Return Value

If the function succeeds, the return value is the handle of an event log; otherwise, the return value is NULL. To get extended error information, use the GetLastError function.

See Also

»ClearEventLog«, »CloseEventLog«, »GetNumberOfEventLogRecords«, »GetOldestEventLogRecord«, »ReadEventLog«, »ReportEvent«


  OpenFile

HFILE OpenFile(lpszFile, lpOpenBuff, fuMode)
LPCSTR  lpszFile;   /* address of filename */
LPOFSTRUCT  lpOpenBuff;   /* address of buffer for file information  */
UINT  fuMode;   /* action and attributes */

The OpenFile function creates, opens, reopens, or deletes a file.

This function is provided for compatibility with earlier versions of Windows. In particular, the OpenFile function cannot open a named pipe. For Win32 applications, use the CreateFile function.

Parameters

lpszFile

Points to a null-terminated string that names the file to be opened. The string must consist of characters from the Windows 3.x character set. The OpenFile function does not support Unicode filenames.

lpOpenBuff

Points to the OFSTRUCT structure to receive information about the file when it is first opened. The structure can be used in subsequent calls to the OpenFile function to refer to the open file.

The OFSTRUCT structure has the following form:

typedef struct _OFSTRUCT { /* of */

    BYTE cBytes;

    BYTE fFixedDisk;

    WORD nErrCode;

    WORD Reserved1;

    WORD Reserved2;

    BYTE szPathName[OFS_MAXPATHNAME];

} OFSTRUCT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuMode

Specifies the action to take. These styles can be combined by using the bitwise OR operator:

Value	Meaning
OF_CANCEL	Ignored. In the Win32 API, the OF_PROMPT style produces a dialog box containing a Cancel button.
OF_CREATE	Creates a new file. If the file already exists, it is truncated to zero length.
OF_DELETE	Deletes the file.
OF_EXIST	Opens the file and then closes it. Used to test for file existence.
OF_PARSE	Fills the OFSTRUCT structure but carries out no other action.
OF_PROMPT	Displays a dialog box if the requested file does not exist. The dialog box informs the user that Windows cannot find the file, and it contains Retry and Cancel buttons. Choosing the Cancel button directs OpenFile to return a file-not-found error message.
OF_READ	Opens the file for reading only.
OF_READWRITE	Opens the file for reading and writing.
OF_REOPEN	Opens the file using information in the reopen buffer.
OF_SHARE_COMPAT	For MS-DOS−based file systems using the Win32 application programming interface (API), opens the file with compatibility mode, allowing any process on a given computer to open the file any number of times. Other efforts to open with any other sharing mode fail. For NTFS-based file systems, this flag is mapped to OF_SHARE_DENY_NONE.
OF_SHARE_DENY_NONE	Opens the file without denying read or write access to other processes. If the file has been opened in compatibility mode by any other process, the function fails.
OF_SHARE_DENY_READ	Opens the file and denies read access to other processes. If the file has been opened in compatibility mode or for read access by any other process, the function fails.
OF_SHARE_DENY_WRITE	Opens the file and denies write access to other processes. If the file has been opened in compatibility mode or for write access by any other process, the function fails.
OF_SHARE_EXCLUSIVE	Opens the file with exclusive mode, denying both read and write access to other processes. If the file has been opened in any other mode for read or write access, even by the current process, the function fails.
OF_VERIFY	Verifies that the date and time of the file are the same as when it was previously opened. This is useful as an extra check for read-only files.
OF_WRITE	Opens the file for writing only.
Return Value

If the function succeeds, the return value specifies a file handle; otherwise, it is HFILE_ERROR. To get extended error information, use the GetLastError function.

Comments

If the lpszFile parameter specifies a filename and extension only, this function searches for a matching file in the following directories, in the order shown:

1.	The directory from which the application loaded.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

The lpszFile parameter cannot contain wildcard characters.

To close the file after use, call the _lclose function.

See Also

»CreateFile«, »GetSystemDirectory«, »GetWindowsDirectory«, »_lclose«


  OpenFileMapping

HANDLE OpenFileMapping(dwDesiredAccess, bInheritHandle, lpName)
DWORD  dwDesiredAccess;   /* access mode */
BOOL  bInheritHandle;   /* inherit flag */
LPTSTR  lpName;   /* address of name of file-mapping object */

The OpenFileMapping function opens a named file-mapping object.

Parameters

dwDesiredAccess

Specifies the access to the file-mapping object. For Windows NT, this access is checked against any security descriptor on the target file-mapping object.

bInheritHandle

Specifies whether the returned handle is to be inherited by a new process during process creation. A value of TRUE indicates that the new process inherits the handle.

lpName

Points to a string that names the file-mapping object to be opened. If there is an open handle to a file-mapping object by this name and the security descriptor on the mapping object does not conflict with the dwDesiredAccess parameter, the open operation succeeds.

Return Value

If the function succeeds, the return value is an open handle to the specified file-mapping object. Otherwise, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

The handle that OpenFileMapping returns can be used with any function that requires a handle to a file-mapping object.


  OpenIcon

BOOL OpenIcon(hwnd)
HWND  hwnd;   /* handle of window */

The OpenIcon function restores a minimized (iconic) window to its previous size and position, and then activates it.

Parameters

hwnd

Identifies the window to be restored and activated.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The OpenIcon function sends a WM_QUERYOPEN message to the given window.

See Also

»CloseWindow«, »IsIconic«, »ShowWindow«


  OpenMutex

HANDLE OpenMutex(fdwAccess, fInherit, lpszMutexName)
DWORD  fdwAccess;   /* access flag */
BOOL  fInherit;   /* inherit flag */
LPTSTR  lpszMutexName;   /* address of mutex-object name */

The OpenMutex function returns a handle of an existing named mutex object.

Parameters

fdwAccess

Specifies the requested access to the mutex object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:

Access	Description
SYNCHRONIZE	Enables use of the mutex handle in any of the wait functions to acquire ownership of the mutex, or in the ReleaseMutex function to release ownership.
MUTEX_ALL_ACCESS	Specifies all possible access flags for the mutex object.
fInherit

Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.

lpszMutexName

Points to a null-terminated string that names the mutex to be opened. Name comparisons are case sensitive.

Return Value

If the function succeeds, the return value is a handle of the mutex object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The OpenMutex function enables multiple processes to open handles of the same mutex object. The function succeeds only if some process has already created the mutex by using the CreateMutex function. The calling process can use the returned handle in any function that requires a handle of a mutex object, subject to the limitations of the access specified in the fdwAccess parameter.

The handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.

See Also

»CloseHandle«, »CreateMutex«, »DuplicateHandle«, »MsgWaitForMultipleObjects«, »ReleaseMutex«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  OpenPrinter

BOOL OpenPrinter(pPrinterName, phPrinter, pDefault)
LPTSTR  pPrinterName;   /* address of printer or server name */
LPHANDLE  phPrinter;   /* address of printer or server handle */
LPPRINTER_DEFAULTS  pDefault;   /* address of printer defaults structure */

The OpenPrinter function retrieves a handle identifying the specified printer or print server.

Parameters

pPrinterName

Points to a null-terminated string that specifies the name of the printer or print server.

phPrinter

Points to a value that receives the handle identifying the opened printer or print server object.

pDefault

Points to a PRINTER_DEFAULTS structure. This value can be NULL. The PRINTER_DEFAULTS structure has the following form:

typedef struct _PRINTER_DEFAULTS {  /* pd */

    LPTSTR      pDatatype;

    LPDEVMODE   pDevMode;

    ACCESS_MASK DesiredAccess;

} PRINTER_DEFAULTS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The pDefault parameter allows an application to specify the data type and device mode values that are used for printing documents submitted by the StartDocPrinter function. However, these values can be overridden by using the SetJob function once a document has been started.

The DesiredAccess member of the PRINTER_DEFAULTS data structure pointed to by pDefault specifies the accesses that an application wishes to perform using the handle returned by OpenPrinter. If an application wishes to open a printer to perform administrative tasks, such as the SetPrinter function, it should open the printer with PRINTER_ALL_ACCESS access. If an application wishes only to perform basic printing operations, an access value that includes PRINTER_ACCESS_USE is sufficient.

An application can determine what permissions a client has on a print server, or obtain a handle to a print server in  order to call WaitForPrinterChange. To do so, it should call OpenPrinter with pPrinterName set to the name of the server and should specify a server access mask value such as SERVER_ALL_ACCESS. The pDatatype and pDevMode members of the PRINTER_DEFAULTS data structure should be set to NULL. The handle returned by such a call may be passed to ClosePrinter or WaitForPrinterChange.

If a user does not hold permission to open a specified printer or print server with the desired access, the OpenPrinter call will fail, and GetLastError will return the value ERROR_ACCESS_DENIED.

See Also

»ClosePrinter«


  OpenProcess

HANDLE OpenProcess(fdwAccess, fInherit, IDProcess)
DWORD  fdwAccess;   /* access flag */
BOOL  fInherit;   /* can child process inherit? */
DWORD  IDProcess;   /* process identifier */

The OpenProcess function returns a handle of an existing process object.

Parameters

fdwAccess

Specifies the access to the process object. For operating systems that support security checking, this access is checked against any security descriptor for the target process. Any combination of the following access flags can be specified in addition to the STANDARD_RIGHTS_REQUIRED access flags:

Access	Description
PROCESS_CREATE_PROCESS	Used internally.
PROCESS_CREATE_THREAD	Enables using the process handle in the CreateRemoteThread function to create a thread in the process.
PROCESS_DUP_HANDLE	Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.
PROCESS_QUERY_INFORMATION	Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.
PROCESS_SET_INFORMATION	Enables using the process handle in the SetPriorityClass function to set the process's priority class.
PROCESS_TERMINATE	Enables using the process handle in the TerminateProcess function to terminate the process.
PROCESS_VM_OPERATION	Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.
PROCESS_VM_READ	Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process.
PROCESS_VM_WRITE	Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process.
SYNCHRONIZE	Enables using the process handle in any of the wait functions to wait for the process to terminate.
PROCESS_ALL_ACCESS	Specifies all possible access flags for the process object.
fInherit

Specifies whether the returned handle can be inherited by a new process created by the current process. If TRUE, the handle is inheritable.

IDProcess

Specifies the process identifier of the process to open.

Return Value

If the function succeeds, the return value is an open handle of the specified process; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The handle returned by the OpenProcess function can be used in any function that requires a handle to a process, provided the appropriate access rights were requested.

See Also

»CreateProcess«, »GetCurrentProcess«, »GetCurrentProcessId«


  OpenProcessToken

BOOL OpenProcessToken(hProcess, dwAccessMask, phToken)
HANDLE  hProcess;   /* handle of process */
DWORD  dwAccessMask;   /* desired access to process */
PHANDLE  phToken;   /* address of handle of open access token */

The OpenProcessToken function opens the access token associated with a process.

Parameters

hProcess

Identifies the process whose access token is opened.

dwAccessMask

Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the token's discretionary access-control list (ACL) to determine which accesses are granted or denied. The following access rights have been defined for access tokens.

Value	Meaning
TOKEN_ADJUST_DEFAULT
	Required to change the default ACL, primary group, or owner of an access token.
TOKEN_ADJUST_GROUPS
	Required to change the groups specified in an access token.
TOKEN_ADJUST_PRIVILEGES
	Required to change the privileges specified in an access token.
TOKEN_ALL_ACCESS
	Combines the STANDARD_RIGHTS_REQUIRED standard access rights and all individual access rights for tokens.
TOKEN_ASSIGN_PRIMARY
	Required to attach a primary token to a process in addition to the SE_CREATE_TOKEN_NAME privilege.
TOKEN_DUPLICATE
	Required to duplicate an access token.
TOKEN_EXECUTE
	Combines the STANDARD_RIGHTS_EXECUTE standard access rights and the TOKEN_IMPERSONATE access right.
TOKEN_IMPERSONATE
	Required to attach an impersonation access token to a process.
TOKEN_QUERY
	Required to query the contents of an access token.
TOKEN_QUERY_SOURCE
	Required to query the source of an access token.
TOKEN_READ
	Combines the STANDARD_RIGHTS_READ standard access rights and the TOKEN_QUERY access right.
TOKEN_WRITE
	Combines the STANDARD_RIGHTS_WRITE standard access rights and the TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT access rights.
phToken

Points to a handle identifying the newly-opened access token when the function returns.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AdjustTokenGroups«, »AdjustTokenPrivileges«, »GetTokenInformation«, »OpenThreadToken«, »SetTokenInformation«


  OpenProfileUserMapping

BOOL OpenProfileUserMapping(VOID)

The OpenProfileUserMapping function opens the HKEY_CURRENT_USER registry key that is associated with initialization-file mapping stored under the HKEY_LOCAL_MACHINE key.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application calls this function to gain access to any initialization data that is mapped to some location under the HKEY_CURRENT_USER key. (Typically, access has first been denied by calling the CloseProfileUserMapping function.) The OpenProfileUserMapping function is used by applications that impersonate clients and that must be able to change the mapping of initialization files.

Calls to functions that read data from or write data to initialization files may be mapped to the registry instead of to the specified files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

See Also

»CloseProfileUserMapping«


  OpenSCManager

SC_HANDLE OpenSCManager(lpszMachineName, lpszDatabaseName, fdwDesiredAccess)
LPTSTR  lpszMachineName;   /* address of machine name string */
LPTSTR  lpszDatabaseName;   /* address of database name string  */
DWORD  fdwDesiredAccess;   /* type of access */

The OpenSCManager function establishes a connection to the service control manager on the specified machine and opens the specified database.

Parameters

lpszMachineName

Points to a null-terminated string that names the target machine. If the pointer is NULL or if it points to an empty string, the function connects to the service control manager on the local machine.

lpszDatabaseName

Points to a null-terminated string that names the service control manager database to open. This string should specify ServicesActive. If the pointer is NULL, the ServicesActive database is opened by default.

fdwDesiredAccess

Specifies the access to the service control manager. Before granting the requested access, the system checks the access token of the calling process against the discretionary access-control list of the security descriptor associated with the service control manager object. The SC_MANAGER_CONNECT access type is implicitly specified by calling this function. In addition, any or all of the following service control manager object access types can be specified:

Type	Description
SC_MANAGER_ALL_ACCESS
	Includes STANDARD_RIGHTS_REQUIRED in addition to all of the access types listed in this table.
SC_MANAGER_CONNECT
	Enables connecting to the service control manager.
SC_MANAGER_CREATE_SERVICE
	Enables calling of the CreateService function to create a service object and add it to the database.
SC_MANAGER_ENUMERATE_SERVICE
	Enables calling of the EnumServicesStatus function to list the services that are in the database.
SC_MANAGER_LOCK
	Enables calling of the LockServiceDatabase function to acquire a lock on the database.
SC_MANAGER_QUERY_LOCK_STATUS
	Enables calling of the QueryServiceLockStatus function to retrieve the lock status information for the database.
The fdwDesiredAccess parameter can specify any or all of the following generic access types:

Generic access	Service manager access
GENERIC_READ	Combines the following access: STANDARD_RIGHTS_READ, SC_MANAGER_ENUMERATE_SERVICE, and SC_MANAGER_QUERY_LOCK_STATUS.
GENERIC_WRITE	Combines the following access: STANDARD_RIGHTS_WRITE, SC_MANAGER_CREATE_SERVICE, and SC_MANAGER_MODIFY_BOOT_CONFIG.
GENERIC_EXECUTE	Combines the following access: STANDARD_RIGHTS_EXECUTE, SC_MANAGER_CONNECT, and SC_MANAGER_LOCK.
Return Value

If the function succeeds, the return value is a handle to the specified service control manager database; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Error	Meaning
ERROR_ACCESS_DENIED	The requested access was denied.
ERROR_DATABASE_DOES_NOT_EXIST	The specified database does not exist.
ERROR_INVALID_PARAMETER	A parameter that was specified is invalid.
Comments

When a process uses the OpenSCManager function to open a handle to a service control manager database, the system performs a security check before granting the requested access. All processes are permitted SC_MANAGER_CONNECT, SC_MANAGER_ENUMERATE_SERVICE, and SC_MANAGER_QUERY_LOCK_STATUS access to all service control manager databases. This enables any process to open a service control manager database handle that it can use in the OpenService, EnumServicesStatus, and QueryServiceLockStatus functions. Only processes with Administrator privileges are able to open a database handle used by the CreateService and LockServiceDatabase functions.

The calling process can use the returned handle to identify the database in the following functions, if the appropriate access rights are enabled:

CreateService
EnumServicesStatus
LockServiceDatabase
OpenService
QueryServiceLockStatus

The returned handle is only valid for the process that called OpenSCManager. It can be closed by calling the CloseServiceHandle function.

See Also

»CloseServiceHandle«, »CreateService«, »EnumServicesStatus«, »LockServiceDatabase«, »OpenService«, »QueryServiceLockStatus«


  OpenSemaphore

HANDLE OpenSemaphore(fdwAccess, fInherit, lpszSemName)
DWORD  fdwAccess;   /* access flag */
BOOL  fInherit;   /* inherit flag */
LPTSTR  lpszSemName;   /* address of semaphore-object name */

The OpenSemaphore function returns a handle of an existing named semaphore object.

Parameters

fdwAccess

Specifies the requested access to the semaphore object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:

Access	Description
SEMAPHORE_MODIFY_STATE	Enables use of the semaphore handle in the ReleaseSemaphore function to modify the semaphore's count.
SYNCHRONIZE	Enables use of the semaphore handle in any of the wait functions to wait for the semaphore's state to be signaled.
SEMAPHORE_ALL_ACCESS	Specifies all possible access flags for the semaphore object.
fInherit

Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.

lpszSemName

Points to a null-terminated string that names the semaphore to be opened. Name comparisons are case sensitive.

Return Value

If the function succeeds, the return value is a handle of the semaphore object; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The OpenSemaphore function enables multiple processes to open handles of the same semaphore object. The function succeeds only if some process has already created the semaphore by using the CreateSemaphore function. The calling process can use the returned handle in any function that requires a handle of a semaphore object, subject to the limitations of the access specified in the fdwAccess parameter.

The handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The semaphore object is destroyed when its last handle has been closed.

See Also

»CloseHandle«, »CreateSemaphore«, »DuplicateHandle«, »MsgWaitForMultipleObjects«, »ReleaseSemaphore«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  OpenService

SC_HANDLE OpenService(schSCManager, lpszServiceName, fdwDesiredAccess)
SC_HANDLE  schSCManager;   /* handle of service control manager database */
LPCTSTR  lpszServiceName;   /* address of name of service to start  */
DWORD  fdwDesiredAccess;   /* type of access to service */

The OpenService function opens a handle to an existing service.

Parameters

schSCManager

Identifies the service control manager database. The OpenSCManager function returns this handle.

lpszServiceName

Points to a null-terminated string that names the service to open. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. A forward-slash (/), back-slash (\), comma, and space are invalid service name characters.

fdwDesiredAccess

Specifies the access to the service. Before granting the requested access, the system checks the access token of the calling process against the discretionary access-control list of the security descriptor associated with the service object. Any or all of the following service object access types can be specified:

Access	Description
SERVICE_ALL_ACCESS
	Includes STANDARD_RIGHTS_REQUIRED in addition to all of the access types listed in this table.
SERVICE_CHANGE_CONFIG
	Enables calling of the ChangeServiceConfig function to change the service configuration.
SERVICE_ENUMERATE_DEPENDENTS
	Enables calling of the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_INTERROGATE
	Enables calling of the ControlService function to ask the service to report its status immediately.
SERVICE_PAUSE_CONTINUE
	Enables calling of the ControlService function to pause or continue the service.
SERVICE_QUERY_CONFIG
	Enables calling of the QueryServiceConfig function to query the service configuration.
SERVICE_QUERY_STATUS
	Enables calling of the QueryServiceStatus function to ask the service control manager about the status of the service.
SERVICE_START
	Enables calling of the StartService function to start the service.
SERVICE_STOP
	Enables calling of the ControlService function to stop the service.
SERVICE_USER_DEFINE_CONTROL
	Enables calling of the ControlService function to specify a user-defined control code.
STANDARD_RIGHTS_REQUIRED enables the following service object access types:

Standard rights	Description
DELETE	Enables calling of the DeleteService function to delete the service.
READ_CONTROL	Enables calling of the QueryServiceObjectSecurity function to query the security descriptor of the service object.
WRITE_DAC|WRITE_OWNER	Enables calling of the SetServiceObjectSecurity function to modify the security descriptor of the service object.
The fdwDesiredAccess parameter can specify any or all of the following generic access types:

Generic access	Service access
GENERIC_READ	Combines the following access: STANDARD_RIGHTS_READ, SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, and SERVICE_ENUMERATE_DEPENDENTS.
GENERIC_WRITE	Combines the following access: STANDARD_RIGHTS_WRITE and SERVICE_CHANGE_CONFIG.
GENERIC_EXECUTE	Combines the following access: STANDARD_RIGHTS_EXECUTE, SERVICE_START, SERVICE_STOP, SERVICE_PAUSE_CONTINUE, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL.
Return Value

If the function succeeds, the return value is a handle to the service; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Errors

The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED	The specified service control manager database handle does not have access to the service.
ERROR_INVALID_HANDLE	The specified handle is invalid.
ERROR_INVALID_NAME	The specified service name is invalid.
ERROR_SERVICE_DOES_NOT_EXIST	The specified service does not exist.
Comments

The calling process can use the returned handle to identify the service in the following functions, if the appropriate access rights are enabled:

ChangeServiceConfig
ControlService
DeleteService
EnumDependentServices
QueryServiceConfig
QueryServiceObjectSecurity
QueryServiceStatus
SetServiceObjectSecurity
StartService

The returned handle is only valid for the process that called OpenService. It can be closed by calling the CloseServiceHandle function.

See Also

»ChangeServiceConfig«, »ControlService«, »CreateService«, »DeleteService«, »EnumDependentServices«, »OpenSCManager«, »QueryServiceConfig«, »QueryServiceObjectSecurity«, »QueryServiceStatus«, »SetServiceObjectSecurity«, »StartService«


  OpenSound

The OpenSound function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  OpenThreadToken

BOOL OpenThreadToken(hThread, dwAccessMask, fOpenAsSelf, phToken)
HANDLE  hThread;   /* handle of thread */
DWORD  dwAccessMask;   /* access to process */
BOOL  fOpenAsSelf;   /* flag for process or thread security */
PHANDLE  phToken;   /* address of handle of open access token */

The OpenThreadToken function opens the access token associated with a thread.

Parameters

hThread

Identifies the thread whose access token is opened.

dwAccessMask

Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the token's discretionary access-control list (ACL) to determine which accesses are granted or denied. The following access rights have been defined for access tokens.

Value	Meaning
TOKEN_ADJUST_DEFAULT
	Required to change the default ACL, primary group, or owner of an access token.
TOKEN_ADJUST_GROUPS
	Required to change the groups specified in an access token.
TOKEN_ADJUST_PRIVILEGES
	Required to change the privileges specified in an access token.
TOKEN_ALL_ACCESS
	Combines the STANDARD_RIGHTS_REQUIRED standard access rights and all individual access rights for tokens.
TOKEN_ASSIGN_PRIMARY
	Required to attach a primary token to a process in addition to the SE_CREATE_TOKEN_NAME privilege.
TOKEN_DUPLICATE
	Required to duplicate an access token.
TOKEN_EXECUTE
	Combines the STANDARD_RIGHTS_EXECUTE standard access rights and the TOKEN_IMPERSONATE access right.
TOKEN_IMPERSONATE
	Required to attach an impersonation access token to a process.
TOKEN_QUERY
	Required to query the contents of an access token.
TOKEN_QUERY_SOURCE
	Required to query the source of an access token.
TOKEN_READ
	Combines the STANDARD_RIGHTS_READ standard access rights and the TOKEN_QUERY access right.
TOKEN_WRITE
	Combines the STANDARD_RIGHTS_WRITE standard access rights and the TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT access rights.
fOpenAsSelf

Specifies a flag indicating whether the access check is to be made against the security context of the thread calling the OpenThreadToken function or against the security context of the process for the calling thread.

If this parameter is FALSE, the access check is performed using the security context for the calling thread. If the thread is impersonating a client, this security context can be that of a client process. If this parameter is TRUE, the access check is made using the security context of the process for the calling thread.

phToken

Points to a handle identifying the newly-opened access token when the function returns.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The fOpenAsSelf parameter allows a server process to open the access token for a client process when the client process has specified the SecurityIdentification impersonation level for the SECURITY_IMPERSONATION_LEVEL enumerated type. Without this parameter, the calling process is not be able to open the client's access token using the client's security context, because it is impossible to open executive-level objects using the SecurityIdentification impersonation level.

See Also

»AdjustTokenGroups«, »AdjustTokenPrivileges«, »GetTokenInformation«, »OpenProcessToken«, »SetTokenInformation«


  OutputDebugString

VOID OutputDebugString(lpszOutputString)
LPCTSTR  lpszOutputString;   /* address of string to be displayed */

The OutputDebugString function sends a string to the debugger for the current application.

Parameters

lpszOutputString

Points to the null-terminated string to be displayed.

Return Value

This function does not return a value.

Comments

If the application has no debugger, the system debugger displays the string. If the application has no debugger and the system debugger is not active, this function does nothing.


  OutputProc

BOOL CALLBACK OutputProc(hdc, lpData, cchData)
HDC  hdc;   /* handle of device context */
LPARAM  lpData;   /* address of string to be drawn  */
int  cchData;   /* length of string to be drawn */

The OutputProc function is an application-defined callback function that draws a string as a result of a call to the GrayString function.

Parameters

hdc

Identifies a device context with a bitmap of at least the width and height specified by the nWidth and nHeight parameters passed to GrayString.

lpData

Points to the string to be drawn.

cchData

Specifies the length, in characters, of the string.

Return Value

If it succeeds, the callback function should return TRUE; otherwise, it should return FALSE.

Comments

The callback function must draw an image relative to the coordinates (0,0).

OutputProc is a placeholder for the application-defined function name.

See Also

»GrayString«


  PackDDElParam

LONG PackDDElParam(uMsg, uLow, uHigh)
UINT  uMsg;   /* DDE message to be posted */
UINT  uLow;   /* low-order word of lParam of message */
UINT  uHigh;   /* high-order word of lParam of message */

The PackDDElParam function packs a dynamic data exchange (DDE) lParam value into an internal structure used for sharing DDE data between processes.

Parameters

uMsg

Specifies the DDE message to be posted.

uLow

Specifies a value that corresponds to the Windows 3.x low-order word of an lParam parameter for the DDE message being posted.

uHigh

Specifies a value that corresponds to the Windows 3.x high-order word of an lParam parameter for the DDE message being posted.

Return Value

If the function succeeds, the return value is nonzero; otherwise, it is zero.

Comments

The return value must be posted as the lParam parameter of a DDE message; it must not be used for any other purpose. Once the application posts a return value, it need not perform any action to dispose of the lParam parameter.

The PackDDElParam function eases the porting of 16-bit DDE applications to 32-bit DDE applications.

An application should call this function only for posted DDE messages.

See Also

»FreeDDElParam«, »ReuseDDElParam«, »UnpackDDElParam«


  PaintRgn

BOOL PaintRgn(hdc, hrgn)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region to be painted */

The PaintRgn function paints the given region by using the brush currently selected into the device context.

Parameters

hdc

Identifies the device context.

hrgn

Identifies the region to be filled. The region's coordinates are presumed to be logical coordinates.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»FillRgn«


  PatBlt

BOOL PatBlt(hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop)
HDC  hdc;   /* handle of device context */
int  nXLeft;   /* x-coord. of upper left corner of rect. to be filled */
int  nYLeft;   /* y-coord. of upper left corner of rect. to be filled */
int  nWidth;   /* width of rectangle to be filled */
int  nHeight;   /* height of rectangle to be filled */
DWORD  dwRop;   /* raster operation code */

The PatBlt function paints the given rectangle using the brush that is currently selected into the given device context. The brush color and the surface color(s) are combined by using the given raster operation.

Parameters

hdc

Identifies the device context.

nXLeft

Specifies the x-coordinate, in logical units, of the upper left corner of the rectangle to be filled.

nYLeft

Specifies the y-coordinate, in logical units, of the upper left corner of the rectangle to be filled.

nWidth

Specifies the width, in logical units, of the rectangle.

nHeight

Specifies the height, in logical units, of the rectangle.

dwRop

Specifies the raster operation code. This code may be one of the following values:

Value	Meaning
PATCOPY	Copies the specified pattern into the destination bitmap.
PATINVERT	Combines the colors of the specified pattern with the colors of the destination rectangle by using the Boolean OR operator.
DSTINVERT	Inverts the destination rectangle.
BLACKNESS	Fills the destination rectangle using the color associated with index 0 in the physical palette. (This color is black for the default physical palette.)
WHITENESS	Fills the destination rectangle using the color associated with index 1 in the physical palette. (This color is white for the default physical palette.)
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The values of the dwRop parameter for this function are a limited subset of the full 256 ternary raster-operation codes; in particular, an operation code that refers to a source rectangle cannot be used.

Not all devices support the PatBlt function. For more information, see the description of the RC_BITBLT capability in the »GetDeviceCaps« function.

See Also

»GetDeviceCaps«


  PathToRegion

HRGN PathToRegion(hdc)
HDC  hdc;   /* handle of device context */

The PathToRegion function creates a region from the path that is selected into the given device context.

Parameters

hdc

Identifies a device context that contains a closed path.

Return Value

If the function succeeds, the return value identifies a valid region; otherwise, it is zero. Use the GetLastError function to get the error value, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

Comments

The device context identified by the hdc parameter must contain a closed path.

After PathToRegion converts a path into a region, Windows discards the closed path from the given device context.

See Also

»BeginPath«, »EndPath« »SetPolyFillMode«,


  PeekConsoleInput

BOOL PeekConsoleInput(hConsoleInput, pirBuffer, cInRecords, lpcRead)
HANDLE  hConsoleInput;   /* handle of a console input buffer */
PINPUT_RECORD  pirBuffer;   /* address of the buffer for peek data */
DWORD  cInRecords;   /* number of records to read */
LPDWORD  lpcRead;   /* address of number of records read */

The PeekConsoleInput function reads data from the specified console input buffer without removing it from the buffer.

Parameters

hConsoleInput

Identifies the input buffer. The handle must have GENERIC_READ access.

pirBuffer

Points to an INPUT_RECORD buffer to receive the input buffer data. The INPUT_RECORD structure has the following form:

typedef struct _INPUT_RECORD { /* ir */

    WORD EventType;

    union {

        KEY_EVENT_RECORD KeyEvent;

        MOUSE_EVENT_RECORD MouseEvent;

        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;

        MENU_EVENT_RECORD MenuEvent;

        FOCUS_EVENT_RECORD FocusEvent;

    } Event;

} INPUT_RECORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cInRecords

Specifies the size, in records, of the buffer pointed to by the pirBuffer parameter.

lpcRead

Points to a 32-bit variable to receive the number of input records read.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of records requested exceeds the number of records available in the buffer, the number available is read. If no data is available, the function returns immediately.

See Also

»ReadConsoleInput«, »WriteConsoleInput«


  PeekMessage

BOOL PeekMessage(lpmsg, hwnd, uMsgFilterMin, uMsgFilterMax, fuRemoveMsg)
LPMSG  lpmsg;   /* address of structure for message */
HWND  hwnd;   /* handle of window */
UINT  uMsgFilterMin;   /* first message */
UINT  uMsgFilterMax;   /* last message */
UINT  fuRemoveMsg;   /* removal flags */

The PeekMessage function checks a thread message queue for a message and places the message (if any) in the specified structure.

Parameters

lpmsg

Points to an MSG structure that contains message information from the Windows application queue. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hwnd

Identifies the window whose messages are to be examined.

uMsgFilterMin

Specifies the value of the first message in the range of messages to be examined.

uMsgFilterMax

Specifies the value of the last message in the range of messages to be examined.

fuRemoveMsg

Specifies whether the message should be removed from the queue. This parameter must be one of the following values:

Value	Meaning
PM_NOREMOVE	The message is not removed from the queue after processing by PeekMessage.
PM_REMOVE	The message is removed from the queue after processing by PeekMessage.
Return Value

If a message is available, the return value is TRUE; otherwise, it is FALSE.

Comments

Unlike the GetMessage function, the PeekMessage function does not wait for a message to be placed in the queue before returning.

PeekMessage retrieves only messages associated with the window identified by the hwnd parameter or any of its children as specified by the IsChild function, and within the range of message values given by the uMsgFilterMin and uMsgFilterMax parameters. If hwnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread making the call. (PeekMessage does not retrieve messages for windows that belong to other threads.) If hwnd is −1, PeekMessage only returns messages with a hwnd value of NULL, as posted by the PostAppMessage function. If uMsgFilterMin and uMsgFilterMax are both zero, PeekMessage returns all available messages (no range filtering is performed).

The WM_KEYFIRST and WM_KEYLAST flags can be used as filter values to retrieve all keyboard messages; the WM_MOUSEFIRST and WM_MOUSELAST flags can be used to retrieve all mouse messages.

PeekMessage does not remove WM_PAINT messages from the queue. The messages remain in the queue until they are processed.

See Also

»GetMessage«, »IsChild«, »PostAppMessage«, »WaitMessage«


  PeekNamedPipe

BOOL PeekNamedPipe(hPipe, lpvBuffer, cbBuffer, lpcbRead, lpcbAvail, lpcbMessage)
HANDLE  hPipe;   /* handle of pipe to copy from */
LPVOID  lpvBuffer;   /* address of data buffer */
DWORD  cbBuffer;   /* size in bytes of data buffer */
LPDWORD  lpcbRead;   /* address of number of bytes read */
LPDWORD  lpcbAvail;   /* address of total number of bytes available */
LPDWORD  lpcbMessage;   /* address of unread bytes in this message */

The PeekNamedPipe function copies data from a named or anonymous pipe into a buffer, without removing it from the pipe. It also returns information about data in the pipe.

Parameters

hPipe

Identifies the pipe. This can be a handle to a named pipe instance, as returned by CreateNamedPipe or CreateFile, or it can be a handle to the read end of an anonymous pipe, as returned by CreatePipe. The handle must have GENERIC_READ access to the pipe.

lpvBuffer

Points to a buffer to receive data read from the pipe. Set this parameter to NULL if no data is to be read.

cbBuffer

Specifies the size, in bytes, of the buffer at lpvBuffer. This parameter is ignored if lpvBuffer is NULL.

lpcbRead

Points to a 32-bit variable that will receive the number of bytes read from the pipe. Set this parameter to NULL if no data is to be read.

lpcbAvail

Points to a 32-bit variable that will receive the total number of bytes available to be read from the pipe. Set this parameter to NULL if this information is not required.

lpcbMessage

Points to a 32-bit variable that will receive the number of bytes remaining in this message. This will be zero for byte-type named pipes or for anonymous pipes. Set this parameter to NULL if this information is not required.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The PeekNamedPipe function is similar to the ReadFile function, with the following exceptions:

•	The data read from the pipe is not removed from the pipe's buffer.

•	The function always returns immediately, even if there is no data in the pipe. The wait mode of a named pipe handle (blocking or nonblocking) has no effect on the function.

•	The function can return additional information about the contents of the pipe.

If the specified handle is a named pipe handle in byte-read mode, the function reads all available bytes up to the size specified in cbBuffer. For a named pipe handle in message-read mode, the function reads the next message in the pipe. If the message is larger than cbBuffer, the function returns TRUE after reading the specified number of bytes. In this situation, lpcbMessage will receive the number of bytes remaining in the message.

See Also

»CreateFile«, »CreateNamedPipe«, »CreatePipe«, »ReadFile«, »WriteFile«


  Pie

BOOL Pie(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect, nXRadial1, nYRadial1,
nXRadial2, nYRadial2)
HDC  hdc;
int  nLeftRect;   /* x-coord. of bounding rect. upper-left corner */
int  nTopRect;   /* y-coord. of bounding rect. upper-left corner */
int  nRightRect;   /* x-coord. of bounding rect. lower-right corner */
int  nBottomRect;   /* y-coord. of bounding rect. lower-right corner */
int  nXRadial1;   /* x-coord. of first radial's endpoint */
int  nYRadial1;   /* y-coord. of first radial's endpoint */
int  nXRadial2;   /* x-coord. of second radial's endpoint */
int  nYRadial2;   /* y-coord. of second radial's endpoint */

The Pie function draws a pie-shaped wedge bounded by the intersection of an ellipse and two radials. The pie is outlined by using the current pen and filled by using the current brush.

Parameters

hdc

Identifies the device context.

nLeftRect

Specifies the x-coordinate of the upper-left corner of the bounding rectangle.

nTopRect

Specifies the y-coordinate of the upper-left corner of the bounding rectangle.

nRightRect

Specifies the x-coordinate of the lower-right corner of the bounding rectangle.

nBottomRect

Specifies the y-coordinate of the lower-right corner of the bounding rectangle.

nXRadial1

Specifies the x-coordinate of the endpoint of the first radial.

nYRadial1

Specifies the y-coordinate of the endpoint of the first radial.

nXRadial2

Specifies the x-coordinate of the endpoint of the second radial.

nYRadial2

Specifies the y-coordinate of the endpoint of the second radial.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The curve of the pie is defined by an ellipse that fits the specified bounding rectangle. The curve begins at the point where the ellipse intersects the first radial and extends counterclockwise to the point where the ellipse intersects the second radial. (A radial is a line drawn from the center of the ellipse to the specified endpoint on the ellipse.)

The current position is neither used nor updated by this function.

See Also

»AngleArc«, »Arc«, »ArcTo«, »Chord«


  PlayEnhMetaFile

BOOL PlayEnhMetaFile(hdc, hemf, lpRect)
HDC  hdc;   /* handle of a device context */
HENHMETAFILE  hemf;   /* handle of an enhanced metafile  */
LPRECT  lpRect;   /* address of bounding rectangle */

The PlayEnhMetaFile function displays the picture stored in the given enhanced-format metafile.

Parameters

hdc

Identifies the device context for the output device on which the picture will appear.

hemf

Identifies the enhanced metafile.

lpRect

Points to a RECT structure that contains the coordinates of the bounding rectangle used to display the picture. The coordinates are specified in logical units.

The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When an application calls the PlayEnhMetaFile function, Windows uses the picture frame in the enhanced-metafile header to map the picture onto the rectangle pointed to by the lpRect parameter. (This picture may be sheared or rotated by setting the world transform in the output device before calling PlayEnhMetaFile.) Points along the edges of the rectangle are included in the picture.

An enhanced metafile picture can be clipped by defining the clipping region in the output device before playing the enhanced metafile.

If an enhanced metafile contains an optional palette, an application can achieve consistent colors by setting up a color palette on the output device before calling PlayEnhMetaFile. To retrieve the optional palette, use the GetEnhMetaFilePaletteEntries function.

An enhanced metafile can be embedded in a newly created enhanced metafile by calling PlayEnhMetaFile and playing the source enhanced metafile into the device context for the new enhanced metafile.

The states of the output device context are preserved by this function. Any object created but not deleted in the enhanced metafile is deleted by this function.

To stop this function, an application can call the CancelDC function from another thread to terminate the operation. In this case, the function returns FALSE.

See Also

»CancelDC«, »GetEnhMetaFileHeader«, »GetEnhMetaFilePaletteEntries«, »SetWorldTransform«


  PlayEnhMetaFileRecord

BOOL PlayEnhMetaFileRecord(hdc, lpHandletable, lpEnhMetaRecord, nHandles)
HDC  hdc;   /* handle of device context */
LPHANDLETABLE  lpHandletable;   /* address of metafile handle table */
LPENHMETARECORD  lpEnhMetaRecord;   /* address of metafile record  */
UINT  nHandles;   /* count of handles */

The PlayEnhMetaFileRecord function plays an enhanced-metafile record by executing the graphics device interface (GDI) functions identified by the record.

Parameters

hdc

Identifies the device context passed to the EnumEnhMetaFile function.

lpHandletable

Points to a table of handles identifying GDI objects used when playing the metafile. The first entry in this table contains the enhanced-metafile handle.

lpEnhMetaRecord

Points to the enhanced-metafile record to be played.

nHandles

Specifies the number of handles in the handle table.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This is an enhanced-metafile function.

An application typically uses PlayEnhMetaFileRecord in conjunction with the EnumEnhMetaFile function to process and play an enhanced-format metafile one record at a time.

The hdc, lpHandletable, and nHandles parameters must be exactly those passed to the EnhMetaFileProc callback procedure by the EnumEnhMetaFile function.

If PlayEnhMetaFileRecord does not recognize a record, it ignores the record and returns TRUE.

See Also

»EnumEnhMetaFile«, »PlayEnhMetaFile«


  PlayMetaFile

BOOL PlayMetaFile(hdc, hmf)
HDC  hdc;   /* handle of the device context */
HMETAFILE  hmf;   /* handle of the metafile */

The PlayMetaFile function displays the picture stored in the given Windows-format metafile on the specified device.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the PlayEnhMetaFile function.

Parameters

hdc

Identifies a device context.

hmf

Identifies a Windows-format metafile.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should use the enhanced-format metafile functions.

To convert a Windows-format metafile into an enhanced format metafile, use the SetWinMetaFileBits function.

A Windows-format metafile can be played multiple times.

A Windows-format metafile can be embedded in a second Windows-format metafile by calling the PlayMetaFile function and playing the source metafile into the device context for the target metafile.

Any object created but not deleted in the Windows-format metafile is deleted by this function.

To stop this function, an application can call the CancelDC function from another thread to terminate the operation. In this case, the function returns FALSE.

See Also

»BeginPath«, »CancelDC«, »PolyBezier«, »SetWinMetaFileBits«, »SetWorldTransform«


  PlayMetaFileRecord

BOOL PlayMetaFileRecord(hdc, lpHandletable, lpMetaRecord, nHandles)
HDC  hdc;   /* handle of device context */
LPHANDLETABLE  lpHandletable;   /* address of metafile handle table */
LPMETARECORD  lpMetaRecord;   /* address of metafile record  */
UINT  nHandles;   /* count of handles */

The PlayMetaFileRecord function plays a Windows-format metafile record by executing the graphics device interface (GDI) function contained within that record.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the PlayEnhMetaFileRecord function.

Parameters

hdc

Identifies a device context.

lpHandletable

Points to a table of handles identifying GDI objects used when playing the metafile.

lpMetaRecord

Points to the Windows-format metafile record.

nHandles

Specifies the number of handles in the handle table.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions, such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions, should use the enhanced format metafile functions.

To convert a Windows-format metafile into an enhanced-format metafile, use the SetWinMetaFileBits function.

An application typically uses PlayMetaFileRecord in conjunction with the EnumMetaFile function to process and play a Windows-format metafile one record at a time.

The lpHandletable and nHandles parameters must be identical to those passed to the EnumMetaFileProc callback procedure by EnumMetaFile.

If the PlayMetaFileRecord function does not recognize a record, it ignores the record and returns TRUE.

See Also

»BeginPath«, »EnumMetaFile«, »PlayMetaFile«, »PolyBezier«, »SetWinMetaFileBits«, »SetWorldTransform«


  PlaySound

BOOL PlaySound(lpszName, hModule, fdwSound)
LPCTSTR  lpszName;   /* sound string */
HANDLE  hModule;   /* sound resource  */
DWORD  fdwSound;   /* sound type */

The PlaySound function plays a waveform sound.

Parameters

lpszName

Points to a null-terminated string that specifies the name of the resource, file, or registry entry for the sound to be played.

hModule

Identifies the module from which the resource is to be loaded if the lpszName parameter specifies the name of a resource.

fdwSound

Specifies the nature of the lpszName parameter and how the sound should be played. This parameter can be a combination of the following values (except as noted):

fdwSound	Meaning
SND_ALIAS	The lpszName parameter specifies an entry in the [sounds] section of the registry, of the form: alias=path. Do not use with either SND_FILENAME or SND_RESOURCE.
SND_ASYNC	The sound should be played asynchronously. The call to PlaySound returns as soon as the sound is started. Do not use with SND_SYNC.
SND_FILENAME	The lpszName parameter specifies the name of a wave file. Do not use with either SND_ALIAS or SND_RESOURCE.
SND_NODEFAULT	The default system sound should not be played if the alias supplied by the lpszName parameter cannot be found. Can be used with SND_ALIAS.
SND_NOWAIT	The call to PlaySound is to fail if no suitable wave device is available to play the sound.
SND_RESOURCE	The lpszName parameter specifies the name of a resource. Do not use with either SND_ALIAS or SND_FILENAME.
SND_SYNC	The sound should be played synchronously. The call to PlaySound does not return until the sound has finished playing. Do not use with SND_ASYNC.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When playing a sound specified by an alias name from the registry, the default action is to search for the given name and, if it is not found, to search for the SystemDefault entry and play that sound. If the application does not want the default sound to be played, it can set the SND_NODEFAULT flag.

The function can play wave resources from a module, from wave files named explicitly, or from wave files specified by entries in the [sounds] section of the registry.

If the SND_ASYNC flag is set, a return value of TRUE indicates only that the thread has started that will attempt to play the sound. There is no indication that the sound will actually be played.

The PlaySound function provides a simple mechanism to play wave files and wave files built into an application as resources of type WAVE.

See Also

»sndPlaySound«


  PlgBlt

BOOL PlgBlt(hdcDest, lpPoint, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hbmMask, xMask, yMask)
HDC  hdcDest;   /* handle of destination device context */
LPPOINT  lpPoint;   /* vertices of destination parallelogram */
HDC  hdcSrc;   /* handle of source device context */
int  nXSrc;   /* x-coord. of upper left corner of source rect. */
int  nYSrc;   /* y-coord. of upper left corner of source rect. */
int  nWidth;   /* width of source rectangle */
int  nHeight;   /* height of source rectangle */
HBITMAP  hbmMask;   /* handle of bitmask */
int  xMask;   /* x-coord. of upper left corner of bitmask rect. */
int  yMask;   /* y-coord. of upper left corner of bitmask rect. */

The PlgBlt function performs a bit-block transfer of the bits of color data from the specified rectangle in the source device context to the specified parallelogram in the destination device context. If the given bitmask handle identifies a valid monochrome bitmap, the function uses this bitmap to mask the bits of color data from the source rectangle.

Parameters

hdcDest

Identifies the destination device context.

lpPoint

Points to an array of three points in logical space that identify three corners of the destination parallelogram. The upper left corner of the source rectangle is mapped to the first point in this array, the upper right corner to the second point in this array, and the lower left corner to the third point. The lower right corner of the source rectangle is mapped to the implicit fourth point in the parallelogram.

hdcSrc

Identifies the source device context.

nXSrc

Specifies the x-coordinate, in logical units, of the upper left corner of the source rectangle.

nYSrc

Specifies the y-coordinate, in logical units, of the upper left corner of the source rectangle.

nWidth

Specifies the width, in logical units, of the source rectangle.

nHeight

Specifies the height, in logical units, of the source rectangle.

hbmMask

Identifies an optional monochrome bitmap that is used to mask the colors of the source rectangle.

xMask

Specifies the x-coordinate of the upper left corner of the the monochrome bitmap.

yMask

Specifies the y-coordinate of the upper left corner of the the monochrome bitmap.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The fourth vertex of the parallelogram (D) is defined by treating the first three points (A, B, and C) as vectors and computing D = B + C − A.

If the bitmask exists, a value of 1 in the mask indicates that the source pixel color should be copied to the destination. A value of 0 in the mask indicates that the destination pixel color is not to be changed.

If the mask rectangle is smaller than the source and destination rectangles, the function replicates the mask pattern.

Scaling, translation, and reflection transformations are allowed in the source device context; however, rotation and shear transformations are not.

If the mask bitmap is not a monochrome bitmap, an error occurs.

The stretching mode for the destination device context is used to determine how to stretch or compress the pixels, if that is necessary.

When an enhanced metafile is being recorded, an error occurs if the source device context identifies an enhanced-metafile device context.

The destination coordinates are transformed according to the destination device context; the source coordinates are transformed according to the source device context. If the source transformation has a rotation or shear, an error is returned.

If the destination and source rectangles do not have the same color format, PlgBlt converts the source rectangle to match the destination rectangle.

Not all devices support the PlgBlt function. For more information, see the description of the RC_BITBLT raster capability in the »GetDeviceCaps« function.

If the source and destination device contexts represent incompatible devices, PlgBlt returns an error.

See Also

»BitBlt«, »GetDeviceCaps«, »MaskBlt«, »SetStretchBltMode«, »StretchBlt«


  PolyBezier

BOOL PolyBezier(hdc, lppt, cPoints)
HDC  hdc;   /* handle of device context */
LPPOINT  lppt;   /* address of endpoints and control points */
DWORD  cPoints;   /* count of endpoints and control points */

The PolyBezier function draws one or more Bézier splines.

Parameters

hdc

Identifies a device context.

lppt

Points to an array of POINT structures that contain the endpoints and control points of the spline(s). The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cPoints

Specifies the number of points in the lppt array. This value must be one more than three times the number of splines to be drawn, because each Bézier spline requires two control points and an endpoint, and the initial spline requires an additional starting point.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function draws cubic Bézier splines by using the endpoints and control points specified by the lppt parameter. The first spline is drawn from the first point to the fourth point by using the second and third points as control points. Each subsequent spline in the sequence needs exactly three more points: the ending point of the previous spline is used as the starting point, the next two points in the sequence are control points, and the third is the ending point.

The current position is neither used nor updated by the PolyBezier function. The figure is not filled.

This function draws lines by using the current pen.

See Also

»MoveToEx«, »PolyBezierTo«


  PolyBezierTo

BOOL PolyBezierTo(hdc, lppt, cCount)
HDC  hdc;   /* handle of device context */
LPPOINT  lppt;   /* address of endpoints and control points */
DWORD  cCount;   /* count of endpoints and control points */

The PolyBezierTo function draws one or more Bézier splines.

Parameters

hdc

Identifies a device context.

lppt

Points to an array of POINT structures that contains the endpoints and control points. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cCount

Specifies the number of points in the lppt array. This value must be three times the number of splines to be drawn, because each Bézier spline requires two control points and an ending point.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function draws cubic Bézier splines by using the control points specified by the lppt parameter. The first spline is drawn from the current position to the third point by using the first two points as control points. For each subsequent spline, the function needs exactly three more points, and uses the ending point of the previous spline as the starting point for the next.

PolyBezierTo moves the current position to the ending point of the last Bézier spline. The figure is not filled.

This function draws lines by using the current pen.

See Also

»MoveToEx«, »PolyBezier«


  PolyDraw

BOOL PolyDraw(hdc, lppt, lpbTypes, cCount)
HDC  hdc;   /* handle of a device context */
LPPOINT  lppt;   /* address of array of points */
LPBYTE  lpbTypes;   /* address of line and curve identifiers  */
int  cCount;   /* count of points */

The PolyDraw function draws a set of line segments and Bézier splines.

Parameters

hdc

Identifies a device context.

lppt

Points to an array of POINT structures that contains the endpoints for each line segment and the endpoints and control points for each Bézier spline. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpbTypes

Points to an array that specifies how each point in the lppt array is used. Values can be one of the following:

Type	Meaning
PT_MOVETO	Specifies that this point starts a disjoint figure. This point becomes the new current position.
PT_LINETO	Specifies that a line is to be drawn from the current position to this point, which then becomes the new current position.
PT_BEZIERTO	Specifies that this point is a control point or ending point for a Bézier spline.
	PT_BEZIERTO types always occur in sets of three. The current position defines the starting point for the Bézier spline. The first two PT_BEZIERTO points are the control points, and the third PT_BEZIERTO point is the ending point. The ending point becomes the new current position. If there are not three consecutive PT_BEZIERTO points, an error results.
A PT_LINETO or PT_BEZIERTO type can be combined with the following constant by using the bitwise operator OR to indicate that the corresponding point is the last point in a figure and the figure is closed:

Type	Meaning
PT_CLOSEFIGURE	Specifies that the figure is automatically closed after the PT_LINETO or PT_BEZIERTO type for this point is done. A line is drawn from this point to the most recent PT_MOVETO or MoveTo point.
	This flag is combined with the PT_LINETO type for a line, or with the PT_BEZIERTO type of the ending point for a Bézier spline, by using the bitwise operator OR.
	The current position is set to the ending point of the closing line.
cCount

Specifies the total number of points in the lppt array, the same as the number of bytes in the lpbTypes array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

This function can be used in place of consecutive calls to MoveTo, LineTo, and PolyBezierTo functions to draw disjoint figures. The lines and splines are drawn using the current pen and figures are not filled. If there is an active path started by calling BeginPath, PolyDraw adds to the path.

The points contained in the lppt array and in lpbTypes indicate whether each point is part of a MoveTo, a LineTo, or part of a BezierTo operation. It is also possible to close figures.

This function updates the current position.

See Also

»BeginPath«, »EndPath«, »LineTo«, »MoveTo«, »PolyBezierTo«, »PolyLine«


  Polygon

BOOL Polygon(hdc, lpPoints, nCount)
HDC  hdc;   /* handle of device context */
CONST POINT  *lpPoints;   /* address of polygon's vertices  */
int  nCount;   /* count of polygon's vertices */

The Polygon function draws a polygon consisting of two or more vertices connected by straight lines. The polygon is outlined by using the current pen and filled by using the current brush and polygon fill mode.

Parameters

hdc

Identifies the device context.

lpPoints

Points to an array of POINT structures that specify the vertices of the polygon. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

nCount

Specifies the number of vertices in the array. This value must be greater than or equal to 2.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The polygon is closed automatically by drawing a line from the last vertex to the first.

The current position is neither used nor updated by this function.

See Also

»GetPolyFillMode«, »Polyline«, »PolylineTo«, »PolyPolygon«, »SetPolyFillMode«


  Polyline

BOOL Polyline(hdc, lppt, cPoints)
HDC  hdc;   /* handle of device context */
CONST POINT  *lppt;   /* address of array containing endpoints  */
int  cPoints;   /* number of points in the array */

The Polyline function draws a series of line segments by connecting the points in the given array.

Parameters

hdc

Identifies a device context.

lppt

Points to an array of POINT structures. Each structure in the array identifies a point in logical space. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cPoints

Specifies the number of points in the array. This number must be greater than or equal to two.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The lines are drawn from the first point through subsequent points by using the current pen. Unlike the LineTo function, the Polyline function neither uses nor updates the current position.

See Also

»LineTo«, »MoveToEx«, »PolylineTo«, »PolyPolyline«


  PolylineTo

BOOL PolylineTo(hdc, lppt, cCount)
HDC  hdc;   /* handle of device context */
LPPOINT  lppt;   /* address of array of points */
DWORD  cCount;   /* number of points in array */

The PolylineTo function draws one or more straight lines.

Parameters

hdc

Identifies the device context.

lppt

Points to an array of POINT structures that contains the vertices of the line. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cCount

Specifies the number of points in the array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

A line is drawn from the current position to the first point specified by the lppt parameter by using the current pen. For each additional line, the function draws from the ending point of the previous line to the next point specified by lppt.

PolylineTo moves the current position to the ending point of the last line.

If the line segments drawn by this function form a closed figure, the figure is not filled.

See Also

»LineTo«, »MoveToEx«, »Polyline«


  PolyPolygon

BOOL PolyPolygon(hdc, lpPoints, lpPolyCounts, nCount)
HDC  hdc;   /* handle of device context */
CONST POINT  *lpPoints;   /* address of vertices for all polygons */
LPINT  lpPolyCounts;   /* count of vertices for each polygon  */
int  nCount;   /* count of polygons */

The PolyPolygon function draws a series of closed polygons. Each polygon is outlined by using the current pen and filled by using the current brush and polygon fill mode. The polygons drawn by this function can overlap.

Parameters

hdc

Identifies the device context.

lpPoints

Points to an array of POINT structures that define the vertices of the polygons. The polygons are specified consecutively. Each polygon is closed automatically by drawing a line from the last vertex to the first. Each vertex should be specified once. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpPolyCounts

Points to an array of integers, each of which specifies the number of points in the corresponding polygon. Each integer must be greater than or equal to 2.

nCount

Specifies the total number of polygons.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The current position is neither used nor updated by this function.

See Also

»GetPolyFillMode«, »Polygon«, »Polyline«, »PolylineTo«, »SetPolyFillMode«


  PolyPolyline

BOOL PolyPolyline(hdc, lppt, lpdwPolyPoints, cCount)
HDC  hdc;   /* handle of a device context */
LPPOINT  lppt;   /* address of an array of points */
LPDWORD  lpdwPolyPoints;   /* address of an array of values  */
DWORD  cCount;   /* number of points in the first array */

The PolyPolyline function draws multiple series of connected line segments.

Parameters

hdc

Identifies the device context.

lppt

Points to an array of POINT structures that contains the vertices of the polylines. The polylines are specified consecutively. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpdwPolyPoints

Points to an array of variables specifying the number of points in the lppt array for the corresponding polygon. Each entry must be greater than or equal to two.

cCount

Specifies the total number of counts in the lpdwPolyPoints array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The line segments are drawn by using the current pen. The figures formed by the segments are not filled.

The current position is neither used nor updated by this function.

See Also

»Polyline«, »PolylineTo«


  PolyTextOut

BOOL PolyTextOut(hdc, pptxt, cStrings)
HDC  hdc;   /* handle of device context */
POLYTEXT  *pptxt;   /* address of array of structures that identify strings  */
int  cStrings;   /* number of structures in array */

The PolyTextOut function draws several strings using the font and text colors currently selected in the specified device context.

Parameters

hdc

Identifies the device context.

pptxt

Points to an array of POLYTEXT structures describing the strings to be drawn. The array contains one structure for each string to be drawn. The POLYTEXT structure has the following form:

typedef struct _POLYTEXT { /* ptxt */

    int   x;

    int   y;

    UINT  n;

    TCHAR *lpwstr;

    UINT  uiFlags;

    RECT  rcl;

    int   *pdx;

} POLYTEXT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cStrings

Specifies the number of POLYTEXT structures in the pptxt array.

Return Value

If the function is successful, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Each POLYTEXT structure contains the coordinates of a reference point that Windows uses to align the corresponding string of text. An application can specify how the reference point is used by calling the SetTextAlign function. An application can determine the current text-alignment setting for the specified device context by calling the GetTextAlign function.

To draw a single string of text, the application should call the ExtTextOut function.

See Also

»ExtTextOut«, »GetTextAlign«, »SetTextAlign«


  PostAppMessage

The PostAppMessage function is retained only for compatibility with earlier versions of Microsoft® Windows. For Win32 applications, use the PostThreadMessage function.

Comments

The PostAppMessage function used a process identifier as its first parameter, but its replacement, the PostThreadMessage function, uses a thread identifier as its first parameter.

See Also

»PostThreadMessage«


  PostMessage

BOOL PostMessage(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of destination window */
UINT  uMsg;   /* message to post */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The PostMessage function places (posts) a message in the message queue associated with the thread that created the given window and then returns without waiting for the thread to process the message. Messages in a message queue are retrieved by calls to the GetMessage or PeekMessage function.

Parameters

hwnd

Identifies the window whose window procedure is to receive the message. If this parameter is HWND_TOPMOST, the message is posted to all overlapped or pop-up windows in the system. The message is not posted to child windows.

uMsg

Specifies the message to be posted.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetMessage«, »PeekMessage«, »PostThreadMessage«, »SendDlgItemMessage«, »SendMessage«


  PostQuitMessage

VOID PostQuitMessage(nExitCode)
int  nExitCode;   /* exit code */

The PostQuitMessage function indicates to Windows that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.

Parameters

nExitCode

Specifies an application exit code. This code is used as the wParam parameter of the WM_QUIT message.

Return Value

This function does not return a value.

Comments

The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.

When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to Windows. The exit code returned to Windows must be the wParam parameter of the WM_QUIT message.

See Also

»GetMessage«, »PeekMessage«, »PostMessage«


  PostThreadMessage

BOOL PostThreadMessage(dwThreadId, uMsg, wParam, lParam)
DWORD  dwThreadId;   /* thread identifier */
UINT  uMsg;   /* message to post */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The PostThreadMessage function places (posts) a message in the message queue of the given thread and then returns without waiting for the thread to process the message.

Parameters

dwThreadId

Identifies the thread to which the message will be posted.

uMsg

Specifies the type of message to be posted.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function replaces the PostAppMessage function. New Win32 applications should use PostThreadMessage, instead. The thread to which the message is posted retrieves the message by calling the GetMessage or PeekMessage function. The hwnd member of the returned MSG structure is NULL.

See Also

»GetCurrentThreadId«, »GetMessage«, »GetWindowThreadProcessId«, »PeekMessage«, »PostMessage«


  PrepareTape

DWORD PrepareTape(hDevice, dwOperation, bImmediate)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwOperation;   /* preparation method */
BOOL  bImmediate;   /* return after operation begins */

The PrepareTape function prepares the tape to be accessed or removed.

Parameters

hDevice

Identifies the device preparing the tape. This handle is created by using the CreateFile function.

dwOperation

Specifies how the tape device is to be prepared. This parameter can be one of the following values:

Value	Meaning
TAPE_LOAD	Loads the tape and moves the tape to the beginning.
TAPE_LOCK	Locks the tape ejection mechanism. This prevents the tape from being ejected accidentally.
TAPE_TENSION	Adjusts the tension by moving the tape to the end of the tape and back to the beginning. This option is not supported by all devices; this flag is ignored if it is not supported.
TAPE_UNLOAD	Moves the tape to the beginning for removal from the device. After a successful unload operation, the device returns errors to applications that attempt to access the tape, until the tape is loaded again.
TAPE_UNLOCK	Unlocks the tape ejection mechanism.
bImmediate

Specifies whether to return as soon as the prepartion begins. If this parameter is TRUE, the function returns immediately; if FALSE, the function does not return until the operation has been completed.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

Some tape devices do not support certain tape operations. See your tape device documentation and use the GetTapeParameters function to determine your tape device's capabilities.


  PrintDlg

BOOL PrintDlg(lppd)
LPPRINTDLG  lppd;   /* pointer to structure with initialization data */

The PrintDlg function displays a Print dialog box or a Print Setup dialog box. The Print dialog box enables the user to specify the properties of a particular print job. The Print Setup dialog box allows the user to select additional job properties and configure the printer.

Parameters

lppd

Points to a PRINTDLG structure that contains information used to initialize the dialog box. When PrintDlg returns, this structure contains information about the user's selections. The PRINTDLG structure has the following form:

typedef struct tagPD {  /* pd */

    DWORD     lStructSize;

    HWND      hwndOwner;

    HANDLE    hDevMode;

    HANDLE    hDevNames;

    HDC       hDC;

    DWORD     Flags;

    WORD      nFromPage;

    WORD      nToPage;

    WORD      nMinPage;

    WORD      nMaxPage;

    WORD      nCopies;

    HINSTANCE hInstance;

    DWORD     lCustData;

    LPPRINTHOOKPROC lpfnPrintHook;

    LPSETUPHOOKPROC lpfnSetupHook;

    LPCSTR    lpPrintTemplateName;

    LPCSTR    lpSetupTemplateName;

    HANDLE    hPrintTemplate;

    HANDLE    hSetupTemplate;

} PRINTDLG;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds in configuring the printer, the return value is TRUE. The return value is FALSE if an error occurs, the user chooses the Cancel button, or the user chooses the Close command on the System menu to close the dialog box. (The return value is also FALSE if the user chooses the Setup button to display the Print Setup dialog box, chooses the OK button in the Print Setup dialog box, and then chooses the Cancel button in the Print dialog box.)

Use the CommDlgExtendedError function to obtain extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE	PDERR_CREATEICFAILURE
CDERR_INITIALIZATION	PDERR_DEFAULTDIFFERENT
CDERR_LOADRESFAILURE	PDERR_DNDMMISMATCH
CDERR_LOADSTRFAILURE	PDERR_GETDEVMODEFAIL
CDERR_LOCKRESFAILURE	PDERR_INITFAILURE
CDERR_MEMALLOCFAILURE	PDERR_LOADDRVFAILURE
CDERR_MEMLOCKFAILURE	PDERR_NODEFAULTPRN
CDERR_NOHINSTANCE	PDERR_NODEVICES
CDERR_NOHOOK	PDERR_PARSEFAILURE
CDERR_NOTEMPLATE	PDERR_PRINTERNOTFOUND
CDERR_STRUCTSIZE	PDERR_RETDEFFAILURE
Comments

If the hook function (pointed to by the lpfnPrintHook or lpfnSetupHook member of the PRINTDLG structure) processes the WM_CTLCOLOR message, this function must return a handle for the brush that should be used to paint the control background.

See Also

»CommDlgExtendedError«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  PrinterProperties

BOOL PrinterProperties(hwnd, hPrinter)
hwnd  hwnd;   /* handle of window in which dialog box appears  */
HANDLE  hPrinter;   /* handle of printer object */

The PrinterProperties function displays a printer-properties dialog box for the given printer.

Parameters

hwnd

Identifies the parent window of the dialog box.

hPrinter

Identifies a printer object.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»OpenPrinter«


  PrivilegeCheck

BOOL PrivilegeCheck(hClientToken, pps, lpfResult)
HANDLE  hClientToken;   /* handle of client's access token */
PPRIVILEGE_SET  pps;   /* address of privileges */
LPBOOL  lpfResult;   /* address of flag for result */

The PrivilegeCheck function tests the security context represented by a specific access token to discover whether it contains the specified privileges. This function is typically called by a server application to check the privileges of a client's access token.

Parameters

hClientToken

Identifies an access token representing a client process. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.

pps

Points to a PRIVILEGE_SET structure specifying the privileges required.

The PRIVILEGE_SET structure has the following form:

typedef struct _PRIVILEGE_SET { /* ps */

    DWORD PrivilegeCount;

    DWORD Control;

    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];

} PRIVILEGE_SET;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The specified access token is checked to see which of the specified privileges are present. When a privilege specified in the PRIVILEGE_SET structure is found in the access token, the function sets the SE_PRIVILEGE_USED_FOR_ACCESS attribute for that privilege in the corresponding LUID_AND_ATTRIBUTES structure.

lpfResult

Points to a flag the function sets to indicate whether the access token contains any or all of the specified privileges. If PRIVILEGE_SET_ALL_NECESSARY is specified in the Control member of the PRIVILEGE_SET structure pointed to by the pps parameter, this flag is TRUE only if all requested privileges are present in the access token. If PRIVILEGE_SET_ALL_NECESSARY is not specified, and if any of the privileges are present, this flag is TRUE.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»AccessCheck«, »AccessCheckAndAuditAlarm«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »LookupPrivilegeDisplayName«, »LookupPrivilegeName«, »LookupPrivilegeValue«, »ObjectPrivilegeAuditAlarm«, »PrivilegedServiceAuditAlarm«


  PrivilegedServiceAuditAlarm

BOOL PrivilegedServiceAuditAlarm(lpszSubsystem, lpszService, hClientToken, pps,
fAccessGranted)
LPTSTR  lpszSubsystem;   /* address of string for subsystem name */
LPTSTR  lpszService;   /* address of string for service name */
HANDLE  hClientToken;   /* handle of access token */
PPRIVILEGE_SET  pps;   /* address of privileges */
BOOL  fAccessGranted;   /* flag for granted access rights */

The PrivilegedServiceAuditAlarm function generates audit messages when an attempt is made to perform privileged system service operations. Alarms are not supported in the current version of Windows NT.

Parameters

lpszSubsystem

Points to a null-terminated string specifying the name of the subsystem calling the function; such as, "DEBUG" or "WIN32".

lpszService

Points to a null-terminated string specifying the name of the privileged subsystem service. For example, "RESET RUNTIME LOCAL SECURITY POLICY" might be specified by a local security authority service used to update the local security policy database.

hClientToken

Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.

pps

Points to a PRIVILEGE_SET structure containing the privileges required to perform the operation. The information in this structure is supplied by a call to the PrivilegeCheck function.

The PRIVILEGE_SET structure has the following form:

typedef struct _PRIVILEGE_SET { /* ps */

    DWORD PrivilegeCount;

    DWORD Control;

    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];

} PRIVILEGE_SET;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fAccessGranted

Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function, such as PrivilegeCheck. If access is granted, this flag is TRUE. If access is denied, it is FALSE.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The PrivilegedServiceAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege. The test for this privilege is always performed against the primary token of the calling process. This allows the calling process to impersonate a client during the call.

The PrivilegedServiceAuditAlarm function can send many messages to port objects. This can result in a significant delay before the function returns. The design of applications calling PrivilegedServiceAuditAlarm can take this potential delay into account. For example, this consideration may affect the design of an application that uses mutexes to lock structures.

See Also

»AccessCheck«, »AccessCheckAndAuditAlarm«, »AreAllAccessesGranted«, »AreAnyAccessesGranted«, »MapGenericMask«, »ObjectCloseAuditAlarm«, »ObjectOpenAuditAlarm«, »ObjectPrivilegeAuditAlarm«, »PrivilegeCheck«


  ProfClear

The ProfClear function has been deleted from the Win32 API.


  ProfFinish

The ProfFinish function has been deleted from the Win32 API.


  ProfFlush

The ProfFlush function has been deleted from the Win32 API.


  ProfInsChk

The ProfInsChk function has been deleted from the Win32 API.


  ProfSampRate

The ProfSampRate function has been deleted from the Win32 API.


  ProfSetup

The ProfSetup function has been deleted from the Win32 API.


  ProfStart

The ProfStart function has been deleted from the Win32 API.


  ProfStop

The ProfStop function has been deleted from the Win32 API.


  PtInRect

BOOL PtInRect(lprc, pt)
CONST RECT  *lprc;   /* address of structure with rectangle  */
POINT  pt;   /* structure with point */

The PtInRect function determines whether the specified point lies within the specified rectangle. A point is within a rectangle if it lies on the left or top side or is within all four sides. A point on the right or bottom side is considered outside the rectangle.

Parameters

lprc

Points to a RECT structure that contains the specified rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

pt

Specifies a POINT structure that contains the specified point. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the specified point lies within the rectangle, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»EqualRect«, »IsRectEmpty«


  PtInRegion

BOOL PtInRegion(hrgn, X, Y)
HRGN  hrgn;   /* handle of region */
int  X;   /* x-coordinate of point */
int  Y;   /* y-coordinate of point */

The PtInRegion function determines whether the specified point is inside the given region.

Parameters

hrgn

Identifies the region to be examined.

X

Specifies the x-coordinate of the point.

Y

Specifies the y-coordinate of the point.

Return Value

If the specified point is in the region, the return value is TRUE; otherwise, it is FALSE.

See Also

»RectInRegion«


  PtVisible

BOOL PtVisible(hdc, X, Y)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of point */
int  Y;   /* y-coordinate of point */

The PtVisible function indicates whether the specified point is within the clipping region of the given device context.

Parameters

hdc

Identifies the device context.

X

Specifies the logical x-coordinate of the point.

Y

Specifies the logical y-coordinate of the point.

Return Value

If the specified point is within the clipping region of the device context, the return value is TRUE; otherwise, it is FALSE.

See Also

»RectVisible«


  PulseEvent

BOOL PulseEvent(hEvent)
HANDLE  hEvent;   /* handle of event object */

The PulseEvent function provides a single operation that sets (to signaled) the state of the specified event object and then resets it (to nonsignaled) after releasing the appropriate number of waiting threads.

Parameters

hEvent

Identifies the event object. The CreateEvent or OpenEvent function returns this handle, which must have EVENT_MODIFY_STATE access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

For a manual-reset event object, all waiting threads that can be released immediately are released. The function then resets the event object's state to nonsignaled and returns.

For an auto-reset event object, the function resets the state to nonsignaled and returns after releasing a single waiting thread, even if multiple threads are waiting.

If no threads are waiting, or if no thread can be released immediately, PulseEvent simply sets the event object's state to nonsignaled and returns.

Note that for a thread using the multiple-object wait functions (WaitForMultipleObjects, WaitForMultipleObjectsEx, and MsgWaitForMultipleObjects) to wait for all specified objects to be signaled, PulseEvent can set the event object's state to signaled and reset it to nonsignaled without causing the wait function to return. This happens if not all of the specified objects are simultaneously signaled.

See Also

»CreateEvent«, »MsgWaitForMultipleObjects«, »OpenEvent«, »ResetEvent«, »SetEvent«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  PurgeComm

BOOL PurgeComm(hCommDev, fdwAction)
HANDLE  hCommDev;   /* handle of the communications resource  */
DWORD  fdwAction;   /* action to perform */

The PurgeComm function can discard all characters from the output or input buffer of a given communications resource. It can also terminate pending read or write operations on the resource.

Parameters

hCommDev

Identifies the communications resource. The CreateFile function returns this handle.

fdwAction

Specifies the action to take. This parameter can be a combination of the following values:

Value	Meaning
PURGE_TXABORT	Terminate all outstanding write operations are terminated and return immediately, even if the write operations have not been completed.
PURGE_RXABORT	Terminate all outstanding read operations are terminated and return immediately, even if the read operations have not been completed.
PURGE_TXCLEAR	Clears the output buffer (if the device driver has one).
PURGE_RXCLEAR	Clears the input buffer (if the device driver has one).
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If a thread uses PurgeComm to flush an output buffer, the deleted characters are not transmitted. To empty the output buffer while ensuring that the contents are transmitted, call the FlushFileBuffers function (a synchronous operation). Note, however, that FlushFileBuffers is subject to flow control but not to write timeouts, and it will not return until all pending write operations have been transmitted.

See Also

»CreateFile«


  QueryDosDevice

DWORD QueryDosDevice(lpDeviceName, lpTargetPath, ucchMax)
LPCTSTR  lpDeviceName;   /* pointer to DOS device name string */
LPTSTR  lpTargetPath;   /* pointer to buffer for storing query results  */
DWORD  ucchMax;   /* maximum storage capacity of that buffer */

The QueryDosDevice function lets an application obtain information about DOS device names. The function can obtain the current mapping for a particular DOS device name. The function can also obtain a list of all existing DOS device names.

DOS device names are stored as symbolic links in the Windows NT object name space. The code that converts a DOS path into a corresponding Windows NT path uses these symbolic links to map DOS devices and drive letters. The QueryDosDevice function provides a mechanism whereby a Win32 application can query the names of the symbolic links used to implement the DOS device namespace as well as the value of each specific symbolic link.

Parameters

lpDeviceName

Pointer to a DOS device name string specifying the target of the query.

This parameter can be NULL. In that case, the QueryDosDevice function will store a list of all existing DOS device names into the buffer pointed to by lpTargetPath.

lpTargetPath

Pointer to a buffer that will receive the result of the query. The function fills this buffer with one or more null-terminated strings. The final null-terminated string is followed by an additional NULL.

If lpDeviceName is non-NULL, the function obtains information about the particular DOS device specified by lpDeviceName. The first null-terminated string stored into the buffer is the current mapping for the device. The other null-terminated strings represent undeleted prior mappings for the device.

If lpDeviceName is NULL, the function obtains a list of all existing DOS device names. Each null-terminated string stored into the buffer is the name of an existing DOS device.

ucchMax

Specifies the maximum number of characters that can be stored into the buffer pointed to by lpTargetPath.

Return Value

If the function succeeds, the return value is the number of characters stored into the buffer pointed to by lpTargetPath.

If the function fails, the return value is zero. Use the GetLastError function to obtain extended error information.

Comments

The DefineDosDevice function provides a means whereby a Win32 application can create and modify the symbolic links used to implement the DOS device namespace.

DOS Device names are global. Once defined, a DOS device name remains visible to all processes until either it is explicity removed or the system reboots.

See Also

»DefineDosDevice«


  QueryPerformanceCounter

BOOL QueryPerformanceCounter(lpliPerformanceCount)
LARGE_INTEGER  *lpliPerformanceCount;   /* address of current counter value */

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter, if one exists.

Parameters

lpliPerformanceCount

Points to a variable that the function sets to the current performance-counter value (in counts). If the installed hardware does not support a high-resolution performance counter, lpliPerformanceCount is set to zero.

Return Value

If the installed hardware supports a high-resolution performance counter, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»QueryPerformanceFrequency«


  QueryPerformanceFrequency

BOOL QueryPerformanceFrequency(lpliPerformanceFreq)
LARGE_INTEGER  *lpliPerformanceFreq;   /* address of current frequency */

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists.

Parameters

lpliPerformanceFreq

Points to a variable that the function sets, in counts per second, to the current performance-counter frequency. If the installed hardware does not support a high-resolution performance counter, lpliPerformanceFreq is set to zero.

Return Value

If the installed hardware supports a high-resolution performance counter, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»QueryPerformanceCounter«


  QueryServiceConfig

BOOL QueryServiceConfig(schService, lpqscServConfig, cbBufSize, lpcbBytesNeeded)
SC_HANDLE  schService;   /* handle of service */
LPQUERY_SERVICE_CONFIG  lpqscServConfig;   /* address of service config. structure */
DWORD  cbBufSize;   /* size of service configuration buffer */
LPDWORD  lpcbBytesNeeded;   /* address of variable for bytes needed */

The QueryServiceConfig function retrieves the configuration parameters of the specified service.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_QUERY_CONFIG access.

lpqscServConfig

Points to a QUERY_SERVICE_CONFIG structure in which the service configuration information is returned. The QUERY_SERVICE_CONFIG structure has the following form:

typedef struct _QUERY_SERVICE_CONFIG { /* qsc */

    DWORD dwServiceType;

    DWORD dwStartType;

    DWORD dwErrorControl;

    LPTSTR lpBinaryPathName;

    LPTSTR lpLoadOrderGroup;

    DWORD dwTagId;

    LPTSTR lpDependencies;

    LPTSTR lpServiceStartName;

    LPTSTR lpDisplayName;

} QUERY_SERVICE_CONFIG, LPQUERY_SERVICE_CONFIG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBufSize

Specifies the size, in bytes, of the buffer pointed to by the lpqscServConfig parameter.

lpcbBytesNeeded

Points to a variable that receives the number of bytes needed to return all the configuration information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED	The specified handle was not opened with SERVICE_QUERY_CONFIG access.
ERROR_INSUFFICIENT_BUFFER	There is more service configuration information than would fit into the lpqscServConfig buffer. The number of bytes required to get all the information is returned in the lpcbBytesNeeded parameter. Nothing is written to the lpqscServConfig buffer.
ERROR_INVALID_HANDLE	The specified handle is invalid.
Comments

The QueryServiceConfig function returns the service configuration information kept in the registry for a particular service. This configuration information was first set via the CreateService function, and may have been updated via the ChangeServiceConfig function. If the service was running when the configuration information was last changed, the information returned with the QueryServiceConfig will not reflect the true configuration of the service that is running. Instead, it will reflect the configuration of the service when it is run next. Upon stopping the service, the service control manager database will be updated with the configuration that is stored in the registry. The DisplayName is an exception to this. When the DisplayName is changed, it takes effect immediately regardless of whether the service is running.

The lpqscServConfig buffer must be large enough to hold the strings pointed to by the members of the QUERY_SERVICE_CONFIG structure.

See Also

»ChangeServiceConfig«, »CreateService«, »OpenService«, »QueryServiceObjectSecurity«, »QueryServiceStatus«


  QueryServiceLockStatus

BOOL QueryServiceLockStatus(schSCManager, lpqslsLockStat, cbBufSize, lpcbBytesNeeded)
SC_HANDLE  schSCManager;   /* handle of svc. ctrl. mgr. database */
LPQUERY_SERVICE_LOCK_STATUS  lpqslsLockStat;  /* address of lock status structure */
DWORD  cbBufSize;   /* size of service configuration buffer */
LPDWORD  lpcbBytesNeeded;   /* address of variable for bytes needed */

The QueryServiceLockStatus function retrieves the lock status of the specified service control manager database.

Parameters

schSCManager

Identifies the service control manager database. The OpenSCManager function returns this handle, which must have SC_MANAGER_QUERY_LOCK_STATUS access.

lpqslsLockStat

Points to a QUERY_SERVICE_LOCK_STATUS structure in which the lock status of the specified database is returned. The QUERY_SERVICE_LOCK_STATUS structure has the following form:

typedef struct _QUERY_SERVICE_LOCK_STATUS { /* qsls */

    DWORD fIsLocked;

    LPTSTR lpLockOwner;

    DWORD dwLockDuration;

} QUERY_SERVICE_LOCK_STATUS, * LPQUERY_SERVICE_LOCK_STATUS ;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBufSize

Specifies the size, in bytes, of the buffer pointed to by the lpqslsLockStat parameter.

lpcbBytesNeeded

Points to a variable that receives the number of bytes needed to return all the lock status information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with SC_MANAGER_QUERY_LOCK_STATUS access.
ERROR_INSUFFICIENT_BUFFER
	There is more lock status information than would fit into the lpqslsLockStat buffer. The number of bytes required to get all the information is returned in the lpcbBytesNeeded parameter. Nothing is written to the lpqslsLockStat buffer.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
Comments

The QueryServiceLockStatus function returns a QUERY_SERVICE_LOCK_STATUS structure that indicates whether the specified database is locked. If the database is locked, the structure provides the account name of the user that holds the lock and the length of time that the lock has been held.

A process calls the LockServiceDatabase function to lock a service control manager database and the UnlockServiceDatabase function to release the lock.

The lpqslsLockStat buffer must be large enough to hold the string pointed to by the lpLockOwner member of the QUERY_SERVICE_LOCK_STATUS structure.

See Also

»LockServiceDatabase«, »OpenSCManager«, »UnlockServiceDatabase«


  QueryServiceObjectSecurity

BOOL QueryServiceObjectSecurity(schService, fdwSecurityInfo, psdSecurityDesc,
cbBufSize, lpcbBytesNeeded, )
SC_HANDLE  schService;   /* handle of service */
SECURITY_INFORMATION  fdwSecurityInfo;   /* type of security information requested */
PSECURITY_DESCRIPTOR  psdSecurityDesc;   /* address of security descriptor */
DWORD  cbBufSize;   /* size of security descriptor buffer */
LPDWORD  lpcbBytesNeeded;   /* address of variable for bytes needed */

The QueryServiceObjectSecurity function retrieves a copy of the security descriptor protecting a service object.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have READ_CONTROL access.

fdwSecurityInfo

Specifies the security information being requested. Any or all of the following flags can be specified:

Value	Meaning
OWNER_SECURITY_INFORMATION
	Requests the object's owner security identifier (SID).
GROUP_SECURITY_INFORMATION
	Requests the object's primary group SID.
DACL_SECURITY_INFORMATION
	Requests the object's discretionary access control list (ACL).
SACL_SECURITY_INFORMATION
	Requests the object's system ACL. The calling process must have SeSecurityPrivilege privilege.
psdSecurityDesc

Points to a buffer that receives a copy of the security descriptor of the specified service object. The calling process must have the appropriate access to view the specified aspects of the object's security descriptor. The SECURITY_DESCRIPTOR structure is returned in self-relative format. For a full description of the SECURITY_DESCRIPTOR structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBufSize

Specifies the size, in bytes, of the buffer pointed to by the psdSecurityDesc parameter.

lpcbBytesNeeded

Points to a variable that receives the number of bytes needed to return all the requested security descriptor information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with READ_CONTROL access, or the calling process is not the owner of the object.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_INSUFFICIENT_BUFFER
	There is more security descriptor information than would fit into the psdSecurityDesc buffer. The number of bytes required to get all the information is returned in the lpcbBytesNeeded parameter. Nothing is written to the psdSecurityDesc buffer.
ERROR_INVALID_PARAMETER
	The specified security information is invalid.
Comments

The initial security descriptor of a service object is created by the service control manager, based on the security descriptor of the process that called the CreateService function to create the service. The security descriptor can be changed by calling the SetServiceObjectSecurity function.

See Also

»CreateService«, »OpenService«, »SetServiceObjectSecurity«, »SECURITY_DESCRIPTOR«


  QueryServiceStatus

BOOL QueryServiceStatus(schService, lpssServiceStatus)
SC_HANDLE  schService;   /* handle of service */
LPSERVICE_STATUS  lpssServiceStatus;   /* address of service status structure */

The QueryServiceStatus function retrieves the current status of the specified service.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or the CreateService function, and it must have SERVICE_QUERY_STATUS access.

lpssServiceStatus

Points to a SERVICE_STATUS structure in which the status information is returned. The SERVICE_STATUS structure has the following form:

typedef struct _SERVICE_STATUS { /* ss */

    DWORD dwServiceType;

    DWORD dwCurrentState;

    DWORD dwControlsAccepted;

    DWORD dwWin32ExitCode;

    DWORD dwServiceSpecificExitCode;

    DWORD dwCheckPoint;

    DWORD dwWaitHint;

} SERVICE_STATUS, *LPSERVICE_STATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED	The specified handle was not opened with SERVICE_QUERY_STATUS access.
ERROR_INVALID_HANDLE	The specified handle is invalid.
Comments

The QueryServiceStatus function returns the most recent service status information reported to the service control manager. The service may have just changed its status and may not have updated the service control manager yet. Applications can find out the absolutely latest service status by interrogating the service directly by using the ControlService function with the SERVICE_CONTROL_INTERROGATE control code.

See Also

»ControlService«, »CreateService«, »OpenService«, »SetServiceStatus«


  RaiseException

VOID RaiseException(dwExceptionCode, dwExceptionFlags, cArguments, lpArguments)
DWORD  dwExceptionCode;   /* exception code */
DWORD  dwExceptionFlags;   /* continuable exception flag */
DWORD  cArguments;   /* number of arguments in array */
LPDWORD  lpArguments;   /* address of array of arguments */

The RaiseException function raises an exception in the calling thread.

Parameters

dwExceptionCode

Specifies the application-defined exception code of the exception being raised. The filter expression and exception-handler block of an exception handler can use the GetExceptionCode function to retrieve this value.

Note that the system will clear bit 28 of dwExceptionCode. This bit is a reserved exception bit, used by the system for its own purposes. For example, after calling the RaiseException function with a dwExceptionCode value of 0xffffffff, Windows NT pops up a message indicating that the exception number is 0xefffffff.

dwExceptionFlags

Specifies the exception flags. This can be either zero to indicate a continuable exception, or EXCEPTION_NONCONTINUABLE to indicate a noncontinuable exception. Any attempt to continue execution after a noncontinuable exception causes the STATUS_NONCONTINUABLE_EXCEPTION exception.

cArguments

Specifies the number of arguments in the lpArguments array. This value must not exceed EXCEPTION_MAXIMUM_PARAMETERS. This parameter is ignored if lpArguments is NULL.

lpArguments

Points to an array of 32-bit arguments. This parameter can be NULL. These arguments can contain any application-defined data that needs to be passed to the filter expression of the exception handler.

Return Value

This function does not return a value.

Comments

The RaiseException function enables a process to use structured exception handling to handle private, software-generated, application-defined exceptions.

Raising an exception causes the exception dispatcher to go through the following search for an exception handler:

1.	The system first attempts to notify the process's debugger, if any.

2.	If the process is not being debugged, or if the associated debugger does not handle the exception, the system attempts to locate a frame-based exception handler by searching the stack frames of the thread in which the exception occurred. The system searches the current stack frame first, then proceeds backward through preceding stack frames.

3.	If no frame-based handler can be found, or no frame-based handler handles the exception, the system makes a second attempt to notify the process's debugger.

4.	If the process is not being debugged, or if the associated debugger does not handle the exception, the system provides default handling based on the exception type. For most exceptions, the default action is to call the ExitProcess function.

The values specified in the dwExceptionCode, dwExceptionFlags, cArguments, and lpArguments parameters can be retrieved in the filter expression of a try-except frame-based exception handler by calling the GetExceptionInformation function. A debugger can retrieve these values by calling the WaitForDebugEvent function.

See Also

»GetExceptionCode«, »GetExceptionInformation«


  ReadConsole

BOOL ReadConsole(hConsoleInput, lpvBuffer, cchToRead, lpcchRead, lpvReserved)
HANDLE  hConsoleInput;   /* handle of a console input buffer */
LPVOID  lpvBuffer;   /* address of buffer to receive data */
DWORD  cchToRead;   /* number of characters to read */
LPDWORD  lpcchRead;   /* address of number of characters read  */
LPVOID  lpvReserved;   /* reserved */

The ReadConsole function reads character input from the console input buffer and removes it from the buffer.

Parameters

hConsoleInput

Identifies the console input buffer. The handle must have GENERIC_READ access.

lpvBuffer

Points to a buffer that receives the data read from the console input buffer.

cchToRead

Specifies the number of characters to read. Because the function can read either 2-byte Unicode or 1-byte ANSI characters, the size of the buffer pointed to by the lpvBuffer parameter should be at least cchToRead * sizeof(TCHAR).

lpcchRead

Points to a 32-bit variable that receives the number of characters actually read.

lpvReserved

Reserved; must be NULL.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

ReadConsole reads keyboard input from a console's input buffer. It behaves like the ReadFile function except that it can read in either Unicode (wide-character) or ANSI mode. To have applications that maintain a single set of sources compatible with both modes, use ReadConsole rather than ReadFile. However, ReadConsole can only be used with a console input buffer handle; ReadFile can also be used with other handles (such as files or pipes). This means that ReadConsole fails if used with a standard handle that has been redirected to be something other than a console handle.

All of the input modes that affect the behavior of ReadFile have the same effect on ReadConsole. To query and set the input modes of a console input buffer, use the GetConsoleMode and SetConsoleMode functions.

If the input buffer contains input events other than keyboard events (such as mouse events or window-resizing events), they are discarded. Such events can only be read by using the ReadConsoleInput function.

See Also

»GetConsoleMode«, »ReadConsoleInput«, »ReadFile«, »SetConsoleMode«, »WriteConsole«


  ReadConsoleInput

BOOL ReadConsoleInput(hConsoleInput, pirBuffer, cInRecords, lpcRead)
HANDLE  hConsoleInput;   /* handle of a console input buffer */
PINPUT_RECORD  pirBuffer;   /* address of the buffer for read data */
DWORD  cInRecords;   /* number of records to read */
LPDWORD  lpcRead;   /* address of number of records read */

The ReadConsoleInput function reads data from a console input buffer and removes it from the buffer.

Parameters

hConsoleInput

Identifies the input buffer. The handle must have GENERIC_READ access.

pirBuffer

Points to an INPUT_RECORD buffer that receives the input buffer data. The INPUT_RECORD structure has the following form:

typedef struct _INPUT_RECORD { /* ir */

    WORD EventType;

    union {

        KEY_EVENT_RECORD KeyEvent;

        MOUSE_EVENT_RECORD MouseEvent;

        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;

        MENU_EVENT_RECORD MenuEvent;

        FOCUS_EVENT_RECORD FocusEvent;

    } Event;

} INPUT_RECORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cInRecords

Specifies the size, in input records, of the buffer pointed to by the pirBuffer parameter.

lpcRead

Points to a 32-bit variable that receives the number of input records read.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of records requested in the cInRecords parameter exceeds the number of records available in the buffer, the number available is read. The function does not return until at least one input record has been read.

A process can specify a console input buffer handle in one of the wait functions (that is, the WaitForSingleObject or WaitForMultipleObjects function) to determine when there is unread console input. When the input buffer is not empty, the state of a console input buffer handle is signaled.

To determine the number of unread input records in a console's input buffer, use the GetNumberOfConsoleInputEvents function. To read input records from a console input buffer without affecting the number of unread records, use the PeekConsoleInput function. To discard all unread records in a console's input buffer, use the FlushConsoleInputBuffer function.

See Also

»FlushConsoleInputBuffer«, »GetNumberOfConsoleInputEvents«, »PeekConsoleInput«, »ReadConsole«, »ReadFile«, »WriteConsoleInput«


  ReadConsoleOutput

BOOL ReadConsoleOutput(hConsoleOutput, pchiDestBuffer, coordDestBufferSize,
coordDestBufferCoord, psrctSourceRect)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
PCHAR_INFO  pchiDestBuffer;   /* address of buffer that receives data */
COORD  coordDestBufferSize;   /* column-row size of destination buffer */
COORD  coordDestBufferCoord;   /* upper left cell to write to */
PSMALL_RECT  psrctSourceRect;   /* address of rectangle to read from */

The ReadConsoleOutput function reads character and color attribute data from a specified rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a given location in the destination buffer.

Parameters

hConsoleOutput

Identifies the screen buffer. The handle must have GENERIC_READ access.

pchiDestBuffer

Points to a destination buffer that receives the data read from the screen buffer. This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures whose size is specified by the coordDestBufferSize parameter. The CHAR_INFO structure has the following form:

typedef struct _CHAR_INFO { /* chi */

    union {                /* Unicode or ANSI character  */

        WCHAR UnicodeChar;

        CHAR AsciiChar;

    } Char;

    WORD Attributes;       /* text and background colors */

} CHAR_INFO, *PCHAR_INFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

coordDestBufferSize

Specifies the size, in character cells, of the pchiDestBuffer parameter. The X member of the COORD structure is the number of columns; the Y member is the number of rows. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

coordDestBufferCoord

Specifies the coordinates of the upper left cell in the pchiDestBuffer parameter to receive the data read from the screen buffer. The X member of the COORD structure is the column, and the Y member is the row.

psrctSourceRect

Points to a SMALL_RECT structure. On input, the structure members specify the upper left and lower right coordinates of the screen buffer rectangle from which to read. On output, the structure members specify the actual rectangle that was copied from. The SMALL_RECT structure has the following form:

typedef struct _SMALL_RECT { /* srct */

    SHORT Left;

    SHORT Top;

    SHORT Right;

    SHORT Bottom;

} SMALL_RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

ReadConsoleOutput treats the screen buffer and the destination buffer as two-dimensional arrays (columns and rows of character cells). The rectangle pointed to by the psrctSourceRect parameter specifies the size and location of the block to read from the screen buffer. A destination rectangle of the same size is located with its upper left cell at the coordinates of the coordDestBufferCoord parameter in the pchiDestBuffer array. Data read from the cells in the screen buffer source rectangle is copied to the corresponding cells in the destination buffer. Where the corresponding cell is outside the boundaries of the destination buffer rectangle (whose dimensions are specified by the coordSrcBufferSize parameter), the data is not copied.

Cells in the destination buffer corresponding to coordinates that are not within the boundaries of the screen buffer are left unchanged. In other words, these are the cells for which there is no screen buffer data available to be read.

Before ReadConsoleOutput returns, it sets the members of the structure pointed to by the psrctSourceRect parameter to the actual screen buffer rectangle whose cells were copied into the destination buffer. This reflects the cells in the source rectangle for which there existed a corresponding cell in the destination buffer, and it clips the dimensions of the source rectangle to the boundaries of the screen buffer.

If the rectangle specified by psrctSourceRect lies completely outside the boundaries of the screen buffer, or if the corresponding rectangle is positioned completely outside the boundaries of the destination buffer, no data is copied. In this case, the function returns with the members of the structure pointed to by the psrctSourceRect parameter set such that the Right member is less than the Left, or the Bottom member is less than the Top. To determine the size of the screen buffer, use the GetConsoleScreenBufferInfo function.

The ReadConsoleOutput function has no effect on the screen buffer's cursor position. The contents of the screen buffer are not changed by the function.

See Also

»ReadConsoleOutputAttribute«, »ReadConsoleOutputCharacter«, »WriteConsoleOutput«


  ReadConsoleOutputAttribute

BOOL ReadConsoleOutputAttribute(hConsoleOutput, lpwAttribute, cReadCells,
coordReadCoord, lpcNumberRead)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
LPWORD  lpwAttribute;   /* address of buffer to receive attributes */
DWORD  cReadCells;   /* number of character cells to read from */
COORD  coordReadCoord;   /* coordinates of first cell to read from */
LPDWORD  lpcNumberRead;   /* address of number of cells read from */

The ReadConsoleOutputAttribute function copies a specified number of foreground and background color attributes from consecutive cells of a console screen buffer, beginning at a specified location.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_READ access.

lpwAttribute

Points to a buffer that receives the attributes read from the screen buffer.

cReadCells

Specifies the number of screen buffer character cells from which to read. The size of the buffer pointed to by the lpwAttribute parameter should be cReadCells * sizeof(WORD).

coordReadCoord

Specifies the coordinates of the first cell in the screen buffer from which to read. The X member of the COORD structure is the column, and the Y member is the row. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcNumberRead

Points to a 32-bit variable that receives the number of attributes actually read.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of attributes to read from extends beyond the end of the specified screen buffer row, attributes are read from the next row. If the number of attributes to read from extends beyond the end of the screen buffer, attributes up to the end of the screen buffer are read.

Each attribute specifies the foreground (text) and background colors in which that character cell is drawn. The attribute values are some combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a white background.

FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE

See Also

»ReadConsoleOutput«, »ReadConsoleOutputCharacter«, »WriteConsoleOutput«, »WriteConsoleOutputAttribute«, »WriteConsoleOutputCharacter«


  ReadConsoleOutputCharacter

BOOL ReadConsoleOutputCharacter(hConsoleOutput, lpReadBuffer, cchRead,
coordReadCoord, lpcNumberRead)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
LPTSTR  lpReadBuffer;   /* address of buffer to receive characters */
DWORD  cchRead;   /* number of character cells to read from */
COORD  coordReadCoord;   /* coordinates of first cell to read from */
LPDWORD  lpcNumberRead;   /* address of number of cells read from */

The ReadConsoleOutputCharacter function copies a specified number of characters from consecutive cells of a console screen buffer, beginning at a given location.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_READ access.

lpReadBuffer

Points to a buffer that receives the characters read from the screen buffer.

cchRead

Specifies the number of screen buffer character cells from which to read. The size of the buffer pointed to by the lpReadBuffer parameter should be cchRead * sizeof(TCHAR).

coordReadCoord

Specifies the coordinates of the first cell in the screen buffer from which to read. The X member of the COORD structure is the column, and the Y member is the row. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcNumberRead

Points to a 32-bit variable that receives the number of characters actually read.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of characters to read from extends beyond the end of the specified screen buffer row, characters are read from the next row. If the number of characters to read from extends beyond the end of the screen buffer, characters up to the end of the screen buffer are read.

See Also

»ReadConsoleOutput«, »ReadConsoleOutputAttribute«, »WriteConsoleOutput«, »WriteConsoleOutputAttribute«, »WriteConsoleOutputCharacter«


  ReadEventLog

BOOL ReadEventLog(hEventLog, fdwRead, dwRecordNumber, lpvBuffer, cbBuffer,
pcbRead, pcbNeeded)
HANDLE  hEventLog;   /* handle of event log */
DWORD  fdwRead;   /* specifies how to read log */
DWORD  dwRecordNumber;   /* number of first record */
LPVOID  lpvBuffer;   /* address of buffer for read data */
DWORD  cbBuffer;   /* number of bytes to read */
DWORD  *pcbRead;   /* number of bytes read */
DWORD  *pcbRequired;   /* number of bytes required for next record */

The ReadEventLog function reads a whole number of entries from the given event log. The function can be used to read log entries in forward or reverse chronological order.

Parameters

hEventLog

Identifies the event log to read. This handle is returned by the OpenEventLog function.

fdwRead

Specifies how the read operation is to proceed. This parameter can be any combination of the following values:

Value	Meaning
EVENTLOG_FORWARDS_READ	The log is read in forward chronological order.
EVENTLOG_BACKWARDS_READ	The log is read in reverse chronological order.
EVENTLOG_SEEK_READ	The read operation proceeds from the record specified by the dwRecordNumber parameter. If this flag is used, fdwRead must also specify EVENTLOG_FORWARDS_READ or EVENTLOG_BACKWARDS_READ. If the buffer is large enough, more than one record can be read at the specified seek position; the additional flag indicates the direction for successive read operations.
EVENTLOG_SEQUENTIAL_READ	The read operation proceeds sequentially from the last call to the ReadEventLog function using this handle.
dwRecordNumber

Specifies the log-entry record number at which the read operation should start. This parameter is ignored unless the fdwRead parameter includes the EVENTLOG_SEEK_READ flag.

lpvBuffer

Points to a buffer for the data read from the event log. This parameter cannot be NULL, even if the cbBuffer parameter is zero.

The buffer will be filled with an EVENTLOGRECORD structure. The EVENTLOGRECORD structure has the following form:

typedef struct _EVENTLOGRECORD { /* evlr        */

    DWORD  Length;

    DWORD  Reserved;

    DWORD  RecordNumber;

    DWORD  TimeGenerated;

    DWORD  TimeWritten;

    DWORD  EventID;

    WORD   EventType;

    WORD   NumStrings;

    WORD   EventCategory;

    WORD   ReservedFlags;

    DWORD  ClosingRecordNumber;

    DWORD  StringOffset;

    DWORD  UserSidLength;

    DWORD  UserSidOffset;

    DWORD  DataLength;

    DWORD  DataOffset;

    //

    // Then follow:

    //

    // WCHAR SourceName[]

    // WCHAR Computername[]

    // SID   UserSid

    // WCHAR Strings[]

    // BYTE  Data[]

    // CHAR  Pad[]

    // DWORD Length;

    //

} EVENTLOGRECORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbBuffer

Specifies the size, in bytes, of the buffer. This function will read as many whole log entries as will fit in the buffer; the function will not return partial entries, even if there is room in the buffer.

pcbRead

Points to a variable that receives the number of bytes read by the function.

pcbRequired

Points to a variable that receives the number of bytes required for the next log entry. This count is valid only if ReadEventLog returns zero and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When this function returns, the read position in the error log is adjusted by the number of records read. Only a whole number of event log records will be returned.

Note  The configured filename for this source may also be the configured filename for other sources (several sources can exist as subkeys under a single logfile). Therefore, this function may return events that were logged by more than one source.

See Also

»ClearEventLog«, »CloseEventLog«, »OpenEventLog«, »ReportEvent«


  ReadFile

BOOL ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped)
HANDLE  hFile;   /* handle of file to read */
LPVOID  lpBuffer;   /* address of buffer that receives data */
DWORD  nNumberOfBytesToRead;   /* number of bytes to read */
LPDWORD  lpNumberOfBytesRead;   /* address of number of bytes read  */
LPOVERLAPPED  lpOverlapped;   /* address of structure for data */

The ReadFile function reads data from a file, starting at the position indicated by the file pointer. After the read operation has been completed, the file pointer is adjusted by the number of bytes actually read, unless the file handle is created with the overlapped attribute. If the file handle is created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the read.

Parameters

hFile

Identifies the file to be read. The file handle must have been created with GENERIC_READ access to the file.

lpBuffer

Points to the buffer that receives the data read from the file.

nNumberOfBytesToRead

Specifies the number of bytes to read from the file.

lpNumberOfBytesRead

Points to the number of bytes read by this call. ReadFile sets this value to zero before doing any work or error checking. If this parameter is zero when ReadFile returns TRUE on a named pipe, the other end of the message-mode pipe called the WriteFile function with nNumberOfBytesToWrite set to zero.

lpOverlapped

Points to an OVERLAPPED structure. This structure is required if hFile was created with FILE_FLAG_OVERLAPPED.

The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the current position of the file pointer is unknown, ReadFile returns FALSE, and the GetLastError function returns ERROR_INVALID_PARAMETER.

If hFile was not created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile does not return until the operation has been completed.

If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile may return before the read operation has been completed. In this case, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. The calling process can continue while the read operation finishes. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation.

If hFile is not created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure. ReadFile does not return until the read operation has been completed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

If the return value is TRUE and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read.

Comments

If part of the file is locked by another process and the read overlaps the locked portion, this function fails.

Characters can be read from the console input buffer by using ReadFile with a handle to console input. The console mode determines the exact behavior of the ReadFile function.

If a named pipe is being read in message mode and the next message is longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the message may be read by a subsequent ReadFile or PeekNamedPipe function call.

When reading from a communications device, ReadFile normally waits until the requested number of bytes has been received. The SetCommTimeouts function can be used to force ReadFile to return with fewer bytes.

If ReadFile attempts to read from a mailslot whose buffer is too small, the function returns FALSE and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

If the anonymous write pipe handle has been closed, and ReadFile attempts to read using the corresponding anonymous read pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.

The ReadFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.

See Also

»CreateFile«, »GetOverlappedResult«, »PeekNamedPipe«, »ReadFileEx«, »SetCommTimeouts«, »WriteFile«


  ReadFileEx

BOOL ReadFileEx(hFile, lpBuffer, nNumberOfBytesToRead, lpOverlapped, lpcr)
HANDLE  hFile;   /* handle of file to read */
LPVOID  lpBuffer;   /* address of buffer */
DWORD  nNumberOfBytesToRead;   /* number of bytes to read */
LPOVERLAPPED  lpOverlapped;   /* address of offset */
LPOVERLAPPED_COMPLETION_ROUTINE  lpcr;   /* address of completion routine */

The ReadFileEx function reads data from a file and reports its completion status asynchronously. This function is an extension to the ReadFile function that enables an application to continue with other processing.

Parameters

hFile

Identifies the file to read. The file handle must have been created with the FILE_FLAG_OVERLAPPED flag and must have GENERIC_READ access to the file.

lpBuffer

Points to the buffer that receives the data read from the file.

nNumberOfBytesToRead

Specifies the number of bytes to read from the file.

lpOverlapped

Points to an OVERLAPPED structure that must be valid for the duration of the read operation. If the calling application can return while the read operation is still pending, do not use a local variable.

The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpcr

Points to the completion routine called when the read operation has been completed. For more information about the completion routine, see the description of the »FileIOCompletionRoutine« function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

If the read operation has not finished, the function returns TRUE. If the calling thread is in an alertable wait (using the SleepEx, WaitForMultipleObjectsEx or WaitForSingleObjectEx function) when the read operation finishes, the completion routine is called and the wait has been completed with a return value of WAIT_IO_COMPLETION.

If the calling thread is not in an alertable wait when the read operation has been completed, the operating system queues the completion routine call until the thread enters an alertable wait.

If ReadFileEx attempts to read past the end of the file, the function returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

Comments

If part of the file is locked by another process and the read overlaps the locked portion, this function fails.

If ReadFileEx attempts to read from a mailslot whose buffer is too small, the function returns FALSE and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

The ReadFileEx function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.

See Also

»CreateFile«, »ReadFile«, »SleepEx«, »WaitForMultipleObjectsEx«, »WaitForSingleObjectEx«, »WriteFileEx«


  ReadPrinter

BOOL ReadPrinter(hPrinter, lpBuf, cbBuf, lpdwBytes)
HANDLE  hPrinter;   /* handle of printer object */
LPVOID  lpBuf;   /* address of array of bytes that receives data */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwBytes;   /* address of variable with number of bytes retrieved */

The ReadPrinter function retrieves data from the given printer.

Parameters

hPrinter

Identifies the printer for which to retrieve data.

lpBuf

Points to an array of bytes that receives the printer data.

cbBuf

Specifies the size, in bytes, of the buffer to which lpBuf points.

lpdwBytes

Points to a variable that receives the number of bytes of data copied into the array to which lpBuf points.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function returns an error if the device or the printer is not bidirectional.

See Also

»OpenPrinter«


  ReadProcessMemory

BOOL ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, cbRead, lpNumberOfBytesRead)
HANDLE  hProcess;   /* handle of the proc whose memory is read */
LPVOID  lpBaseAddress;   /* address to start reading */
LPVOID  lpBuffer;   /* address of buffer to place read data */
DWORD  cbRead;   /* number of bytes to read */
LPDWORD  lpNumberOfBytesRead;   /* actual number of bytes read */

The ReadProcessMemory function reads memory in a specified process. The entire area to be read must be accessible, or the operation fails.

Parameters

hProcess

Specifies an open handle of a process whose memory is read. The handle must have been created with PROCESS_VM_READ access to the process.

lpBaseAddress

Specifies the base address in the specified process to be read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access. If this is the case, the function proceeds; otherwise, the function fails.

lpBuffer

Specifies the address of a buffer that receives the contents from the address space of the specified process.

cbRead

Specifies the requested number of bytes to read from the specified process.

lpNumberOfBytesRead

Specifies the actual number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is NULL, the parameter is ignored.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function. The function will fail if the requested read operation crosses into an area of the process that is inaccessible.

Comments

This function copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call ReadProcessMemory. The process whose address space is read is typically, but not necessarily, being debugged.

The entire area to be read must be accessible. If it is not, the function fails, as noted above.

See Also

»WriteProcessMemory«


  RealizePalette

UINT RealizePalette(hdc)
HDC  hdc;   /* handle of device context */

The RealizePalette function maps palette entries from the current logical palette to the system palette.

Parameters

hdc

Identifies the device context (DC) into which a logical palette has been selected.

Return Value

If the function succeeds, the return value is the number of entries in the logical palette mapped to the system palette; otherwise, it is GDI_ERROR. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

The RealizePalette function modifies the palette for the device associated with the given device context. If the device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device context is a display DC, the physical palette for that device is modified.

A logical color palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows.

When an application's window has the focus and it calls the RealizePalette function, Windows attempts to realize as many of the requested colors as possible. The same is also true for applications with inactive windows.

See Also

»GetDeviceCaps«


  Rectangle

BOOL Rectangle(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coord. of bounding rect. upper-left corner */
int  nTopRect;   /* y-coord. of bounding rect. upper-left corner */
int  nRightRect;   /* x-coord. of bounding rect. lower-right corner */
int  nBottomRect;   /* y-coord. of bounding rect. lower-right corner */

The Rectangle function draws a rectangle. The rectangle is outlined by using the current pen and filled by using the current brush.

Parameters

hdc

Identifies the device context.

nLeftRect

Specifies the logical x-coordinate of the upper-left corner of the rectangle.

nTopRect

Specifies the logical y-coordinate of the upper-left corner of the rectangle.

nRightRect

Specifies the logical x-coordinate of the lower-right corner of the rectangle.

nBottomRect

Specifies the logical y-coordinate of the lower-right corner of the rectangle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The current position is neither used nor updated by this function.

See Also

»RoundRect«


  RectInRegion

BOOL RectInRegion(hrgn, lprc)
HRGN  hrgn;   /* handle of region */
CONST RECT  *lprc;   /* address of structure with rectangle */

The RectInRegion function determines whether any part of the specified rectangle is within the boundaries of the given region.

Parameters

hrgn

Identifies the region.

lprc

Points to a RECT structure containing the coordinates of the rectangle. The lower and right edges of the rectangle are not included. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If any part of the specified rectangle lies within the boundaries of the region, the return value is TRUE; otherwise, the return value is FALSE.

See Also

»PtInRegion«


  RectVisible

BOOL RectVisible(hdc, lprc)
HDC  hdc;   /* handle of the device context */
CONST RECT  *lprc;   /* address of rectangle structure */

The RectVisible function determines whether any part of the specified rectangle lies within the clipping region of the given device context.

Parameters

hdc

Identifies the device context.

lprc

Points to a RECT structure that contains the logical coordinates of the specified rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If some portion of the specified rectangle lies within the clipping region, the return value is TRUE; otherwise, it is FALSE.

See Also

»CreateRectRgn«, »PtVisible«, »SelectClipRgn«


  RedrawWindow

BOOL RedrawWindow(hwnd, lprcUpdate, hrgnUpdate, afuRedraw)
HWND  hwnd;   /* handle of window */
CONST RECT  *lprcUpdate;   /* address of structure with update rectangle */
HRGN  hrgnUpdate;   /* handle of update region  */
UINT  afuRedraw;   /* array of redraw flags */

The RedrawWindow function updates the given rectangle or region in a window's client area.

Parameters

hwnd

Identifies the window to be redrawn. If this parameter is NULL, the desktop window is updated.

lprcUpdate

Points to a RECT structure containing the coordinates of the update rectangle. This parameter is ignored if the hrgnUpdate parameter identifies a region. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hrgnUpdate

Identifies the update region. If both the hrgnUpdate and lprcUpdate parameters are NULL, the entire client area is added to the update region.

afuRedraw

Specifies one or more redraw flags. This parameter can be a combination of flags that invalidate or validate a window, control repainting, and control which windows are affected by RedrawWindow.

The following flags are used to invalidate the window:

Flag	Description
RDW_ERASE	Causes the window to receive a WM_ERASEBKGND message when the window is repainted. The RDW_INVALIDATE flag must also be specified; otherwise, RDW_ERASE has no effect.
RDW_FRAME	Causes any part of the nonclient area of the window that intersects the update region to receive a WM_NCPAINT message. The RDW_INVALIDATE flag must also be specified; otherwise, RDW_FRAME has no effect. The WM_NCPAINT message is typically not sent during the execution of RedrawWindow unless either RDW_UPDATENOW or RDW_ERASENOW is specified.
RDW_INTERNALPAINT	Causes a WM_PAINT message to be posted to the window regardless of whether any portion of the window is invalid.
RDW_INVALIDATE	Invalidates lprcUpdate or hrgnUpdate (only one may be non-NULL). If both are NULL, the entire window is invalidated.
The following flags are used to validate the window:

Flag	Description
RDW_NOERASE	Suppresses any pending WM_ERASEBKGND messages.
RDW_NOFRAME	Suppresses any pending WM_NCPAINT messages. This flag must be used with RDW_VALIDATE and is typically used with RDW_NOCHILDREN. RDW_NOFRAME should be used with care, as it could cause parts of a window to be painted improperly.
RDW_NOINTERNALPAINT	Suppresses any pending internal WM_PAINT messages. This flag does not affect WM_PAINT messages resulting from a non-NULL update area.
RDW_VALIDATE	Validates lprcUpdate or hrgnUpdate (only one may be non-NULL). If both are NULL, the entire window is validated. This flag does not affect internal WM_PAINT messages.
The following flags control when repainting occurs. RedrawWindow will not repaint unless one of these flags is specified.

Flag	Description
RDW_ERASENOW	Causes the affected windows (as specified by the RDW_ALLCHILDREN and RDW_NOCHILDREN flags) to receive WM_NCPAINT and WM_ERASEBKGND messages, if necessary, before the function returns. WM_PAINT messages are received at the ordinary time.
RDW_UPDATENOW	Causes the affected windows (as specified by the RDW_ALLCHILDREN and RDW_NOCHILDREN flags) to receive WM_NCPAINT, WM_ERASEBKGND, and WM_PAINT messages, if necessary, before the function returns.
By default, the windows affected by RedrawWindow depend on whether the given window has the WS_CLIPCHILDREN style. Child windows not belonging to the WS_CLIPCHILDREN style windows are not affected; however, non-WS_CLIPCHILDREN windows are recursively validated or invalidated until a WS_CLIPCHILDREN window is encountered. The following flags control which windows are affected by the RedrawWindow function:

Flag	Description
RDW_ALLCHILDREN	Includes child windows, if any, in the repainting operation.
RDW_NOCHILDREN	Excludes child windows, if any, from the repainting operation.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When RedrawWindow is used to invalidate part of the desktop window, the desktop window does not receive a WM_PAINT message. To repaint the desktop, an application uses the RDW_ERASE flag to generate a WM_ERASEBKGND message.

See Also

»GetUpdateRect«, »GetUpdateRgn«, »InvalidateRect«, »InvalidateRgn«, »UpdateWindow«


  RegCloseKey

LONG RegCloseKey(hkey)
HKEY  hkey;   /* handle of key to close */

The RegCloseKey function releases the handle of the given key.

Parameters

hkey

Identifies the open key to close.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The handle for a given key should not be used after it has been closed, because it will no longer be valid. Key handles should not be left open any longer than necessary.

The RegCloseKey function does not necessarily write information to the registry before returning; it can take as much as several seconds for the cache to be flushed to the hard disk. If an application must explicitly write registry information to the hard disk, it can use the RegFlushKey function. RegFlushKey, however, uses many system resources and should be called only when necessary.

See Also

»RegCreateKey«, »RegCreateKeyEx«, »RegDeleteKey«, »RegFlushKey«, »RegOpenKey«, »RegOpenKeyEx«, »RegSetValue«, »RegSetValueEx«


  RegConnectRegistry

LONG RegConnectRegistry(lpszComputerName, hkey, phkResult)
LPTSTR  lpszComputerName;   /* address of name of remote computer */
HKEY  hkey;   /* predefined registry handle */
PHKEY  phkResult;   /* address of buffer for remote registry handle */

The RegConnectRegistry function establishes a connection to a predefined registry handle on another computer.

Parameters

lpszComputerName

Points to a null-terminated string containing the name of the remote computer. The string has the following form:

\\computername

If lpszComputerName is NULL, the local computer name is used.

hkey

Specifies the predefined handle of the registry on the remote computer. Currently, the following values can be used:

HKEY_LOCAL_MACHINE
HKEY_USERS

An application cannot specify the HKEY_CLASSES_ROOT or HKEY_CURRENT_USER value for this parameter.

phkResult

Points to a variable that receives a key handle identifying the predefined handle on the remote computer.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

When a handle returned by RegConnectRegistry is no longer needed it should be closed by calling RegCloseKey.


  RegCreateKey

LONG RegCreateKey(hkey, lpszSubKey, phkResult)
HKEY  hkey;   /* handle of an open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey to open  */
PHKEY  phkResult;   /* address of buffer for opened handle */

The RegCreateKey function creates the specified key. If the key already exists in the registry, the function opens it. This function is provided for compatibility with Windows version 3.1. New applications should use the RegCreateKeyEx function.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The key opened or created by this function is a subkey of the key identified by hkey.

lpszSubKey

Points to a null-terminated string specifying the name of a key that this function opens or creates. This key must be a subkey of the key identified by the hkey parameter.

If hkey is one of the predefined keys, lpszSubKey may be NULL. In that case, the handle returned via phkResult is the same hkey handle passed in to the function.

phkResult

Points to a variable that receives the handle of the opened or created key.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

An application can use the RegCreateKey function to create several keys at once. For example, an application can create a subkey four-levels deep at the same time as the three preceding subkeys by specifying a string of the following form for the lpszSubKey parameter:

subkey1\subkey2\subkey3\subkey4

The key identified by the hkey parameter must have been opened with KEY_CREATE_SUB_KEY access (KEY_WRITE access includes KEY_CREATE_SUB_KEY access).

See Also

»RegCloseKey«, »RegCreateKeyEx«, »RegDeleteKey«, »RegOpenKey«, »RegOpenKeyEx«, »RegSetValue«


  RegCreateKeyEx

LONG RegCreateKeyEx(hkey, lpszSubKey, dwReserved, lpszClass, fdwOptions,
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition)
HKEY  hkey;   /* handle of an open key */
LPCTSTR  lpszSubKey;   /* address of subkey name */
DWORD  dwReserved;   /* reserved */
LPTSTR  lpszClass;   /* address of class string */
DWORD  fdwOptions;   /* special options flag */
REGSAM  samDesired;   /* desired security access */
LPSECURITY_ATTRIBUTES  lpSecurityAttributes;   /* address of key security structure */
PHKEY  phkResult;   /* address of buffer for opened handle */
LPDWORD  lpdwDisposition;   /* address of dispostion value buffer */

The RegCreateKeyEx function creates the specified key. If the key already exists in the registry, the function opens it.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The key opened or created by the RegCreateKeyEx function is a subkey of the key identified by the hkey parameter.

lpszSubKey

Points to a null-terminated string specifying the name of a key that this function opens or creates. This key must be a subkey of the key identified by the hkey parameter. This parameter cannot be NULL.

dwReserved

Reserved; must be zero.

lpszClass

Points to a null-terminated string that specifies the class (object type) of this key. This parameter is ignored if the key already exists.

fdwOptions

Specifies special options for the key. Currently, this parameter can be one of the following values:

Value	Meaning
REG_OPTION_VOLATILE	This key is volatile; the information is stored in memory and is not preserved when the system is restarted.
REG_OPTION_NON_VOLATILE	This key is not volatile; the information is stored in a file and is preserved when the system is restarted.
By default, keys are not volatile. This option is ignored if the key already exists.

samDesired

Specifies an access mask that specifies the desired security access for the new key. This parameter can be a combination of the following values:

Value	Meaning
KEY_ALL_ACCESS	Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access.
KEY_CREATE_LINK	Permission to create a symbolic link.
KEY_CREATE_SUB_KEY	Permission to create subkeys.
KEY_ENUMERATE_SUB_KEYS	Permission to enumerate subkeys.
KEY_EXECUTE	Permission for read access.
KEY_NOTIFY	Permission for change notification.
KEY_QUERY_VALUE	Permission to query subkey data.
KEY_READ	Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
KEY_SET_VALUE	Permission to set subkey data.
KEY_WRITE	Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.
lpSecurityAttributes

Points to a SECURITY_ATTRIBUTES structure that specifies the security attributes for the new key. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If this parameter is NULL, the key receives a default security descriptor. If the operating system does not support security, this parameter is ignored.

phkResult

Points to a variable that receives the handle of the opened or created key.

lpdwDisposition

Points to a variable that receives one of the following disposition values:

Value	Meaning
REG_CREATED_NEW_KEY	The key did not exist and was created.
REG_OPENED_EXISTING_KEY	The key existed and was simply opened without being changed.
Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The key that the RegCreateKeyEx function creates has no values. An application can use the RegSetValue or RegSetValueEx function to set key values.

The key identified by the hkey parameter must have been opened with KEY_CREATE_SUB_KEY access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

An application cannot create a key under HKEY_USERS or HKEY_MACHINE.

An application can use RegCreateKeyEx to temporarily lock a portion of the registry. When the locking process creates a new key, it receives the disposition value REG_CREATED_NEW_KEY, indicating that it "owns" the lock. Another process attempting to create the same key receives the disposition value REG_OPENED_EXISTING_KEY, indicating that another process already owns the lock.

See Also

»RegCreateKey«, »RegDeleteKey«, »RegOpenKey«, »RegOpenKeyEx«


  RegDeleteKey

LONG RegDeleteKey(hkey, lpszSubKey)
HKEY  hkey;   /* handle of open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey to delete */

The RegDeleteKey function deletes the specified key. This function cannot delete a key that has subkeys.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The key specified by the lpszSubKey parameter must be a subkey of the key identified by hkey.

lpszSubKey

Points to a null-terminated string specifying the name of the key to delete. This parameter cannot be NULL, and the specified key must not have subkeys.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

If the function succeeds, RegDeleteKey removes the specified key from the registration database. The entire key, including all of its values, is removed.

To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

See Also

»RegCloseKey«, »RegCreateKeyEx«, »RegOpenKeyEx«


  RegDeleteValue

LONG RegDeleteValue(hkey, lpszValue)
HKEY  hkey;   /* handle of key */
LPTSTR  lpszValue;   /* address of value name */

The RegDeleteValue function removes a named value from the given registry key.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszValue

Points to a null-terminated string that names the value to remove. If this parameter is NULL or points to an empty string, the value set by the RegSetValue function is removed.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The key identified by the hkey parameter must have been opened with KEY_SET_VALUE access (KEY_WRITE access includes KEY_SET_VALUE access).

See Also

»RegSetValue«, »RegSetValueEx«


  RegEnumKey

LONG RegEnumKey(hkey, iSubKey, lpszName, cchName)
HKEY  hkey;   /* handle of key to query */
DWORD  iSubKey;   /* index of subkey to query */
LPTSTR  lpszName;   /* address of buffer for subkey name  */
DWORD  cchName;   /* size of subkey buffer */

The RegEnumKey function enumerates subkeys of the given open registry key. The function retrieves the name of one subkey each time it is called. This function is provided for compatibility with Windows version 3.1. New applications should use the RegEnumKeyEx function.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The keys returned are relative to the key identified by hkey.

iSubKey

Specifies the index of the subkey to retrieve. This value should be zero for the first call to the RegEnumKey function and then incremented for subsequent calls.

Because subkeys are not ordered, any new subkey will have an arbitrary index. This means that the function may return subkeys in any order.

lpszName

Points to a buffer that receives the name of the subkey, including the termination null character. This function copies only the name of the subkey, not the full key hierarchy, to the buffer.

cchName

Specifies the size, in characters, of the buffer pointed to by the lpszName parameter, in characters. To determine the required buffer size, use the RegQueryInfoKey function to determine the size of the largest subkey for the key identified by the hkey parameter. The maximum required buffer size is plus one MAX_PATH characters.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

To enumerate subkeys, an application should initially call the RegEnumKey function with the iSubKey parameter set to zero. The application should then increment the iSubKey parameter and call the RegEnumKey function until there are no more subkeys (until the function returns ERROR_NO_MORE_ITEMS).

The application can also set iSubKey to the index of the last key on the first call to the function and decrement the index until the subkey with index 0 is enumerated. To retrieve the index of the last subkey, use the RegQueryInfoKey.

While an application is using the RegEnumKey function, it should not make calls to any registration functions that might change the key being queried.

The key identitied by the hkey parameter must have been opened with KEY_ENUMERATE_SUB_KEYS access (KEY_READ access includes KEY_ENUMERATE_SUB_KEYS access). To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

See Also

»RegCloseKey«, »RegCreateKeyEx«, »RegDeleteKey«, »RegEnumKeyEx«, »RegOpenKeyEx«, »RegQueryInfoKey«, »RegQueryValue«


  RegEnumKeyEx

LONG RegEnumKeyEx(hkey, iSubkey, lpszName, lpcchName, lpdwReserved, lpszClass,
lpcchClass, lpftLastWrite)
HKEY  hkey;   /* handle of key to enumerate */
DWORD  iSubkey;   /* index of subkey to enumerate */
LPTSTR  lpszName;   /* address of buffer for subkey name */
LPDWORD  lpcchName;   /* address for size of subkey buffer */
LPDWORD  lpdwReserved;   /* reserved */
LPTSTR  lpszClass;   /* address of buffer for class string */
LPDWORD  lpcchClass;   /* address for size of class buffer */
PFILETIME  lpftLastWrite;   /* address for time key last written to */

The RegEnumKeyEx function enumerates subkeys of the given open registry key. The function retrieves information about one subkey each time it is called. Unlike the RegEnumKey function, RegEnumKeyEx retrieves the class name of the subkey and the time it was last modified.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The enumerated keys are subkeys of the key identified by hkey.

iSubkey

Specifies the index of the subkey to retrieve. This parameter should be zero for the first call to the RegEnumKeyEx function and then incremented for subsequent calls.

Because subkeys are not ordered, any new subkey will have an arbitrary index. This means that the function may return subkeys in any order.

lpszName

Points to a buffer that receives the name of the subkey, including the terminating null character. The function copies only the name of the subkey, not the full key hierarchy, to the buffer.

lpcchName

Points to a variable that specifies the size, in characters, of the buffer specified by the lpszName parameter. This size should include the terminating null character. When the function returns, the variable pointed to by lpcchName contains the number of characters stored in the buffer. The count returned does not include the terminating null character.

lpdwReserved

Reserved; must be NULL.

lpszClass

Points to a buffer that contains the class of the enumerated subkey when the function returns. This parameter can be NULL if the class is not required.

lpcchClass

Points to a variable that specifies the size, in characters, of the buffer specified by the lpszClass parameter. The size should include the terminating null character. When the function returns, lpcchClass contains the number of characters stored in the buffer. The count returned does not include the terminating null charater. This parameter can be NULL only if lpszClass is NULL.

lpftLastWrite

Points to a variable that receives the time the enumerated subkey was last written to.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

To enumerate subkeys, an application should initially call the RegEnumKeyEx function with the iSubKey parameter set to zero. The application should then increment the iSubKey parameter and call RegEnumKeyEx until there are no more subkeys (until the function returns ERROR_NO_MORE_ITEMS).

The application can also set iSubKey to the index of the last subkey on the first call to the function and decrement the index until the subkey with the index 0 is enumerated. To retrieve the index of the last subkey, use the RegQueryInfoKey function.

While an application is using the RegEnumKeyEx function it should not make calls to any registration functions that might change the key being enumerated.

The key identified by hkey must have been opened with KEY_ENUMERATE_SUB_KEYS access (KEY_READ includes KEY_ENUMERATE_SUB_KEYS). Use the RegCreateKeyEx or RegOpenKeyEx function to open the key.

See Also

»RegDeleteKey«, »RegEnumKey«


  RegEnumValue

LONG RegEnumValue(hkey, iValue, lpszValue, lpcchValue, lpdwReserved, lpdwType,
lpbData, lpcbData)
HKEY  hkey;   /* handle of key to query */
DWORD  iValue;   /* index of value to query */
LPTSTR  lpszValue;   /* address of buffer for value string */
LPDWORD  lpcchValue;   /* address for size of value buffer */
LPDWORD  lpdwReserved;   /* reserved */
LPDWORD  lpdwType;   /* address of buffer for type code */
LPBYTE  lpbData;   /* address of buffer for value data */
LPDWORD  lpcbData;   /* address for size of data buffer */

The RegEnumValue function enumerates the values for the given open registry key. The function copies one indexed value name and data block for the key each time it is called.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The enumerated values are associated with the key identified by hkey.

iValue

Specifies the index of the value to retrieve. This parameter should be zero for the first call to the RegEnumValue function and then be incremented for subsequent calls.

Because values are not ordered, any new value will have an arbitrary index. This means that the function may return values in any order.

lpszValue

Points to a buffer that receives the name of the value, including the terminating null character.

lpcchValue

Points to a variable that specifies the size, in characters, of the buffer pointed to the lpszValue parameter. This size should include the terminating null character. When the function returns, the variable pointed to by lpcchValue contains the number of characters stored in the buffer. The count returned does not include the terminating null character.

lpdwReserved

Reserved; must be NULL.

lpdwType

Points to a variable that receives the type code for the value entry. The type code can be one of the following values:

Value	Meaning
REG_BINARY	Binary data in any form.
REG_DWORD	A 32-bit number.
REG_DWORD_LITTLE_ENDIAN	A 32-bit number in little-endian format (same as REG_DWORD). In little-endian format, the most significant byte of a word is the high-order word. This is the most common format for computers running Windows NT.
REG_DWORD_BIG_ENDIAN	A 32-bit number in big-endian format. In big-endian format, the most significant byte of a word is the low-order word.
REG_EXPAND_SZ	A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
REG_LINK	A Unicode symbolic link.
REG_MULTI_SZ	An array of null-terminated strings, terminated by two null characters.
REG_NONE	No defined value type.
REG_RESOURCE_LIST	A device-driver resource list.
REG_SZ	A null-terminated string. It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
The lpdwType parameter can be NULL if the type code is not required.

lpbData

Points to a buffer that receives the data for the value entry. This parameter can be NULL if the data is not required.

lpcbData

Points to a variable that specifies the size, in bytes, of the buffer pointed to by the lpbData parameter. When the function returns, the variable pointed to by the lpcbData parameter contains the number of bytes stored in the buffer. This parameter can be NULL, only if lpbData is NULL.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

To enumerate values, an application should initially call the RegEnumValue function with the iValue parameter set to zero. The application should then increment iValue and call the RegEnumValue function until there are no more values (until the function returns ERROR_NO_MORE_ITEMS).

The application can also set iValue to the index of the last value on the first call to the function and decrement the index until the value with index 0 is enumerated. To retrieve the index of the last value, use the ReqQueryInfoKey function.

While using RegEnumValue, an application should not call any registration functions that might change the key being queried.

The key identified by the hkey parameter must have been opened with KEY_QUERY_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

To determine the maximum size of the name and data buffers, use the RegQueryInfoKey function.

See Also

»RegCreateKeyEx«, »RegEnumKey«, »RegEnumKeyEx«, »RegOpenKeyEx«, »RegQueryInfoKey«


  RegFlushKey

LONG RegFlushKey(hkey)
HKEY  hkey;   /* handle of key to write */

The RegFlushKey function writes all the attributes of the given open key into the registry.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

It is not necessary to call RegFlushKey to change a key. Registry changes are flushed to disk by the registry using its lazy flusher. Registry changes are also flushed to disk at system shutdown.

Unlike RegCloseKey, the RegFlushKey function returns only when all the data has been written to the registry.

The RegFlushKey function may also write out parts of or all of the other keys. Calling this function excessively can have a negative effect on an application's performance.

An application should only call RegFlushKey if it requires 110% certainty that registry changes are on disk. If you don't know whether a RegFlushKey call is required, it probably isn't.

See Also

»RegCloseKey«, »RegDeleteKey«


  RegGetKeySecurity

LONG RegGetKeySecurity(hkey, SecInf, pSecDesc, lpcbSecDesc)
HKEY  hkey;   /* open handle of key to set */
SECURITY_INFORMATION  SecInf;   /* descriptor contents */
PSECURITY_DESCRIPTOR  pSecDesc;   /* address of descriptor for key  */
LPDWORD  lpcbSecDesc;   /* address of size of buffer and descriptor */

The RegGetKeySecurity function retrieves a copy of the security descriptor protecting the given open registry key.

Parameters

hkey

Identifies an open key for which to retrieve the security descriptor.

SecInf

Specifies a SECURITY_INFORMATION structure that indicates the requested security information. The SECURITY_INFORMATION structure has the following form:

typedef DWORD SECURITY_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5

pSecDesc

Points to a buffer that receives a copy of the requested security descriptor.

lpcbSecDesc

Points to a variable that specifies the size, in bytes, of the buffer pointed to by the pSecDesc parameter. When the function returns, the variable contains the number of bytes written to the buffer.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

If the buffer specified by the pSecDesc parameter is too small, the function returns ERROR_INSUFFICIENT_BUFFER and the lpcbSecDesc parameter contains the number of bytes required for the requested security descriptor.

To read the security descriptor for the given key, the calling process must have been granted READ_CONTROL access when the key was opened, or it must be the owner of the key. (READ_CONTROL access is granted by the KEY_READ, KEY_WRITE, KEY_EXECUTE, and KEY_ALL_ACCESS access rights.) In addition, the caller must have the SE_SECURITY_NAME privilege to read the system access-control list (SACL). For more information about security, see Chapter 49, "Security," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»RegDeleteKey«, »RegOpenKeyEx«, »RegSetKeySecurity«


  RegisterClass

ATOM RegisterClass(lpwc)
CONST WNDCLASS  *lpwc;   /* address of structure with class data */

The RegisterClass function registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function.

Parameters

lpwc

Points to a WNDCLASS structure. You must fill the structure with the appropriate class attributes before passing it to the function. The WNDCLASS structure has the following form:

typedef struct tagWNDCLASS {    /* wc */

    UINT    style;

    WNDPROC lpfnWndProc;

    int     cbClsExtra;

    int     cbWndExtra;

    HANDLE  hInstance;

    HICON   hIcon;

    HCURSOR hCursor;

    HBRUSH  hbrBackground;

    LPCTSTR lpszMenuName;

    LPCTSTR lpszClassName;

} WNDCLASS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is an atom that uniquely identifies the class being registered; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

All window classes registered by an application are unregistered when it terminates.

See Also

»CreateWindow«, »CreateWindowEx«, »GetClassInfo«, »GetClassName«, »UnregisterClass«, »WindowProc«


  RegisterClipboardFormat

UINT RegisterClipboardFormat(lpszFormat)
LPCTSTR  lpszFormat;   /* address of name string */

The RegisterClipboardFormat function registers a new clipboard format. This format can then be used as a valid clipboard format.

Parameters

lpszFormat

Points to a null-terminated string that names the new format.

Return Value

If the function succeeds, the return value identifies the registered clipboard format; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

If a registered format with the specified name already exists, a new format is not registered and the return value identifies the existing format. This enables more than one application to copy and paste data using the same registered clipboard format.

Registered clipboard formats are identified by values in the range 0xC000 through 0xFFFF.

See Also

»CountClipboardFormats«, »EnumClipboardFormats«, »GetClipboardFormatName«


  RegisterDialogClasses

BOOL RegisterDialogClasses(hinst)
HANDLE  hinst;   /* handle of application instance */

The RegisterDialogClasses function registers any nonstandard window classes required by a screen saver's configuration dialog box.

Parameters

hinst

Identifies an instance of the module registering the window classes.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The RegisterDialogClasses function should not be exported. It is called by routines defined in the SCRNSAVE.LIB file.

If a screen saver does not register any special window classes for the configuration dialog box, the RegisterDialogClasses function must return TRUE.

See Also

»ScreenSaverConfigureDialog«


  RegisterEventSource

HANDLE RegisterEventSource(lpszUNCServer, lpszSource)
LPTSTR  lpszUNCServer;   /* server name for source */
LPTSTR  lpszSource;   /* source name for registered handle */

The RegisterEventSource function returns a handle that can be used with the ReportEvent function to log an event.

Any source name can be used; it will be carried in the event log record so that Event Viewer can use it for filtering.

Parameters

lpszUNCServer

Points to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which this operation is to be performed. If this parameter is NULL, the operation is performed on the local computer.

lpszSource

Points to a null-terminated string that specifies the name of the source referenced by the returned handle. The source name must be a subkey of a logfile entry under the EventLog key in the registry. For example, the source name WinApp would be valid if the registry had the following form:

HKEY_LOCAL_MACHINE

  System

    CurrentControlSet

      Services

        EventLog

          Application

            WinApp

          Security

          System

If the source name cannot be found, the event logging service uses the Application logfile with no message files for the event identifier or category.

Return Value

If the function succeeds, the return value is a handle that can be used with the ReportEvent function; otherwise, the return value is NULL.

See Also

»DeregisterEventSource«, »ReportEvent«


  RegisterHotKey

BOOL RegisterHotKey(hwnd, idHotKey, fuModifiers, uVirtKey)
HWND  hwnd;   /* window to receive hot-key notification */
int  idHotKey;   /* identifier of hot key */
UINT  fuModifiers;   /* key-modifier flags  */
UINT  uVirtKey;   /* virtual-key code */

The RegisterHotKey function defines a hot key for the current thread.

Parameters

hwnd

Identifies the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.

idHotKey

Specifies the identifier of the hot key. No other hot key in the calling thread should have the same identifier. An application must specify a value in the range 0x0000 through 0xBFFF. A shared dynamic-link library (DLL) must specify a value in the range 0xC000 through 0xFFFF (the range returned by the GlobalAddAtom function). To avoid conflicts with hot key identifiers defined by other shared DLLs, a DLL should use the GlobalAddAtom function to obtain the hot key identifier.

fuModifiers

Specifies keys that must be pressed in combination with the key specified by the nVirtKey parameter in order to generate the WM_HOTKEY message. The fuModifiers parameter can be a combination of the following values:

Value	Meaning
MOD_ALT	Either ALT key must be held down.
MOD_CONTROL	Either CTRL key must be held down.
MOD_SHIFT	Either SHIFT key must be held down.
uVirtKey

Specifies the virtual-key code of the hot key.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

When a key is pressed, the system looks for a match against all thread hot keys. Upon finding a match, the system posts the WM_HOTKEY message to the message queue of the thread that registered the hot key. This message is posted to the beginning of the queue so it is removed by the next iteration of the message loop.

This function cannot associate a hot key with a window created by another thread.

RegisterHoyKey fails if the keystrokes specified for the hot key have already been registered by another hot key.

If the window identified by the hwnd parameter already registered a hot key with the same identifier as that specified by the idHotKey parameter, the new values for the fuModifiers and uVirtKey parameters replace the previously specified values for these parameters.

See Also

»UnregisterHotKey«, »WM_HOTKEY«


  RegisterServiceCtrlHandler

SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(lpszServiceName, lpHandlerProc)
LPCTSTR  lpszServiceName;   /* address of name of service */
LPHANDLER_FUNCTION  lpHandlerProc;   /* address of handler function */

The RegisterServiceCtrlHandler function registers a function to handle service control requests for a service.

Parameters

lpszServiceName

Points to a null-terminated string that names the service run by the calling thread. This is the service name that was specified in the CreateService function when the service was created.

lpHandlerProc

Points to the Handler function to be registered.

Return Value

If the function succeeds, the return value is a service status handle; otherwise, it is zero. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_INVALID_NAME	The specified service name is invalid.
ERROR_SERVICE_DOES_NOT_EXIST	The specified service does not exist.
Comments

The ServiceMain function of a new service should immediately call the RegisterServiceCtrlHandler function to register a control handling function with the control dispatcher. This enables the control dispatcher to invoke the specified function when it receives control requests for this service. The threads of the calling process can use the service status handle returned by this function to identify the service in subsequent calls to the SetServiceStatus function.

This function must be called before the first SetServiceStatus call because it returns a service status handle for the caller to use so that no other service can inadvertently set this service's status, which is maintained by the service control manager. It also needs to be called before the first SetServiceStatus so that a control handler is in place to field control requests by the time the service specifies the controls it accepts through the SetServiceStatus function.

When the control handler function is invoked with a control request, it must call SetServiceStatus to notify the service control manager of its latest status, regardless of whether the status of the service has changed.

The service status handle does not have to be closed.

See Also

»CreateService«, »Handler«, »ServiceMain«, »SetServiceStatus«


  RegisterWindowMessage

UINT RegisterWindowMessage(lpsz)
LPCTSTR  lpsz;   /* address of message string */

The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout the system. The returned message value can be used when calling the SendMessage or PostMessage function.

Parameters

lpsz

Points to a null-terminated string that specifies the message to be registered.

Return Value

If the message is successfully registered, the return value is a message identifier in the range 0xC000 through 0xFFFF; otherwise, it is zero.

Comments

The RegisterWindowMessage function is typically used to register messages for communicating between two cooperating applications.

If two different applications register the same message string, the applications return the same message value. The message remains registered until the Windows session ends.

Only use the RegisterWindowMessage function when more than one application must process the same message. For sending private messages within a window class, an application can use any integer in the range WM_USER through 0x7FFF. (Messages in this range are private to a window class, not to an application. For example, predefined control classes such as BUTTON, EDIT, LISTBOX, and COMBOBOX may use values in this range.)

See Also

»PostAppMessage«, »PostMessage«, »SendMessage«


  RegLoadKey

LONG RegLoadKey(hkey, lpszSubKey, lpszFile)
HKEY  hkey;   /* handle of open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey */
LPCTSTR  lpszFile;   /* address of filename for registry information */

The RegLoadKey function creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores registration information from a specified file into that subkey. This registration information is in the form of a hive. A hive is a discrete body of keys, subkeys, and values that is rooted at the top of the registry hierarchy. A hive is backed by a single file and .log file.

Parameters

hkey

Specifies the key where the subkey will be created. This can be a predefined reserved handle value, or a handle returned by a call to RegConnectRegistry. The predefined reserved handle values are:

HKEY_LOCAL_MACHINE
HKEY_USERS

This function always loads information at the top of the registry hierarchy. The HKEY_CLASSES_ROOT and HKEY_CURRENT_USER handle values cannot be specified for this parameter, because they represent subsets of the HKEY_LOCAL_MACHINE and HKEY_USERS handle values, respectively.

lpszSubKey

Points to a null-terminated string that specifies the name of the key to be created under hkey. This subkey is where the registration information from the file will be loaded.

lpszFile

Points to a null-terminated string containing the name of a file that has registration information. This file must have been created with the RegSaveKey function. Under the file allocation table (FAT) file system, the filename may not have an extension.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

A call to RegLoadKey fails if the calling process does not have the SE_RESTORE_PRIVILEGE privilege.

If hkey is a handle returned by RegConnectRegistry, then the path specified in lpszFile is relative to the remote computer.

See Also

»RegDeleteKey«, »RegReplaceKey«, »RegRestoreKey«, »RegSaveKey«, »RegUnloadKey«


  RegNotifyChangeKeyValue

LONG RegNotifyChangeKeyValue(hkey, fWatchSubTree, fdwNotifyFilter, hEvent, fAsync)
HKEY  hkey;   /* handle of key to watch */
BOOL  fWatchSubTree;   /* flag for subkey notification */
DWORD  fdwNotifyFilter;   /* changes to be reported */
HANDLE  hEvent;   /* handle of signaled event */
BOOL  fAsync;   /* flag for asynchronous reporting */

The RegNotifyChangeKeyValue function indicates when a registry key or any of its subkeys has changed.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

fWatchSubTree

Specifies a flag that indicates whether to report changes in the specified key and all of its subkeys or only in the specified key. If this parameter is TRUE, the function reports changes in the key and its subkeys. If the parameter is FALSE, the function reports changes only in the key.

fdwNotifyFilter

Specifies a set of flags that control which changes should be reported. This parameter can be a combination of the following values:

Value	Meaning
REG_NOTIFY_CHANGE_NAME
	Changes to key names that occur in the specified key or in the specified key and its subkeys cause a change notification. This includes key creations and deletions.
REG_NOTIFY_CHANGE_ATTRIBUTES
	Attribute changes that occur in a key or in a key and its subkeys cause a change notification.
REG_NOTIFY_CHANGE_LAST_SET
	Changes to the last write time that occur in a key or in a key and its subkeys cause a change notification.
REG_NOTIFY_CHANGE_SECURITY
	Security-descriptor changes that occur in a key or in a key and its subkeys cause a change notification.
hEvent

Identifies an event. If the fAsync parameter is TRUE, the function returns immediately and changes are reported by signaling this event. If fAsync is FALSE, hEvent is ignored.

fAsync

Specifies a flag that indicates how the function reports changes. If this parameter is TRUE, the function returns immediately and reports changes by signaling the given event. When this parameter is FALSE, the function does not return until a change has occurred.

If hEvent does not specify a valid event, the fAsync parameter cannot be TRUE.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

If the key identified by the hkey parameter is closed, the event is signaled. This means that an application should not depend on the key being open after returning from a wait operation on the event.

See Also

»RegDeleteKey«, »RegEnumKey«, »RegEnumKeyEx«, »RegEnumValue«, »RegQueryInfoKey«, »RegQueryValue«, »RegQueryValueEx«


  RegOpenKey

LONG RegOpenKey(hkey, lpszSubKey, phkResult)
HKEY  hkey;   /* handle of open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey to open  */
PHKEY  phkResult;   /* address of handle of open key */

The RegOpenKey function opens the specified key. This function is provided for compatibility with Windows version 3.1. New applications should use the RegOpenKeyEx function.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

The key opened by the RegOpenKey function is a subkey of the key identified by hkey.

lpszSubKey

Points to a null-terminated string containing the name of the key to open. This key must be a subkey of the key identified by the hkey parameter. If this parameter is NULL or a pointer to an empty string, the function returns the same handle that was passed in.

phkResult

Points to a variable that receives the handle of the opened key.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The RegOpenKey function uses the default security access mask to open a key. If opening the key requires a different mask, the function fails, returning ERROR_ACCESS_DENIED. An application should use the RegOpenKeyEx function to specify an access mask in this situation.

Unlike the RegCreateKey function, RegOpenKey does not create the specified key if the key does not exist in the database.

See Also

»RegCreateKey«, »RegCreateKeyEx«, »RegDeleteKey«, »RegOpenKeyEx«


  RegOpenKeyEx

LONG RegOpenKeyEx(hkey, lpszSubKey, dwReserved, samDesired, phkResult)
HKEY  hkey;   /* handle of open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey to open */
DWORD  dwReserved;   /* reserved */
REGSAM  samDesired;   /* security access mask */
PHKEY  phkResult;   /* address of handle of open key */

The RegOpenKeyEx function opens the specified key.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszSubKey

Points to a null-terminated string containing the name of the subkey to open. If this parameter is NULL or a pointer to an empty string, the function will open a new handle of the key identified by the hKey parameter. In this case, the function will not close the handles perviously opened.

dwReserved

Reserved; must be zero.

samDesired

Specifies an access mask that describes the desired security access for the new key. This parameter can be a combination of the following values:

Value	Meaning
KEY_ALL_ACCESS	Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access.
KEY_CREATE_LINK	Permission to create a symbolic link.
KEY_CREATE_SUB_KEY	Permission to create subkeys.
KEY_ENUMERATE_SUB_KEYS	Permission to enumerate subkeys.
KEY_EXECUTE	Permission for read access.
KEY_NOTIFY	Permission for change notification.
KEY_QUERY_VALUE	Permission to query subkey data.
KEY_READ	Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
KEY_SET_VALUE	Permission to set subkey data.
KEY_WRITE	Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.
phkResult

Points to a variable that receives the handle of the opened key.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

Unlike the RegCreateKeyEx function, the RegOpenKeyEx function does not create the specified key if the key does not exist in the registry.

See Also

»RegCreateKeyEx«, »RegDeleteKey«, »RegOpenKey«


  RegQueryInfoKey

LONG RegQueryInfoKey (hkey, lpszClass, lpcchClass, lpdwReserved, lpcSubKeys,
lpcchMaxSubkey, lpcchMaxClass, lpcValues, lpcchMaxValueName, lpcbMaxValueData,
lpcbSecurityDescriptor, lpftLastWriteTime)
HKEY  hkey;   /* handle of key to query */
LPTSTR  lpszClass;   /* address of buffer for class string */
LPDWORD  lpcchClass;   /* address of size of class string buffer */
LPDWORD  lpdwReserved;   /* reserved */
LPDWORD  lpcSubKeys;   /* address of buffer for number of subkeys */
LPDWORD  lpcchMaxSubkey;   /* address of buffer for longest subkey name length */
LPDWORD  lpcchMaxClass;   /* address of buffer for longest class string length */
LPDWORD  lpcValues;   /* address of buffer for number of value entries */
LPDWORD  lpcchMaxValueName;   /* address of buffer for longest value name length */
LPDWORD  lpcbMaxValueData;   /* address of buffer for longest value data length */
LPDWORD  lpcbSecurityDescriptor;   /* address of buffer for security descriptor length */
PFILETIME  lpftLastWriteTime;   /* address of buffer for last write time */

The RegQueryInfoKey function retrieves information about a specified registry key.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszClass

Points to a buffer that receives the key's class name.

lpcchClass

Points to a variable that specifies the size, in characters, of the buffer pointed to by the lpszClass parameter. This size should include the terminating null character. When the function returns, this variable contains the length of the class string stored in the buffer. The count returned does not include the terminating null character. If the buffer is not big enough, the function returns ERROR_MORE_DATA, and the variable contains the size of the string, in characters, without counting the null character.

lpdwReserved

Reserved; must be NULL.

lpcSubKeys

Points to a variable that receives the number of subkeys contained by the specified key.

lpcchMaxSubkey

Points to a variable that receives the length, in characters, of the key's subkey with the longest name. The count returned does not include the terminating null character.

lpcchMaxClass

Points to a variable that receives the length, in characters, of the longest string specifying a subkey class. The count returned does not include the terminating null character.

lpcValues

Points to a variable that receives the number of values associated with the key.

lpcchMaxValueName

Points to a variable that receives the length, in characters, of the key's longest value name. The count returned does not include the terminating null character.

lpcbMaxValueData

Points to a variable that receives the length, in bytes, of the longest data component among the key's values.

lpcbSecurityDescriptor

Points to a variable that receives the length, in bytes, of the key's security descriptor.

lpftLastWriteTime

Points to a variable that receives a FILETIME structure, indicating the last time the key or any of its value entries was modified. The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The key identified by the hkey parameter must have been opened with KEY_QUERY_VALUE access (KEY_READ access includes KEY_QUERY_VALUE access).

See Also

»RegDeleteKey«, »RegEnumKey«, »RegEnumKeyEx«, »RegEnumValue«, »RegQueryValue«, »RegQueryValueEx«


  RegQueryValue

LONG RegQueryValue(hkey, lpszSubKey, lpszValue, pcbValue)
HKEY  hkey;   /* handle of key to query */
LPCTSTR  lpszSubKey;   /* address of name of subkey to query */
LPTSTR  lpszValue;   /* address of buffer for returned string */
PLONG  pcbValue;   /* address of buffer for size of returned string */

The RegQueryValue function retrieves the value associated with the unnamed value for a specified key in the registry. Values in the Windows NT registry have name, type, and data components. This function retrieves the data for a key's first value that has a NULL name. This function is provided for compatibility with Windows version 3.1. New applications should use the RegQueryValueEx function.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszSubKey

Points to a null-terminated string containing the name of the subkey of the hkey parameter for which a value is to be retrieved. If this parameter is NULL or points to an empty string, the function retrieves the value set by the RegSetValue function for the key identified by hkey.

lpszValue

Points to a buffer that receives the value associated with the lpszSubKey parameter. The buffer should be big enough to contain the terminating null character. This parameter can be NULL if the data is not required.

If lpszValue is NULL, and pcbValue is not NULL, the function places the size in bytes of the data referenced by the value key, including the NULL terminator, into the variable pointed to by pcbValue. This lets an application determine how to best pre-allocate a buffer for the value key's data.

pcbValue

Points to a variable specifying the size, in bytes, of the buffer pointed to by the lpszValue parameter. When the function returns, this variable contains the size of the data copied to lpszValue, including the terminating NULL character.

If the buffer specified by lpszValue parameter is not large enough to hold the data, the function returns the value ERROR_MORE_DATA, and stores the required buffer size, in bytes, into the variable pointed to by pcbValue.

If lpszValue is NULL, the function returns ERROR_SUCCESS, and stores the size of the string, in bytes, into the variable pointed to by pcbValue. This lets an application determine the best way to allocate a buffer for the value key's data.

In all cases the value returned in pcbValue always incudes the size of the terminating NULL character in the string.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The key identified by the hkey parameter must have been opened with KEY_QUERY_VALUE access (KEY_READ access includes KEY_QUERY_VALUE access).

If the ANSI version of this function is used (either by explicitly calling RegQueryValue or by not defining UNICODE before including the WINDOWS.H file), this function converts the stored Unicode string to an ANSI string before copying it to the buffer specified by the lpszValue parameter.

See Also

»RegEnumKey«, »RegEnumKeyEx«, »RegEnumValue«, »RegQueryInfoKey«, »RegQueryValueEx«, »RegSetValue«, »RegSetValueEx«


  RegQueryValueEx

LONG RegQueryValueEx(hkey, lpszValueName, lpdwReserved, lpdwType, lpbData, lpcbData)
HKEY  hkey;   /* handle of key to query */
LPTSTR  lpszValueName;   /* address of name of value to query */
LPDWORD  lpdwReserved;   /* reserved */
LPDWORD  lpdwType;   /* address of buffer for value type */
LPBYTE  lpbData;   /* address of data buffer */
LPDWORD  lpcbData;   /* address of data buffer size */

The RegQueryValueEx function retrieves the type and data for a specified value name associated with an open registry key.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszValueName

Points to a null-terminated string containing the name of the value to be queried.

lpdwReserved

Reserved; must be NULL.

lpdwType

Points to a variable that receives the key's value type. The value returned through this parameter will be one of the following:

Value	Meaning
REG_BINARY	Binary data in any form.
REG_DWORD	A 32-bit number.
REG_DWORD_LITTLE_ENDIAN	A 32-bit number in little-endian format (same as REG_DWORD). In little-endian format, the most significant byte of a word is the high-order word. This is the most common format for computers running Windows NT.
REG_DWORD_BIG_ENDIAN	A 32-bit number in big-endian format. In big-endian format, the most significant byte of a word is the low-order word.
REG_EXPAND_SZ	A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
REG_LINK	A Unicode symbolic link.
REG_MULTI_SZ	An array of null-terminated strings, terminated by two null characters.
REG_NONE	No defined value type.
REG_RESOURCE_LIST	A device-driver resource list.
REG_SZ	A null-terminated string. It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
The lpdwType parameter can be NULL if the type is not required.

lpbData

Points to a buffer that receives the value's data. This parameter can be NULL if the data is not required.

lpcbData

Points to a variable that specifies the size, in bytes, of the buffer pointed to by the lpbData parameter. When the function returns, this variable contains the size of the data copied to lpbData.

If the buffer specified by lpbData parameter is not large enough to hold the data, the function returns the value ERROR_MORE_DATA, and stores the required buffer size, in bytes, into the variable pointed to by lpcbData.

If lpbData is NULL, and lpcbData is non-NULL, the function returns ERROR_SUCCESS, and stores the size of the data, in bytes, into the variable pointed to by lpcbData. This lets an application determine the best way to allocate a buffer for the value key's data.

If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, then lpData will also include the size of the terminating NULL character.

The lpcbData parameter may be NULL only if lpbData is NULL.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The key identified by hkey must have been opened with KEY_QUERY_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

This function does not expand the environment-variable names in the value data when the value type is REG_EXPAND_SZ. The ExpandEnvironmentStrings function can be used to expand the environment-variable names.

If the value data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, and the ANSI version of this function is used (either by explicitly calling RegQueryValueEx or by not defining UNICODE before including the WINDOWS.H file), this function converts the stored Unicode string to an ANSI string before copying it to the buffer pointed to by lpbData.

When calling the RegQueryValueEx function with hkey set to the HKEY_PERFORMANCE_DATA handle and a value string of a specified object, the returned data structure sometimes has unrequested objects. Don't be surprised; this is normal behavior. When calling the RegQueryValueEx function, you should always expect to walk the returned data structure to look for the requested object.

See Also

»ExpandEnvironmentStrings«, »RegEnumKey«, »RegEnumKeyEx«, »RegEnumValue«, »RegQueryInfoKey«, »RegQueryValue«


  RegReplaceKey

LONG RegReplaceKey(hkey, lpszSubKey, lpszNewFile, lpszBackupFile)
HKEY  hkey;   /* handle of open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey */
LPCTSTR  lpszNewFile;   /* address of filename for file with new data  */
LPCTSTR  lpszBackupFile;   /* address of filename for backup file */

The RegReplaceKey function replaces the file backing a key and all its subkeys with another file, so that when the system is next started, the key and subkeys will have the values stored in the new file.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszSubKey

Points to a null-terminated string containing the name of a key whose subkeys and values are replaced by this function. This key must be a subkey of the key identified by the hkey parameter. This parameter can be NULL.

The selected key must be the root of a hive; that is, it must be an immediate descendent of HKEY_LOCAL_MACHINE or HKEY_USERS.

lpszNewFile

Points to a null-terminated string containing the name of the file with registration information. This file is typically created by using the RegSaveKey function. Under the file allocation table (FAT) file system, the filename may not have an extension.

lpszBackupFile

Points to a null-terminated string containing the name of a file that receives a backup copy of the registry information being replaced. If this file is created under the FAT file system, it should not have an extension.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

The file specified by the lpszNewFile parameter remains open until the system is restarted.

A process must have the SE_RESTORE_NAME privilege to call this function. For more information about privileges, see Chapter 49, "Security."

If hkey is a handle  returned by RegConnectRegistry, then the paths specified in lpszNewFile and lpszBackupFile are relative to the remote computer.

See Also

»RegDeleteKey«, »RegLoadKey«, »RegRestoreKey«


  RegRestoreKey

LONG RegRestoreKey(hkey, lpszFile, fdw)
HKEY  hkey;   /* handle of key where restore begins */
LPCTSTR  lpszFile;   /* address of filename containing saved tree  */
DWORD  fdw;   /* optional flags */

The RegRestoreKey function reads the registry information in a specified file and loads it into a given key. This registry information may be in the form of a key and multiple levels of subkeys.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

Any information contained in this key and its descendent keys is overwritten by the information in the file pointed to by the lpszFile parameter.

lpszFile

Points to a null-terminated string containing the name of the file with registry information. This file is typically created by using the RegSaveKey function. Under the file allocation table (FAT) file system, the filename may not have an extension.

fdw

Specifies a flag indicating whether the key is volatile. (A volatile key is valid only until the next time the system is started.) This parameter is optional; if no value is specified, the key is not volatile.

This parameter can be the REG_WHOLE_HIVE_VOLATILE flag set. Instead of restoring the given key, this flag causes a new, volatile (memory only) set of registry information to be created. (A hive is a large set of registry information, typically containing all of the pertinent information for part of the system. For example, HKEY_LOCAL_MACHINE\Hardware is a volatile hive.)

If REG_WHOLE_HIVE_VOLATILE is specified, the key identified by the hkey parameter must be either the HKEY_USERS or HKEY_LOCAL_MACHINE value.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

If the calling process does not have the SE_RESTORE_NAME privilege or if any subkeys of the hkey parameter are open, ReqRestoreKey fails. For more information about privileges, see Chapter 49, "Security."

This function replaces the keys and values below the given key with the keys and values that are subsidiary to the top-level key in the file, no matter what the name of the top-level key in the file might be. For example, hkey might identify a key A with subkeys B and C, while the lpszFile parameter specifies a file containing key X with subkeys Y and Z. After a call to RegRestoreKey, the registry would contain key A with subkeys Y and Z. The value entries of A would be replaced by the value entries of X.

The new information in the file specified by lpszFile overwrites the contents of the key specified by the hKey parameter, except for the key name.

If hkey represents a key in a remote computer, the path described by lpszFile is relative to the remote computer.

See Also

»RegDeleteKey«, »RegLoadKey«, »RegReplaceKey«, »RegSaveKey«


  RegSaveKey

LONG RegSaveKey(hkey, lpszFile, lpsa)
HKEY  hkey;   /* handle of key where save begins */
LPCTSTR  lpszFile;   /* address of filename to save to */
LPSECURITY_ATTRIBUTES  lpsa;   /* address of security structure */

The RegSaveKey function saves the given key and all of its subkeys and values to a new file.

Parameters

hkey

Specifies a handle of the key where the save operation is to begin, or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszFile

Points to a null-terminated string containing the name of the file in which the given key and subkeys are saved. This file cannot already exist. If this filename includes an extension, it cannot be used on file allocation table (FAT) file systems by the RegLoadKey, RegReplaceKey, or RegRestoreKey function.

lpsa

Points to a SECURITY_ATTRIBUTES structure for the new file. If this parameter is NULL, the file receives a default security descriptor. The SECURITY_ATTRIBUTES structure has the following form:

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

If hkey represents a key on a remote computer, the path described by lpszFile is relative to the remote computer.

Requires SeBackupPrivilege. The caller of this function must posses the SeBackupPrivilege security privilege.

See Also

»RegDeleteKey«, »RegLoadKey«, »RegReplaceKey«, »RegRestoreKey«


  RegSetKeySecurity

LONG RegSetKeySecurity(hkey, si, psd)
HKEY  hkey;   /* open handle of key to set */
SECURITY_INFORMATION  si;   /* descriptor contents */
PSECURITY_DESCRIPTOR  psd;   /* address of descriptor to for key */

The RegSetKeySecurity function sets the security of an open registry key.

Parameters

hkey

Identifies an open key for which the security descriptor is set.

si

Specifies a SECURITY_INFORMATION structure that indicates the contents of the supplied security descriptor. The SECURITY_INFORMATION structure has the following form:

typedef DWORD SECURITY_INFORMATION;

For more information about this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Because subkeys are not ordered, any new subkey will have an arbitrary index. This means the function may return subkeys in any order.

psd

Points to a SECURITY_DESCRIPTOR structure that specifies the security attributes to set for the specified key.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

This function succeeds only if the following conditions are met:

•	If the key's owner or group is being set, the caller must have WRITE_OWNER permission or have the SE_TAKE_OWNERSHIP_NAME privilege.

•	If the key's discretionary access-control list (DACL) is being set, the caller must have WRITE_DAC permission or be the object's owner.

•	If the key's system access-control list (SACL) is being set, the caller must have the SE_SECURITY_NAME privilege.

If hkey is one of the predefined keys, the predefined key should be closed with RegCloseKey. That ensures that the new security information is in effect the next time the predefined key is referenced.

For more information about privileges, see Chapter 49, "Security," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»RegDeleteKey«, »RegGetKeySecurity«


  RegSetValue

LONG RegSetValue(hkey, lpszSubKey, fdwType, lpszData, cbData)
HKEY  hkey;   /* handle of key to set value for */
LPCTSTR  lpszSubKey;   /* address of subkey name */
DWORD  fdwType;   /* type of value */
LPCTSTR  lpszData;   /* address of value data  */
DWORD  cbData;   /* size of value data */

The RegSetValue function associates a value with a specified key. This value must be a text string and cannot have a name. This function is provided for compatibility with Windows version 3.1. New applications should use the RegSetValueEx function, which allows an application to set any number of named values of any data type.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszSubKey

Points to a null-terminated string containing the name of the subkey with which a value is associated. This parameter can be Null or a pointer to an empty string. In this case, the value will be added to the key identified by the hKey parameter.

fdwType

Specifies the type of information to be stored. This parameter must be the REG_SZ type. To store other data types, use the RegSetValueEx function.

lpszData

Points to a null-terminated string containing the value to set for the given key.

cbData

Specifies the length, in characters, of the string pointed to by the lpszData parameter, not including the terminating null character.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

If the key specified by the lpszSubKey parameter does not exist, the RegSetValue function creates it.

Value lengths are limited by available memory. Long values (more than 2048 bytes) should be stored as files with the filenames stored in the configuration registry. This will help the registry perform efficiently.

The key identified by hkey must have been opened with KEY_SET_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

If the ANSI version of this function is used (either by explicitly calling RegSetValue or by not defining UNICODE before including the WINDOWS.H file), the lpszData parameter must be an ANSI character string. The string is converted to Unicode before it is stored in the registry.

See Also

»RegFlushKey«, »RegQueryValue«, »RegQueryValueEx«, »RegSetValueEx«


  RegSetValueEx

LONG RegSetValueEx(hkey, lpszValueName, dwReserved, fdwType, lpbData, cbData)
HKEY  hkey;   /* handle of key to set value for */
LPCTSTR  lpszValueName;   /* address of value to set */
DWORD  dwReserved;   /* reserved */
DWORD  fdwType;   /* flag for value type */
CONST LPBYTE  lpbData;   /* address of value data  */
DWORD  cbData;   /* size of value data */

The RegSetValueEx function stores data in the value field of an open registry key. It can also set additional value and type information for the given key.

Parameters

hkey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpszValueName

Points to a string containing the name of the value to set. If a value with this name is not already present in the key, the function adds it to the key.

If this parameter is NULL or points to an empty string and the fdwType parameter is the REG_SZ type, this function sets the same value the RegSetValue function would set.

dwReserved

Reserved; must be zero.

fdwType

Specifies the type of information to be stored as the value's data. This parameter can be one of the following values:

Value	Meaning
REG_BINARY	Binary data in any form.
REG_DWORD	A 32-bit number.
REG_DWORD_LITTLE_ENDIAN	A 32-bit number in little-endian format (same as REG_DWORD). In little-endian format, the most significant byte of a word is the high-order word. This is the most common format for computers running Windows NT.
REG_DWORD_BIG_ENDIAN	A 32-bit number in big-endian format. In big-endian format, the most significant byte of a word is the low-order word.
REG_EXPAND_SZ	A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
REG_LINK	A Unicode symbolic link.
REG_MULTI_SZ	An array of null-terminated strings, terminated by two null characters.
REG_NONE	No defined value type.
REG_RESOURCE_LIST	A device-driver resource list.
REG_SZ	A null-terminated string. It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
lpbData

Points to a buffer containing the data to be stored with the specified value name.

cbData

Specifies the size, in bytes, of the information pointed to by the lpbData parameter. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS; otherwise, it is an error value.

Comments

Value lengths are limited by available memory. Long values (more than 2048 bytes) should be stored as files with the filenames stored in the registry. This helps the registry perform efficiently. Application elements such as icons, bitmaps, and executable files should be stored as files and not be placed in the registry.

The key identified by the hkey parameter must have been opened with KEY_SET_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

If fdwType is the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type and the ANSI version of this function is used (either by explicitly calling RegSetValueEx or by not defining UNICODE before including the WINDOWS.H file), the data pointed to by the lpbData parameter must be an ANSI character string. The string is converted to Unicode before it is stored in the registry.

See Also

»RegFlushKey«, »RegQueryValue«, »RegQueryValueEx«, »RegSetValue«


  RegUnLoadKey

LONG RegUnLoadKey(hkey, lpszSubKey)
HKEY  hkey;   /* handle of open key */
LPCTSTR  lpszSubKey;   /* address of name of subkey to unload */

The RegUnLoadKey function unloads the specified key and subkeys from the registry.

Parameters

hkey

Specifies the key to be unloaded. This can be a predefined reserved handle value, or a handle returned by a call to RegConnectRegistry. The predefined reserved handle values are:

HKEY_LOCAL_MACHINE
HKEY_USERS

lpszSubKey

Points to a null-terminated string containing the name of the subkey to be unloaded. The key referred to by the lpszSubKey parameter must have been created by using the RegLoadKey function.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, it is an error code.

Comments

This function removes a hive from the registry but does not modify the file containing the registry information. (A hive is a discrete body of keys, subkeys, and values that is rooted at the top of the registry hierarchy.)

The calling process must have the SE_RESTORE_NAME privilege. For more information about privileges, see Chapter 49, "Security," in the Microsoft Win32 Programmer's Reference, Volume 2.

See Also

»RegDeleteKey«, »RegLoadKey«, »RegRestoreKey«


  ReleaseCapture

BOOL ReleaseCapture(VOID)

The ReleaseCapture function releases the mouse capture from a window in the current thread and restores normal mouse input processing. A window that has captured the mouse receives all mouse input, regardless of the position of the cursor, except when a mouse button is clicked while the cursor hot spot is in the window of another thread.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

An application calls this function after calling the SetCapture function.

See Also

»GetCapture«, »SetCapture«


  ReleaseDC

int ReleaseDC(hwnd, hdc)
HWND  hwnd;   /* handle of window */
HDC  hdc;   /* handle of device context */

The RealeaseDC function releases a device context (DC), freeing it for use by other applications. The effect of the ReleaseDC function depends on the type of device-context. It frees only common and window DCs. It has no effect on class or private DCs.

Parameters

hwnd

Identifies the window whose DC is to be released.

hdc

Identifies the DC to be released.

Return Value

The return value specifies whether the DC is released. It is 1 if the DC is released. Otherwise, it is zero.

Comments

The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common DC.

An application cannot use the ReleaseDC function to release a DC that was created by calling the CreateDC function; instead, it must use the DeleteDC function.

See Also

»CreateDC« »DeleteDC« »GetDC«, »GetWindowDC«


  ReleaseMutex

BOOL ReleaseMutex(hMutex)
HANDLE  hMutex;   /* handle of mutex object */

The ReleaseMutex function releases ownership of the specified mutex object.

Parameters

hMutex

Identifies the mutex object. The CreateMutex or OpenMutex function returns this handle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ReleaseMutex function fails if the calling thread does not own the mutex object.

A thread gets ownership of a mutex by specifying a handle of the mutex in one of the wait functions. The thread that creates a mutex object can also get immediate ownership without using one of the wait functions. When the owning thread no longer needs to own the mutex object, it calls the ReleaseMutex function.

While a thread has ownership of a mutex, it can specify the same mutex in additional wait-function calls without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait.

See Also

»CreateMutex«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  ReleaseSemaphore

BOOL ReleaseSemaphore(hSemaphore, cReleaseCount, lplPreviousCount)
HANDLE  hSemaphore;   /* handle of the semaphore object */
LONG  cReleaseCount;   /* amount to add to current count */
LPLONG  lplPreviousCount;   /* address of previous count */

The ReleaseSemaphore function increases the count of the specified semaphore object by a specified amount.

Parameters

hSemaphore

Identifies the semaphore object. The CreateSemaphore or OpenSemaphore function returns this handle, which must have SEMAPHORE_MODIFY_STATE access.

cReleaseCount

Specifies the amount by which the semaphore object's current count is to be increased. The value must be greater than zero. If the specified amount would cause the semaphore's count to exceed the maximum count that was specified when the semaphore was created, the count is not changed and the function returns FALSE.

lplPreviousCount

Points to a 32-bit variable to receive the previous count for the semaphore. This parameter can be NULL if the previous count is not required.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The state of a semaphore object is signaled when its count is greater than zero and nonsignaled when its count is equal to zero. The process that calls the CreateSemaphore function specifies the semaphore's initial count. Each time a waiting thread is released because of the semaphore's signaled state, the count of the semaphore is decreased by one.

Typically, an application uses a semaphore to limit the number of threads using a resource. Before a thread uses the resource, it specifies the semaphore handle in a call to one of the wait functions. When the wait function returns, it decreases the semaphore's count by one. When the thread has finished using the resource, it calls ReleaseSemaphore to increase the semaphore's count by one.

Another use of ReleaseSemaphore is during an application's initialization. The application can create a semaphore with an initial count of zero. This sets the semaphore's state to nonsignaled and blocks all threads from accessing the protected resource. When the application finishes its initialization, it uses ReleaseSemaphore to increase the count to its maximum value, to permit normal access to the protected resource.

See Also

»CreateSemaphore«, »MsgWaitForMultipleObjects«, »OpenSemaphore«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  RemoveDirectory

BOOL RemoveDirectory(lpszDir)
LPTSTR  lpszDir;   /* address of directory to remove */

The RemoveDirectory function deletes an existing empty directory.

Parameters

lpszDir

Points to a null-terminated string that specifies the path of the directory to be removed. The path must specify an empty directory, and the calling process must have delete access to the directory.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreateDirectory«


  RemoveFontModule

BOOL RemoveFontModule(hmodFontRes)
HMODULE  hmodFontRes;   /* handle of loaded module */

The RemoveFontModule function removes the fonts in the specified module from the font table.

Parameters

hmodFontRes

Identifies a loaded module.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application that adds or removes fonts from the Windows font table should notify other windows of the change by sending a WM_FONTCHANGE message to all top-level windows in the system. The application sends this message by calling the SendMessage function with the hWnd parameter set to HWND_BROADCAST.

The RemoveFontModule function may not actually remove the font resource. If there are outstanding references, the font resource remains loaded until no device context is using it.

See Also

»AddFontModule«, »SendMessage«


  RemoveFontResource

BOOL RemoveFontResource(lpFileName)
LPTSTR  lpFileName;   /* address of font-resource filename */

The RemoveFontResource function removes the fonts in the specified file from the Windows font table.

Parameters

lpFileName

Points to a null-terminated string that names a font resource file.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application that adds or removes fonts from the Windows public font table should notify other windows of the change by sending a WM_FONTCHANGE message to all top-level windows in the system. The application sends this message is sent by calling the SendMessage function with the hwnd parameter set to HWND_BROADCAST.

If there are outstanding references to a font, the associated resource remains loaded until no device context is using it.

See Also

»AddFontResource«, »SendMessage«


  RemoveMenu

BOOL RemoveMenu(hmenu, uItem, fuFlags)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item identifier or position  */
UINT  fuFlags;   /* menu item flag */

The RemoveMenu function deletes a menu item from the given menu. If the menu item activates a pop-up menu, RemoveMenu does not destroy the pop-up menu or its handle, allowing the menu to be reused. Before this function is called, the GetSubMenu function should retrieve the handle of the pop-up menu.

Parameters

hmenu

Identifies the menu to be changed.

uItem

Specifies the menu item to be deleted, as determined by the fuFlags parameter.

fuFlags

Specifies how the uItem parameter is interpreted. This parameter must be one of the following values:

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the menu item.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The application must call the DrawMenuBar function whenever a menu changes, whether or not the menu is in a displayed window.

See Also

»CreatePopupMenu«, »DeleteMenu«, »DrawMenuBar«, »GetSubMenu«


  RemoveProp

HANDLE RemoveProp(hwnd, lpsz)
HWND  hwnd;   /* handle of window */
LPCTSTR  lpsz;   /* atom or address of string */

The RemoveProp function removes an entry from the property list of the given window. The given character string identifies the entry to be removed.

Parameters

hwnd

Identifies the window whose property list is to be changed.

lpsz

Points to a null-terminated character string or contains an atom that identifies a string. If this parameter is an atom, it must have been created using the AddAtom function. The atom, a 16-bit value, must be placed in the low-order word of lpsz; the high-order word must be zero.

Return Value

If the function succeeds, the return value identifies the given string. If the string cannot be found in the given property list, the return value is NULL.

Comments

An application must free the data handles associated with entries removed from a property list. The application can remove only those properties it has added. It must not remove properties added by other applications or by Windows itself.

The RemoveProp function returns the data handle associated with the string so that the application can free the data associated with the handle.

See Also

»AddAtom«, »EnumProps«, »EnumPropsEx«, »GetProp«, »SetProp«


  ReplaceText

HWND ReplaceText(lpfr)
LPFINDREPLACE  lpfr;   /* pointer to structure with initialization data */

The ReplaceText function creates a system-defined modeless dialog box that enables the user to find and replace text within a document.

Parameters

lpfr

Points to a FINDREPLACE structure that contains information used to initialize the dialog box. When the user makes a selection in the dialog box, the system fills this structure with information about the user's selection and then sends a message to the application. This message contains a pointer to the FINDREPLACE structure. The FINDREPLACE structure has the following form:

typedef struct {    /* fr */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HINSTANCE    hInstance;

    DWORD        Flags;

    LPSTR        lpstrFindWhat;

    LPSTR        lpstrReplaceWith;

    WORD         wFindWhatLen;

    WORD         wReplaceWithLen;

    DWORD        lCustData;

    LPFRHOOKPROC lpfnHook;

    LPCSTR       lpTemplateName;

} FINDREPLACE;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the window handle of the dialog box, or it is NULL if an error occurs.

Errors

Use the CommDlgExtendedError function to retrieve extended error information, which may be one of the following values:

CDERR_FINDRESFAILURE
CDERR_INITIALIZATION
CDERR_LOADRESFAILURE
CDERR_LOADSTRFAILURE
CDERR_LOCKRESFAILURE
CDERR_MEMALLOCFAILURE
CDERR_MEMLOCKFAILURE
CDERR_NOHINSTANCE
CDERR_NOHOOK
CDERR_NOTEMPLATE
CDERR_STRUCTSIZE
FRERR_BUFFERLENGTHZERO

Comments

The ReplaceText function does not perform a text replacement operation, it simply returns a string typed by the user (as well as related data). An application must perform the replacement using this string.

An application can use the window handle returned by this function to communicate with or to close the dialog box.

The dialog box procedure for ReplaceText passes user requests to the application by sending special messages. The lParam parameter of each of these messages contains a pointer to a FINDREPLACE structure. The procedure sends the messages to the window identified by the hwndOwner member of the FINDREPLACE structure. An application can register the identifier for these messages by specifying the "commdlg_FindReplace" string in a call to the RegisterWindowMessage function.

For the TAB key to function correctly, any application that calls ReplaceText must also call the IsDialogMessage function in its main message loop. (IsDialogMessage returns a value that indicates whether messages are intended for the Replace dialog box.)

See Also

»IsDialogMessage«, »RegisterWindowMessage«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  ReplyMessage

BOOL ReplyMessage(lResult)
LRESULT  lResult;   /* message-dependent reply */

The ReplyMessage function is used to reply to a message sent through the SendMessage function without returning control to the function that called SendMessage.

Parameters

lResult

Specifies the result of the message processing. The possible values are based on the message sent.

Return Value

If the calling thread was processing a message sent from another thread or process, the return value is TRUE; otherwise, it is FALSE.

Comments

By calling this function, the window procedure that receives the message allows the thread that called SendMessage to continue to run as though the thread receiving the message had returned control. The thread that calls the ReplyMessage function also continues to run.

If the message was not sent through the SendMessage function or if the message was sent by the same thread, ReplyMessage has no effect.

See Also

»InSendMessage«, »SendMessage«


  ReportEvent

BOOL ReportEvent(hEventSource, fwEventType, fwCategory, IDEvent, pUserSid,
cStrings, cbData, plpszStrings, lpvData)
HANDLE  hEventSource;   /* handle returned by RegisterEventSource */
WORD  fwEventType;   /* event type to log */
WORD  fwCategory;   /* event category */
DWORD  IDEvent;   /* event identifier */
PSID  pUserSid;   /* user security identifier (optional) */
WORD  cStrings;   /* number of strings to merge with message */
DWORD  cbData;   /* size of raw (binary) data (in bytes) */
LPTSTR  *plpszStrings;   /* array of strings to merge with message  */
LPVOID  lpvData;   /* address of binary data */

The ReportEvent function writes an entry at the end of the given event log.

Parameters

hEventSource

Identifies the event log. This handle is returned by the RegisterEventSource function.

fwEventType

Specifies the type of event being logged. This parameter can be one of the following values:

Value	Meaning
EVENTLOG_ERROR_TYPE	Error event
EVENTLOG_WARNING_TYPE	Warning event
EVENTLOG_INFORMATION_TYPE	Information event
EVENTLOG_AUDIT_SUCCESS	Success Audit event
EVENTLOG_AUDIT_FAILURE	Failure Audit event
For more information about event types, see Chapter 65, "Event Logging," in the Microsoft Win32 Programmer's Reference, Volume 2.

fwCategory

Specifies the event category. This is source-specific information; the category can have any value.

IDEvent

Specifies the event identifier. The event identifier specifies the message that goes with this event as an entry in the message file associated with the event source.

pUserSid

Points to the current user's security identifier. This parameter can be NULL if the security identifier is not required.

cStrings

Specifies the number of strings in the array pointed to by the plpszStrings parameter. A value of zero indicates that no strings are present.

cbData

Specifies the number of bytes of event-specific raw (binary) data to write to the log. If this parameter is zero, no event-specific data is present.

plpszStrings

Points to a buffer containing an array of null-terminated strings that are merged into the message before Event Viewer displays the string to the user. This parameter must be a valid pointer (or NULL), even if cStrings is zero.

lpvData

Points to the buffer containing the binary data. This parameter must be a valid pointer (or NULL), even if the cbData parameter is zero.

Return Value

If the function succeeds, the return value is TRUE, indicating that the entry was written to the log. If the function fails, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

This function is used to log an event. The entry is written to the end of the configured logfile for the source identified by the hEventSource parameter. The ReportEvent function adds the time, the user name, the entry's length, and the offsets before storing the entry in the log.

See Also

»ClearEventLog«, »CloseEventLog«, »OpenEventLog«, »ReadEventLog«


  ResetDC

HDC ResetDC(hdc, lpInitData)
HDC  hdc;   /* handle of device context */
LPDEVMODE  lpInitData;   /* address of structure with DC information */

The ResetDC function updates the given printer or plotter device context (DC), based on the information in the specified structure.

Parameters

hdc

Identifies the device context to update.

lpInitData

Points to a DEVMODE structure containing information about the new device context. The DEVMODE structure has the following form:

typedef struct _devicemode {    /* dvmd */

    TCHAR  dmDeviceName[32];

    WORD   dmSpecVersion;

    WORD   dmDriverVersion;

    WORD   dmSize;

    WORD   dmDriverExtra;

    DWORD  dmFields;

    short  dmOrientation;

    short  dmPaperSize;

    short  dmPaperLength;

    short  dmPaperWidth;

    short  dmScale;

    short  dmCopies;

    short  dmDefaultSource;

    short  dmPrintQuality;

    short  dmColor;

    short  dmDuplex;

    short  dmYResolution;

    short  dmTTOption;

    short  dmCollate;

    TCHAR  dmFormName[32];

    WORD   dmUnusedPadding;

    USHORT dmBitsPerPel;

    DWORD  dmPelsWidth;

    DWORD  dmPelsHeight;

    DWORD  dmDisplayFlags;

    DWORD  dmDisplayFrequency;

} DEVMODE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the original device context. Otherwise, it is NULL.

Comments

An application will typically use the ResetDC function when a window receives a WM_DEVMODECHANGE message. ResetDC can also be used to change the paper orientation or paper bins while printing a document.

The ResetDC function cannot be used to change the driver name, device name, or the output port. When the user changes the port connection or device name, the application must delete the original device context and create a new device context with the new information.

An application can pass an information device context to the ResetDC function. In that situation, ResetDC will always return a printer device context. For more information about device context types, see Chapter 28, "Device Contexts."

See Also

»DeviceCapabilitiesEx«, »Escape«


  ResetEvent

BOOL ResetEvent(hEvent)
HANDLE  hEvent;   /* handle of event object */

The ResetEvent function sets the state of the specified event object to nonsignaled.

Parameters

hEvent

Identifies the event object. The CreateEvent or OpenEvent function returns this handle, which must have EVENT_MODIFY_STATE access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The state of an event object remains nonsignaled until it is explicitly set to signaled by the SetEvent or PulseEvent function. This nonsignaled state blocks the execution of any threads that have specified the event object in a call to one of the wait functions.

The ResetEvent function is used primarily for manual-reset event objects, which must be set explicitly to the nonsignaled state. Auto-reset event objects automatically change from signaled to nonsignaled after a single waiting thread is released.

See Also

»CreateEvent«, »OpenEvent«, »PulseEvent«, »SetEvent«


  ResizePalette

BOOL ResizePalette(hpal, nEntries)
HPALETTE  hpal;
UINT  nEntries;

The ResizePalette function increases or decreases the size of the given logical palette based on the specified value.

Parameters

hpal

Identifies the palette to be changed.

nEntries

Specifies the number of entries in the palette after it has been resized.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

If an application calls ResizePalette to reduce the size of the palette, the entries remaining in the resized palette are unchanged. If the application calls ResizePalette to enlarge the palette, the additional palette entries are set to black (the red, green, and blue values are all 0) and their flags are set to zero.

See Also

»GetDeviceCaps«


  RestoreDC

BOOL RestoreDC(hdc, nSavedDC)
HDC  hdc;   /* handle of device context */
int  nSavedDC;   /* specifies state to be restored */

The RestoreDC function restores the given device context (DC) to the specified state. The DC is restored by popping state information off a stack created by earlier calls to the SaveDC function.

Parameters

hdc

Identifies the DC.

nSavedDC

Specifies the instance of the DC to be restored. If this parameter is positive, nSavedDC represents a specific instance of the DC to be restored. If this parameter is negative, nSavedDC represents an instance relative to the current DC. For example, −1 restores the most recently saved state.

Return Value

If the function succeeds, the return value is TRUE. Otherwise, it is FALSE.

Comments

The stack can contain the state information for several instances of the DC. If the state specified by the given parameter is not at the top of the stack, RestoreDC deletes all state information between the top of the stack and the specified instance.

See Also

»SaveDC«


  ResultCallBack

VOID CALLBACK ResultCallBack(hwnd, uMsg, dwData, lResult)
HWND  hwnd;   /* handle of destination window */
UINT  uMsg;   /* message */
DWORD  dwData;   /* application-defined value */
LRESULT  lResult;   /* result of message processing */

The ResultCallBack function is a library-defined callback function that the system calls whenever the SendMessageCallback function is called. The system passes the message to the callback function after passing the message to the destination window procedure.

Parameters

hwnd

Identifies the window whose window procedure received the message. If this parameter is HWND_TOPMOST, the message was sent to all top-level windows in the system, including disabled or invisible unowned windows.

uMsg

Specifies the message.

dwData

Specifies an extra value sent from the SendMessageCallback function.

lResult

Specifies the result of the message processing and depends on the message.

Return Value

This callback function does not return a value.

Comments

ResultCallBack is a placeholder for the library-defined function name.

See Also

»SendMessage«, »SendMessageCallback«


  ResumeThread

DWORD ResumeThread(hThread)
HANDLE  hThread;   /* identifies thread to restart */

The ResumeThread function decrements a thread's suspend count. When the suspend count is decremented to zero, the execution of the thread is resumed.

Parameters

hThread

Specifies a handle for the thread to be restarted. The handle must have THREAD_SUSPEND_RESUME access to the thread.

Return Value

If the function succeeds, the return value is the thread's previous suspend count. Otherwise, the return value is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

Comments

The ResumeThread function checks the suspend count of the subject thread. If the suspend count is 0, the thread is not currently suspended. Otherwise, the subject thread's suspend count is decremented. If the resultant value is 0, then the execution of the subject thread is resumed.

If the return value is 0, the specified thread was not suspended. If the return value is 1, the specified thread was suspended but was restarted. If the return value is greater than 1, the specified thread is still suspended. The ResumeThread function must be called the return value minus one times before the thread will start running.

Note that while reporting debug events, all threads within the reporting process are frozen. Debuggers are expected to use the SuspendThread and ResumeThread functions to limit the set of threads that can execute within a process. By suspending all threads in a process except for the one reporting a debug event, it is possible to "single step" a single thread. The other threads are not released by a continue if they are suspended.

See Also

»SuspendThread«


  ReuseDDElParam

LONG ReuseDDElParam(lParam, uMsgIn, uMsgOut, uLow, uHigh)
LONG  lParam;   /* posted lParam to be reused */
UINT  uMsgIn;   /* identifier of received message */
UINT  uMsgOut;   /* identifier of posted message */
UINT  uLow;   /* low-order word of new lParam */
UINT  uHigh;   /* high-order word of new lParam */

The ReuseDDElParam function allows an application to reuse a packed dynamic data exchange (DDE) lParam parameter, rather than allocating a new packed lParam parameter. Using this function reduces reallocations for applications that pass packed DDE messages.

Parameters

lParam

Specifies the lParam parameter of the posted DDE message being reused.

uMsgIn

Specifies the identifier of the received DDE message.

uMsgOut

Specifies the identifier of the DDE message to be posted. The DDE message will reuse the packed lParam parameter.

uLow

Specifies the value to be packed into the low-order word of the reused lParam parameter.

uHigh

Specifies the value to be packed into the high-order word of the reused lParam parameter.

Return Value

If the function succeeds, the return value is nonzero; otherwise, it is zero.

Comments

The return value must be posted as the lParam parameter of a DDE message; it must not be used for any other purpose. Once the return value is posted, the posting application need not perform any action to dispose of the lParam parameter.

Use the ReuseDDElParam function instead of the FreeDDElParam function if the lParam parameter will be reused in a responding message. ReuseDDElParam returns the lParam appropriate for reuse.

This function allocates or frees lParam parameters as needed, depending on the packing requirements of the incoming and outgoing messages. This reduces reallocations in passing DDE messages.

See Also

»FreeDDElParam«, »PackDDElParam«, »UnpackDDElParam«


  RevertToSelf

BOOL RevertToSelf(VOID)

The RevertToSelf function terminates the impersonation of a client application.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

It is advisable for a process to call the RevertToSelf function after finishing any impersonation begun by using the DdeImpersonateClient, ImpersonateNamedPipeClient, or ImpersonateSelf function.

See Also

»DdeImpersonateClient«, »ImpersonateNamedPipeClient«, »ImpersonateSelf«


  RoundRect

BOOL RoundRect(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect, nWidth, nHeight)
HDC  hdc;   /* handle of device context */
int  nLeftRect;   /* x-coord. of bounding rect. upper-left corner */
int  nTopRect;   /* y-coord. of bounding rect. upper-left corner */
int  nRightRect;   /* x-coord. of bounding rect. lower-right corner */
int  nBottomRect;   /* y-coord. of bounding rect. lower-right corner */
int  nWidth;   /* width of ellipse used to draw rounded corners */
int  nHeight;   /* height of ellipse used to draw rounded corners */

The RoundRect function draws a rectangle with rounded corners. The rectangle is outlined by using the current pen and filled by using the current brush.

Parameters

hdc

Identifies the device context.

nLeftRect

Specifies the x-coordinate of the upper-left corner of the rectangle.

nTopRect

Specifies the y-coordinate of the upper-left corner of the rectangle.

nRightRect

Specifies the x-coordinate of the lower-right corner of the rectangle.

nBottomRect

Specifies the y-coordinate of the lower-right corner of the rectangle.

nWidth

Specifies the width of the ellipse used to draw the rounded corners.

nHeight

Specifies the height of the ellipse used to draw the rounded corners.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The current position is neither used nor updated by this function.

See Also

»Rectangle«


  SaveDC

int SaveDC(hdc)
HDC  hdc;   /* handle of device context */

The SaveDC function saves the current state of the given device context (DC) by copying data describing selected objects and graphic modes (such as the bitmap, brush, palette, font, pen, region, drawing mode, and mapping mode) to a context stack.

Parameters

hdc

Identifies the device context to be saved.

Return Value

If the function succeeds, the return value identifies the saved device context. Otherwise, it is zero.

Comments

The SaveDC function can be used any number of times to save any number of instances of the device context's state.

A saved state can later be restored by using the RestoreDC function.

See Also

»RestoreDC«


  ScaleViewportExt

The ScaleViewportExt function has been deleted. Win32 applications should use the ScaleViewportExtEx function.

See Also

»ScaleViewportExtEx«


  ScaleViewportExtEx

BOOL ScaleViewportExtEx(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize)
HDC  hdc;   /* handle of device context */
int  Xnum;   /* horizontal multiplicand */
int  Xdenom;   /* horizontal divisor */
int  Ynum;   /* vertical multiplicand */
int  Ydenom;   /* vertical divisor */
LPSIZE  lpSize;   /* address of previous viewport extents */

The ScaleViewportExtEx function modifies the viewport for the given device context (DC) by using the ratios formed by the given multiplicands and divisors.

Parameters

hdc

Identifies the DC.

Xnum

Specifies the amount by which to multiply the current horizontal extent.

Xdenom

Specifies the amount by which to divide the current horizontal extent.

Ynum

Specifies the amount by which to multiply the current vertical extent.

Ydenom

Specifies the amount by which to divide the current vertical extent.

lpSize

Points to a SIZE structure. The previous viewport extents (in device units) are placed in this structure. If lpSize is NULL, nothing is returned. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The viewport extents are modified as follows:

    xNewVE = (xOldVE * Xnum) / Xdenom

    yNewVE = (yOldVE * Ynum) / Ydenom

See Also

»GetViewportExtEx«


  ScaleWindowExt

The ScaleWindowExt function has been deleted. Win32 applications should use the ScaleWindowExtEx function.

See Also

»ScaleWindowExtEx«


  ScaleWindowExtEx

BOOL ScaleWindowExtEx(hdc, Xnum, Xdenom, Ynum, Ydenom, lpSize)
HDC  hdc;   /* handle of device context */
int  Xnum;   /* horizontal multiplicand */
int  Xdenom;   /* horizontal divisor */
int  Ynum;   /* vertical multiplicand */
int  Ydenom;   /* vertical divisor */
LPSIZE  lpSize;   /* address of previous window extents */

The ScaleWindowExtEx function modifies the window for the given device context (DC) using the ratios formed by the given multiplicands and divisors.

Parameters

hdc

Identifies the DC.

Xnum

Specifies the amount by which to multiply the current horizontal extent.

Xdenom

Specifies the amount by which to divide the current  horizontal extent.

Ynum

Specifies the amount by which to multiply the current vertical extent.

Ydenom

Specifies the amount by which to divide the current vertical extent.

lpSize

Points to a SIZE structure. The previous window extents (in logical units) are placed in this structure. If lpSize is NULL, nothing is returned. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The window extents are modified as follows:

    xNewWE = (xOldWE * Xnum) / Xdenom

    yNewWE = (yOldWE * Ynum) / Ydenom

See Also

»GetWindowExtEx«


  ScheduleJob

BOOL ScheduleJob(hPrinter, dwJobID)
HANDLE  hPrinter;   /* handle of printer object  */
DWORD  dwJobID;   /* job-identifier value */

The ScheduleJob function informs the print spooler that the specified job can be scheduled for printing.

Parameters

hPrinter

Identifies the printer for which the job is scheduled.

dwJobID

Specifies the print job being scheduled.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter is obtained by calling the OpenPrinter function.

This function should be called after an application calls the AddJob function.

See Also

»AddJob«, »OpenPrinter«


  ScreenSaverConfigureDialog

BOOL ScreenSaverConfigureDialog(hwndDlg, uMsg, wParam, lParam)
HWND  hwndDlg;   /* handle of dialog box */
UINT  uMsg;   /* message */
DWORD  wParam;   /* first message parameter */
LONG  lParam;   /* second message parameter */

The ScreenSaverConfigureDialog function receives messages sent to a screen saver's configuration dialog box. A screen saver that allows user configuration must support this function.

Parameters

hwndDlg

Identifies the configuration dialog box.

uMsg

Specifies the message.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

If the function processes the message, the return value is TRUE; otherwise, it is FALSE, except in response to a WM_INITDIALOG message. In response to a WM_INITDIALOG message, ScreenSaverConfigureDialog should return FALSE if it calls the SetFocus function to set the keyboard focus to one of the controls in the dialog box. Otherwise, the function should return TRUE, in which case the system sets the keyboard focus to the first control in the dialog box that can be given the focus.

Comments

The dialog box template for the configuration dialog box must have the DLG_SCRNSAVECONFIGURE identifier.

The dialog box procedure is used only if the application specifies the default window class (WC_DIALOG) for the dialog box. The application uses the default class if no explicit class is given in the dialog box template. Although the dialog box procedure is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the default dialog box procedure.

The ScreenSaverConfigureDialog function must be exported by including it in the EXPORTS statement in the application's module-definition (.DEF) file.

See Also

»RegisterDialogClasses«


  ScreenSaverProc

LONG ScreenSaverProc(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of screen saver window */
UINT  uMsg;   /* message */
DWORD  wParam;   /* first message parameter */
LONG  lParam;   /* second message parameter */

The ScreenSaverProc function receives messages sent to the given screen saver window.

Parameters

hwnd

Identifies the window.

uMsg

Specifies the message.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value is the result of the message processing and depends on the message sent.

Comments

A screen saver's ScreenSaverProc window procedure should use the DefScreenSaverProc function instead of the DefWindowProc function to provide default message processing. The DefScreenSaverProc function passes any messages that do not affect screen saver operations to DefWindowProc.

The ScreenSaverProc function must be exported by including it in the EXPORTS statement in the application's module-definition (.DEF) file.

See Also

»DefScreenSaverProc«


  ScreenToClient

BOOL ScreenToClient(hwnd, lpPoint)
HWND  hwnd;   /* window handle for source coordinates */
LPPOINT  lpPoint;   /* address of structure containing coordinates */

The ScreenToClient function converts the screen coordinates of a specified point on the screen to client coordinates.

Parameters

hwnd

Identifies the window whose client area will be used for the conversion.

lpPoint

Points to a POINT structure that contains the screen coordinates to be converted. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The function uses the window identified by the hwnd parameter and the screen coordinates given in the POINT structure to compute client coordinates. It then replaces the screen coordinates with the client coordinates. The new coordinates are relative to the upper left corner of the given window's client area.

The ScreenToClient function assumes the given point is in screen coordinates.

See Also

»ClientToScreen«, »MapWindowPoints«


  ScrollConsoleScreenBuffer

BOOL ScrollConsoleScreenBuffer(hConsoleOutput, psrctSourceRect, psrctClipRect,
coordDestOrigin, pchiFill)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
PSMALL_RECT  psrctSourceRect;   /* address of screen buffer rect. to move */
PSMALL_RECT  psrctClipRect;   /* address of affected screen buffer rect. */
COORD  coordDestOrigin;   /* new location of screen buffer rect.  */
PCHAR_INFO  pchiFill;   /* address of fill character and color */

The ScrollConsoleScreenBuffer function moves a block of data in a screen buffer. The effects of the move can be limited by specifying a clipping rectangle, so the contents of the screen buffer outside the clipping rectangle are unchanged.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_WRITE access.

psrctSourceRect

Points to a SMALL_RECT structure whose members specify the upper left and lower right coordinates of the screen buffer rectangle to be moved. The SMALL_RECT structure has the following form:

typedef struct _SMALL_RECT { /* srct */

    SHORT Left;

    SHORT Top;

    SHORT Right;

    SHORT Bottom;

} SMALL_RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

psrctClipRect

Points to a SMALL_RECT structure whose members specify the upper left and lower right coordinates of the screen buffer rectangle that is affected by the scrolling. This pointer can be NULL.

coordDestOrigin

Specifies the upper left corner of the new location of the psrctSourceRect contents.

pchiFill

Points to a CHAR_INFO structure that specifies the character and color attributes to be used in filling the cells within the intersection of psrctSourceRect and psrctClipRect that were left empty as a result of the move. The CHAR_INFO structure has the following form:

typedef struct _CHAR_INFO { /* chi */

    union {                /* Unicode or ANSI character  */

        WCHAR UnicodeChar;

        CHAR AsciiChar;

    } Char;

    WORD Attributes;       /* text and background colors */

} CHAR_INFO, *PCHAR_INFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

ScrollConsoleScreenBuffer copies the contents of a rectangular region of a screen buffer, the psrctSourceRect parameter, to another area of the screen buffer. The target rectangle has the same dimensions as psrctSourceRect with its upper left corner at the coordinates specified by the coordDestOrigin parameter. Those parts of psrctSourceRect, that do not overlap with the target rectangle are filled in with the character and color attributes specified by the pchiFill parameter.

The clipping rectangle applies to changes made in both the psrctSourceRect and the target rectangle. For example, if the clipping rectangle does not include a region that would have been filled by the contents of pchiFill, the original contents of the region are left unchanged.

If the scroll or target regions extend beyond the dimensions of the screen buffer, they are clipped. For example, if psrctSourceRect is the region contained by (0,0) and (19,19) and coordDestOrigin is (10,15), the target rectangle is the region contained by (10,15) and (29,34). However, if the screen buffer is 50 characters wide and 30 characters high, the target rectangle is clipped to (10,15) and (29,29). The changes to the screen buffer are also clipped according to psrctClipRect, if the parameter specifies a SMALL_RECT structure. If the clipping rectangle is specified as (0,0) and (49,19), only the changes that occur in that region of the screen buffer are made.

See Also

»SetConsoleWindowInfo«


  ScrollDC

BOOL ScrollDC(hdc, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate)
HDC  hdc;   /* handle of device context */
int  dx;   /* horizontal scroll units */
int  dy;   /* vertical scroll units */
CONST RECT  *lprcScroll;   /* address of structure for scrolling rectangle */
CONST RECT  *lprcClip;   /* address of structure for clipping rectangle */
HRGN  hrgnUpdate;   /* handle of scrolling region */
LPRECT  lprcUpdate;   /* address of structure for update rectangle */

The ScrollDC function scrolls a rectangle of bits horizontally and vertically.

Parameters

hdc

Identifies the device context that contains the bits to be scrolled.

dx

Specifies the amount, in device units, of horizontal scrolling. This parameter must be a negative value to scroll to the left.

dy

Specifies the amount, in device units, of vertical scrolling. This parameter must be a negative value to scroll up.

lprcScroll

Points to the RECT structure containing the coordinates of the scrolling rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprcClip

Points to the RECT structure containing the coordinates of the clipping rectangle. Only device bits within the clipping rectangle are affected. Bits scrolled from the outside of the rectangle to the inside are painted; bits scrolled from the inside of the rectangle to the outside are not painted.

hrgnUpdate

Identifies the region uncovered by the scrolling process. The ScrollDC function defines this region; it is not necessarily a rectangle.

lprcUpdate

Points to the RECT structure that receives the coordinates of the rectangle bounding the scrolling update region. This is the largest rectangular area that requires repainting. When the function returns, the values in the structure are in client coordinates, regardless of the mapping mode for the given device context. This allows applications to use the update region in a call to the InvalidateRgn function, if required.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the lprcUpdate parameter is NULL, Windows does not compute the update rectangle. If both the hrgnUpdate and lprcUpdate parameters are NULL, Windows does not compute the update region. If hrgnUpdate is not NULL, Windows proceeds as though it contains a valid handle of the region uncovered by the scrolling process (defined by the ScrollDC function).

When you must scroll the entire client area of a window, use the ScrollWindow function; otherwise, use ScrollDC.

See Also

»InvalidateRgn«, »ScrollWindow«


  ScrollWindow

BOOL ScrollWindow(hwnd, dx, dy, lprcScroll, lprcClip)
HWND  hwnd;   /* handle of window to scroll */
int  dx;   /* amount of horizontal scrolling */
int  dy;   /* amount of vertical scrolling */
CONST RECT *  lprcScroll;   /* address of structure with scroll rectangle  */
CONST RECT *  lprcClip;   /* address of structure with clip rectangle */

The ScrollWindow function scrolls the contents of the given window's client area.

Parameters

hwnd

Identifies the window where the client area is to be scrolled.

dx

Specifies the amount, in device units, of horizontal scrolling. This parameter must be a negative value to scroll the contents of the window to the left.

dy

Specifies the amount, in device units, of vertical scrolling. This parameter must be a negative value to scroll the contents of the window up.

lprcScroll

Points to the RECT structure specifying the portion of the client area to be scrolled. If this parameter is NULL, the entire client area is scrolled. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprcClip

Points to the RECT structure containing the coordinates of the clipping rectangle. Only device bits within the clipping rectangle are affected. Bits scrolled from the outside of the rectangle to the inside are painted; bits scrolled from the inside of the rectangle to the outside are not painted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the caret is in the window being scrolled, the ScrollWindow function automatically hides the caret to prevent it from being erased and then restores the caret after the scrolling is finished. The caret position is adjusted accordingly.

The area uncovered by ScrollWindow is not repainted, but it is combined into the window's update region. The application eventually receives a WM_PAINT message notifying it that the region must be repainted. To repaint the uncovered area at the same time the scrolling is in action, call the UpdateWindow function immediately after calling ScrollWindow.

If the lprcScroll parameter is NULL, the positions of any child windows in the window are offset by the amount specified by the dx and dy parameters; invalid (unpainted) areas in the window are also offset. ScrollWindow is faster when lprcScroll is NULL.

If lprcScroll is not NULL, the positions of child windows are not changed and invalid areas in the window are not offset. To prevent updating problems when lprcScroll is not NULL, call UpdateWindow to repaint the window before calling ScrollWindow.

See Also

»ScrollDC«, »ScrollWindowEx«, »UpdateWindow«


  ScrollWindowEx

int ScrollWindowEx(hwnd, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate, fuScroll)
HWND  hwnd;   /* handle of window to scroll */
int  dx;   /* amount of horizontal scrolling */
int  dy;   /* amount of vertical scrolling */
CONST RECT  *lprcScroll;   /* address of structure with scroll rectangle */
CONST RECT  *lprcClip;   /* address of structure with clip rectangle */
HRGN  hrgnUpdate;   /* handle of update region */
LPRECT  lprcUpdate;   /* address of structure for update rectangle  */
UINT  fuScroll;   /* scrolling flags */

The ScrollWindowEx function scrolls the contents of the given window's client area. This function is similar to the ScrollWindow function, but it has additional features.

Parameters

hwnd

Identifies the window where the client area is to be scrolled.

dx

Specifies the amount, in device units, of horizontal scrolling. This parameter must be a negative value to scroll to the left.

dy

Specifies the amount, in device units, of vertical scrolling. This parameter must be a negative value to scroll up.

lprcScroll

Points to the RECT structure specifying the portion of the client area to be scrolled. If this parameter is NULL, the entire client area is scrolled. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprcClip

Points to the RECT structure containing the coordinates of the clipping rectangle. Only device bits within the clipping rectangle are affected. Bits scrolled from the outside of the rectangle to the inside are painted; bits scrolled from the inside of the rectangle to the outside are not painted.

hrgnUpdate

Identifies the region that is modified to hold the region invalidated by scrolling. This parameter may be NULL.

lprcUpdate

Points to the RECT structure receiving the boundaries of the rectangle invalidated by scrolling. This parameter may be NULL.

fuScroll

Specifies flags that control scrolling. This parameter can be one of the following values:

Value	Meaning
SW_ERASE	Erases the newly invalidated region by sending a WM_ERASEBKGND message to the window when specified with the SW_INVALIDATE flag.
SW_INVALIDATE	Invalidates the region identified by the hrgnUpdate parameter after scrolling.
SW_SCROLLCHILDREN	Scrolls all child windows that intersect the rectangle pointed to by the lprcScroll parameter. The child windows are scrolled by the number of pixels specified by the dx and dy parameters. Windows sends a WM_MOVE message to all child windows that intersect the lprcScroll rectangle, even if they do not move.
Return Value

If the function succeeds, the return value is SIMPLEREGION (rectangular invalidated region), COMPLEXREGION (nonrectangular invalidated region; overlapping rectangles), or NULLREGION (no invalidated region). Otherwise, the return value is ERROR.

Comments

If the SW_INVALIDATE and SW_ERASE flags are not specified, the ScrollWindowEx function does not invalidate the area that is scrolled away from. If either of these flags is set, ScrollWindowEx invalidates this area. The area is not updated until the application calls the UpdateWindow function, calls the RedrawWindow function (specifying the RDW_UPDATENOW or RDW_ERASENOW flag), or retrieves the WM_PAINT message from the application queue.

If the window has the WS_CLIPCHILDREN style, the returned areas specified by the hrgnUpdate and lprcUpdate parameters represent the total area of the scrolled window that must be updated, including any areas in child windows that need updating.

If the SW_SCROLLCHILDREN flag is specified, Windows does not properly update the screen if part of a child window is scrolled. The part of the scrolled child window that lies outside the source rectangle is not erased and is not redrawn properly in its new destination. To move child windows that do not lie completely within the rectangle specified by the lprcScroll parameter, use the DeferWindowPos function. The cursor is repositioned if the SW_SCROLLCHILDREN flag is set and the caret rectangle intersects the scroll rectangle.

All input and output coordinates (for the lprcScroll, lprcClip, lprcUpdate, and hrgnUpdate parameters) are determined as client coordinates, regardless of whether the window has the CS_OWNDC or CS_CLASSDC class style. Use the LPtoDP and DPtoLP functions to convert to and from logical coordinates, if necessary.

See Also

»DeferWindowPos«, »DPtoLP«, »LPtoDP«, »RedrawWindow«, »ScrollDC«, »ScrollWindow«, »UpdateWindow«


  SearchPath

DWORD SearchPath(lpszPath, lpszFile, lpszExtension, cchReturnBuffer,
lpszReturnBuffer, plpszFilePart)
LPCTSTR  lpszPath;   /* address of the search path */
LPCTSTR  lpszFile;   /* address of the filename */
LPCTSTR  lpszExtension;   /* address of the extension */
DWORD  cchReturnBuffer;   /* size, in characters, of the buffer */
LPTSTR  lpszReturnBuffer;   /* address of buffer for found filename  */
LPTSTR  *plpszFilePart;   /* address of pointer to file part */

The SearchPath function searches for the specified file.

Parameters

lpszPath

Points to a null-terminated string that specifies the path to be searched for the file. If lpszPath is NULL, the function searches for a matching file in the following directories, in the order shown:

1.	The directory from which the application loaded.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

lpszFile

Points to a null-terminated string that specifies the name of the file to search for.

lpszExtension

Points to a null-terminated string that specifies an extension to be added to the filename when searching for the file. The first character of the extension must be a period (.). The extension is added only if the specified filename does not end with an extension.

If a file extension is not required or if the filename contains an extension, this parameter can be NULL.

cchReturnBuffer

Specifies the length, in characters, of the buffer that receives the valid path and filename.

lpszReturnBuffer

Points to the buffer for the valid path and filename of the file found.

plpszFilePart

Specifies the address (within lpszReturnBuffer) of the last component of the valid path and filename. This is the address of the character immediately following the final backslash (\) in the path; it points to the filename.

Return Value

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer, not including the terminating null character. If the return value is greater than cchReturnBuffer, the return value is the size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

See Also

»FindFirstFile«, »FindNextFile«


  SelectClipPath

BOOL SelectClipPath(hdc, iMode)
HDC  hdc;   /* handle of device context  */
int  iMode;   /* clipping mode */

The SelectClipPath function selects the current path as a clipping region for the given device context, combining the new region with any existing clipping region by using the specified mode.

Parameters

hdc

Identifies the device context of the path.

iMode

Specifies the way to use the path. The following values are allowed:

Value	Meaning
RGN_AND	The new clipping region includes the intersection (overlapping areas) of the current clipping region and the current path.
RGN_COPY	The new clipping region is the current path.
RGN_DIFF	The new clipping region includes the areas of the current clipping region with those of the current path excluded.
RGN_OR	The new clipping region includes the union (combined areas) of the current clipping region and the current path.
RGN_XOR	The new clipping region includes the union of the current clipping region and the current path but without the overlapping areas.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get the error value, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

Comments

The device context identified by the hdc parameter must contain a closed path.

See Also

»BeginPath«, »EndPath«


  SelectClipRgn

int SelectClipRgn(hdc, hrgn)
HDC  hdc;   /* handle of device context */
HRGN  hrgn;   /* handle of region to be selected */

The SelectClipRgn function selects the given region as the current clipping region for the given device context.

Parameters

hdc

Identifies the device context.

hrgn

Identifies the region to be selected.

Return Value

If the function succeeds, the return value specifies the region's complexity. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred. (The previous clipping region is not affected.)
Comments

Only a copy of the selected region is used. The region itself can be selected for any number of other device contexts or it can be deleted.

The SelectClipRgn function assumes that the coordinates for the given region are specified in device units.

To remove a device-context's clipping region, specify a NULL region handle.

See Also

»ExtSelectClipRgn«


  SelectObject

HGDIOBJ SelectObject(hdc, hgdiobj)
HDC  hdc;   /* handle of DC */
HGDIOBJ  hgdiobj;   /* handle of object */

The SelectObject function selects an object into the given device context (DC). The new object replaces the previous object of the same type.

Parameters

hdc

Identifies the DC.

hgdiobj

Identifies the object to be selected. The specified object must have been created by using one of the following functions:

Object	Functions
Bitmap	CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDIBitmap
	(Bitmaps can be selected for memory DCs only, and for only one DC at a time.)
Brush	CreateBrushIndirect, CreateDIBPatternBrush, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush
Font	CreateFont, CreateFontIndirect
Pen	CreatePen, CreatePenIndirect
Region	CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreateRectRgn, CreateRectRgnIndirect
Return Value

If the selected object is not a region and the function succeeds, the return value is the handle of the object being replaced. If the selected object is a region and the function succeeds, the return value is one of the following values:

Value	Meaning
SIMPLEREGION	Region consists of a single rectangle.
COMPLEXREGION	Region consists of more than one rectangle.
NULLREGION	Region is empty.
If an error occurs and the selected object is not a region, the return value is NULL. Otherwise, it is GDI_ERROR.

Comments

This function returns the previously selected object of the given type. An application should always replace a new object with the original, default object after it has finished drawing with the new object.

An application cannot select a bitmap into more than one DC at a time.

See Also

»SelectClipRgn«, »SelectPalette«


  SelectPalette

HPALETTE SelectPalette(hdc, hpal, bForceBackground)
HDC  hdc;   /* handle of device context */
HPALETTE  hpal;   /* handle of logical color-palette */
BOOL  bForceBackground;   /* foreground/background mode */

The SelectPalette function selects the given logical palette into the given device context.

Parameters

hdc

Identifies the device context (DC).

hpal

Identifies the logical palette to be selected.

bForceBackground

Specifies whether the logical palette is forced to be a background palette. If this value is TRUE, the RealizePalette parameter causes the logical palette to be mapped to the colors already in the physical palette in the best possible way. This is always done, even if the window for which the palette is realized belongs to a thread without active focus.

If this value is FALSE, RealizePalette causes the logical palette to be copied into the device palette when the application is in the foreground. (If the hdc parameter is a memory DC, this parameter is ignored.)

Return Value

If the function succeeds, the return value identifies the device context's previous logical palette; otherwise, it is null. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

An application can select a logical palette into more than one device context. However, changes to a logical palette will affect all device contexts for which it is selected.

An application might call the SelectPalette function with the bForceBackground parameter set to TRUE if the child windows of a top-level window each realize their own palettes. However, only the child window that needs to realize its palette must set bForceBackground to TRUE; other child windows must set this value to FALSE.

See Also

»CreatePalette«, »GetDeviceCaps«, »RealizePalette«


  SendDlgItemMessage

LONG SendDlgItemMessage(hwndDlg, idControl, uMsg, wParam, lParam)
HWND  hwndDlg;   /* handle of dialog box */
int  idControl;   /* identifier of control */
UINT  uMsg;   /* message to send */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The SendDlgItemMessage function sends a message to the specified control in the given dialog box.

Parameters

hwndDlg

Identifies the dialog box that contains the control.

idControl

Specifies the identifier of the control that receives the message.

uMsg

Specifies the message to be sent.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message sent.

Comments

The SendDlgItemMessage function does not return until the message has been processed.

Using SendDlgItemMessage is identical to retrieving a handle of the given control and calling the SendMessage function.

See Also

»SendMessage«


  SendMessage

LRESULT SendMessage(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of destination window */
UINT  uMsg;   /* message to send */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The SendMessage function sends the specified message to the given window or windows. The function calls the window procedure for the given window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.

Parameters

hwnd

Identifies the window whose window procedure will receive the message. If this parameter is HWND_TOPMOST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows.

uMsg

Specifies the message to be sent.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

The return value specifies the result of the message processing and depends on the message sent.

Comments

If the given window was created by the calling thread, the window procedure is called immediately as a subroutine. If the given window was created by a different thread, Windows switches to that thread and calls the appropriate window procedure.

See Also

»InSendMessage«, »PostMessage«, »SendDlgItemMessage«


  SendMessageCallback

BOOL SendMessageCallback(hwnd, uMsg, wParam, lParam, lpResultCallBack, dwData)
HWND  hwnd;   /* handle of destination window */
UINT  uMsg;   /* message to send */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */
SENDASYNCPROC  lpResultCallBack;   /* function to receive message value  */
DWORD  dwData;   /* value to pass to callback function */

The SendMessageCallback function sends the specified message to the given window or windows. The function calls the window procedure for the given window and returns immediately. After the window procedure processes the message, the system calls the specified callback function, passing the result of the message processing and an application-defined value to the callback function.

Parameters

hwnd

Identifies the window whose window procedure will receive the message. If this parameter is HWND_TOPMOST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows.

uMsg

Specifies the message to be sent.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

lpfnResultCallBack

Points to the callback function to receive the return value associated with the message being sent.

dwData

Specifies an application-defined value to be sent to the callback function pointed to by the lpfnResultCallBack parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»InSendMessage«, »PostMessage«, »ResultCallBack«, »SendDlgItemMessage«, »SendMessage«, »SendMessageTimeout«, »SendNotifyMessage«


  SendMessageTimeout

LRESULT SendMessageTimeout(hwnd, uMsg, wParam, lParam, wFlags, uTimeout, lpdwResult)
HWND  hwnd;   /* handle of destination window */
UINT  uMsg;   /* message to send */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */
UINT  fuFlags;   /* how to send the message */
UINT  uTimeout;   /* time-out duration */
LPDWORD  lpdwResult;   /* return value for synchronous call */

The SendMessageTimeout function sends the specified message to the given window or windows. The function calls the window procedure for the given window and does not return until the window procedure has processed the message or the specified time-out period has elapsed.

Parameters

hwnd

Identifies the window whose window procedure will receive the message. If this parameter is HWND_TOPMOST, the message is sent to all top-level windows in the system, including disabled or invisible unowned windows.

uMsg

Specifies the message to be sent.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

fuFlags

Specifies how to send the message. This parameter can be a combination of the following values:

Value	Meaning
SMTO_ABORTIFHUNG	Returns without waiting for the time-out period to elapse if the receiving process appears to be in a hung state.
SMTO_BLOCK	Prevents the calling thread from processing any other requests until the function returns.
uTimeout

Specifies the duration, in milliseconds, of the time-out period.

lpdwResult

Specifies the result of the message processing and depends on the message sent.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»InSendMessage«, »PostMessage«, »SendDlgItemMessage«, »SendMessage«, »SendMessageCallback«, »SendNotifyMessage«


  SendNotifyMessage

BOOL SendNotifyMessage(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of destination window */
UINT  uMsg;   /* message to send */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The SendNotifyMessage function sends the specified message to the given window. If the window was created by the calling thread, SendNotifyMessage calls the window procedure for the window and does not return until the window procedure has processed the message. If the window was created by a different thread, SendNotifyMessage passes the message to the window procedure and returns immediately; it does not wait for the window procedure to finish processing the message.

Parameters

hwnd

Identifies the window whose window procedure will receive the message. If this parameter is HWND_TOPMOST, the message will be posted to all overlapped or pop-up windows in the system. The message is not posted to child windows.

uMsg

Specifies the message to be sent.

wParam

Specifies additional message-dependent information.

lParam

Specifies additional message-dependent information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»PostMessage«, »PostThreadMessage«, »SendMessage«


  ServiceMain

VOID ServiceMain(dwArgc, lpszArgv)
DWORD  dwArgc;   /* number of arguments */
LPTSTR  *lpszArgv;   /* address of array of argument string pointers */

A ServiceMain function is a function that a service process specifies as the entry point function of a particular service. The function can have any application-defined name.

Parameters

dwArgc

Specifies the number of arguments in the lpszArgv array.

lpszArgv

Points to an array of pointers that point to null-terminated argument strings. The first argument in the array is the name of the service, and subsequent arguments are any strings passed to the service by the process that called the StartService function to start the service.

Return Value

This function does not return a value.

Comments

A service process can start one or more services. For each service that it can start, a service process has a SERVICE_TABLE_ENTRY structure that specifies the service name and a pointer to the ServiceMain function for that service.

When the service control manager receives a request to start a service, it starts the service process (if it is not already running). The main thread of the service process calls the StartServiceCtrlDispatcher function with a pointer to an array of SERVICE_TABLE_ENTRY structures. Then the service control manager sends a start request to the service control dispatcher for this service process. The service control dispatcher creates a new thread to execute the ServiceMain function of the service being started.

This function should immediately call the RegisterServiceCtrlHandler function to specify a Handler function to handle control requests. Next, it should call the SetServiceStatus function to send status information to the service control manager. After these calls, the function completes the initialization tasks of the service, and then it waits for the service to terminate.

A ServiceMain function does not return until the service is ready to terminate.

See Also

»Handler«, »RegisterServiceCtrlHandler«, »SetServiceStatus«, »StartServiceCtrlDispatcher«


  SetAbortProc

int SetAbortProc(hdc, lpAbortProc)
HDC  hdc;   /* handle of device context */
ABORTPROC  lpAbortProc;   /* address of abort function */

The SetAbortProc function sets the application-defined abort function that allows a print job to be canceled during spooling. This function replaces the SETABORTPROC printer escape.

Parameters

hdc

Identifies the device context for the print job.

lpAbortProc

Points to the application-defined abort function. For more information about the callback function, see the description of the »AbortProc« callback function.

Return Value

If the function succeeds, the return value is greater than zero.

If the function fails, the return value is SP_ERROR. To get extended error information, use the GetLastError function.

See Also

»AbortDoc«, »AbortProc«


  SetAclInformation

BOOL SetAclInformation(pAcl, lpvAclInfo, cbAclInfo, aclic)
PACL  pAcl;   /* address of access-control list */
LPVOID  lpvAclInfo;   /* address of ACL information */
DWORD  cbAclInfo;   /* size of ACL information */
ACL_INFORMATION_CLASS  aclic;   /* specifies class of requested info */

The SetAclInformation function sets information about an access-control list (ACL).

Parameters

pAcl

Points to an ACL structure. The function sets information in this ACL.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpvAclInfo

Points to a buffer containing the information to be set. For the current version of Windows NT, this must be an ACL_REVISION_INFORMATION structure.

cbAclInfo

Specifies the size, in bytes, of the buffer pointed to by the pAclInfo parameter.

aclic

Specifies an ACL_INFORMATION_CLASS enumerated type that gives the class of information requested.

The ACL_INFORMATION_CLASS enumerated type has the following form:

typedef enum tagACL_INFORMATION_CLASS { /* aclic */

    AclRevisionInformation = 1,

    AclSizeInformation

} ACL_INFORMATION_CLASS;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

Currently, this parameter can be AclRevisionInformation. This means that the buffer pointed to by the lpvAclInfo parameter contains an ACL_REVISION_INFORMATION structure. The ACL_REVISION_INFORMATION structure has the following form:

typedef struct _ACL_REVISION_INFORMATION {

    DWORD   AclRevision;

} ACL_REVISION_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetAclInformation«, »InitializeAcl«, »IsValidAcl«


  SetActiveWindow

HWND SetActiveWindow(hwnd)
HWND  hwnd;   /* handle of window to activate */

The SetActiveWindow function makes the given top-level window associated with the thread calling this function the active window.

Parameters

hwnd

Identifies the top-level window to be activated.

Return Value

If the function succeeds, the return value is the handle of the window that was previously active.

Comments

Applications must use the SetActiveWindow function carefully, because the function allows an application to arbitrarily take over the active window and keyboard focus. Usually, Windows takes care of all activation.

If the window identified by the hwnd parameter was created by the calling thread, the active window status of the calling thread is set to hwnd. Otherwise, the active window status of the calling thread is set to NULL, and the active window status of the thread that created the window is set to hwnd.

See Also

»GetActiveWindow«, »WM_ACTIVATE«


  SetArcDirection

int SetArcDirection(hdc, ArcDirection)
HDC  hdc;   /* identifies the device context */
int  ArcDirection;   /* specifies the new arc direction */

The SetArcDirection sets the drawing direction to be used for arc and rectangle functions.

Parameters

hdc

Identifies the device context.

ArcDirection

Specifies the new arc direction. This parameter can be one of the following values:

Value	Meaning
AD_COUNTERCLOCKWISE	Figures drawn counterclockwise.
AD_CLOCKWISE	Figures drawn clockwise.
Return Value

If the function succeeds, the return value specifies the old arc direction; otherwise, it is zero.

Comments

The default direction is counterclockwise.

The SetArcDirection function specifies the direction in which the following functions draw:

Arc	ArcTo
Chord	Ellipse
Pie	Rectangle
RoundRect
See Also

»Arc«, »ArcTo«, »Chord«, »Ellipse«, »Pie«, »Rectangle«, »RoundRect«


  SetBitmapBits

LONG SetBitmapBits(hbmp, cBytes, lpBits)
HBITMAP  hbmp;   /* handle of bitmap */
DWORD  cBytes;   /* number of bytes in bitmap array */
CONST VOID  *lpBits;   /* address of array with bitmap bits */

The SetBitmapBits function sets the bits of color data for the given bitmap to the specified values.

The SetBitmapBits function is included only for compatibility with earlier versions of Windows. For Win32 applications, use the SetDIBits function.

Parameters

hbmp

Identifies the bitmap to be set.

cBytes

Specifies the number of bytes pointed to by the lpBits parameter.

lpBits

Points to an array of bytes that contain color data for the given bitmap.

Return Value

If the function succeeds, the return value is the number of bytes used in setting the bitmap bits; otherwise, it is zero.

Comments

The array identified by lpBits must be WORD aligned.

See Also

»GetBitmapBits«, »SetDIBits«


  SetBitmapDimension

The SetBitmapDimension function has been deleted. For Win32 applications, use the SetBitmapDimensionEx function.

See Also

»SetBitmapDimensionEx«


  SetBitmapDimensionEx

BOOL SetBitmapDimensionEx(hBitmap, nWidth, nHeight, lpSize)
HBITMAP  hBitmap;   /* handle of bitmap */
int  nWidth;   /* bitmap width in .01-mm units */
int  nHeight;   /* bitmap height in .01-mm units */
LPSIZE  lpSize;   /* address of structure for original dimensions */

The SetBitmapDimensionEx function assigns preferred dimensions to a bitmap. These dimensions can be used by applications; however, they are not used by Windows.

Parameters

hBitmap

Identifies the bitmap.

nWidth

Specifies the width, in 0.1-millimeter units, of the bitmap.

nHeight

Specifies the height, in 0.1-millimeter units, of the bitmap.

lpSize

Points to a SIZE structure to receive the previous dimensions of the bitmap. This pointer can be NULL. The SIZE structure has the following format:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can retrieve the dimensions assigned to a bitmap with the SetBitmapDimensionEx function by calling the GetBitmapDimensionEx function.

See Also

»GetBitmapDimensionEx«


  SetBkColor

COLORREF SetBkColor(hdc, crColor)
HDC  hdc;   /* handle of device context */
COLORREF  crColor;   /* background color value */

The SetBkColor function sets the current background color to the specified color value, or to the nearest physical color if the device cannot represent the specified color value.

Parameters

hdc

Identifies the device context.

crColor

Specifies the new background color.

Return Value

If the function succeeds, the return value specifies the previous background color as a COLORREF value. Otherwise, the return value is CLR_INVALID.

Comments

This function fills the gaps between styled lines drawn using a pen created by the CreatePen function; it does not fill the gaps between styled lines drawn using a pen created by the ExtCreatePen function.

If the background mode is OPAQUE, the background color is used to fill gaps between styled lines, gaps between hatched lines in brushes, and character cells. The background color is also used when converting bitmaps from color to monochrome and vice versa.

See Also

»CreatePen«, »GetBkMode«, »SetBkMode«


  SetBkMode

int SetBkMode(hdc, iBkMode)
HDC  hdc;   /* handle of device context */
int  iBkMode;   /* flag specifying background mode */

The SetBkMode function sets the background mix mode of the given device context (DC). The background mix mode is used with text, hatched brushes, and pen styles that are not solid lines.

Parameters

hdc

Identifies the DC.

iBkMode

Specifies the background mode. This parameter can be either of the following modes:

Value	Description
OPAQUE	Background is filled with the current background color before the text, hatched brush, or pen is drawn.
TRANSPARENT	Background remains untouched.
Return Value

If the function succeeds, the return value specifies the previous background mode; otherwise, it is zero.

Comments

This function affects the line styles for lines drawn using a pen created by the CreatePen function. This function does not affect lines drawn using a pen created by the ExtCreatePen function.

See Also

»CreatePen«, »ExtCreatePen«, »GetBkMode«


  SetBoundsRect

UINT SetBoundsRect(hdc, lprcBounds, flags)
HDC  hdc;   /* handle of device context */
CONST RECT  *lprcBounds;   /* address of structure for rectangle  */
UINT  flags;   /* controls rectangle combination */

The SetBoundsRect function controls the accumulation of bounding rectangle information for the given device context (DC). Windows can maintain a bounding rectangle for all drawing operations. An application can examine and set this rectangle. The drawing boundaries are useful for invalidating bitmap caches.

Parameters

hdc

Identifies the DC for which to accumulate bounding rectangles.

lprcBounds

Points to a RECT structure used to set the bounding rectangle. Rectangle dimensions are in logical coordinates. This parameter can be NULL. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

flags

Specifies how the new rectangle will be combined with the accumulated rectangle. This parameter can be a combination of the following values:

Value	Description
DCB_ACCUMULATE	Adds the rectangle specified by the lprcBounds parameter to the bounding rectangle (using a rectangle union operation). Using both DCB_RESET and DCB_ACCUMULATE sets the bounding rectangle to the rectangle specified by the lprcBounds parameter.
DCB_DISABLE	Turns off boundary accumulation.
DCB_ENABLE	Turns on boundary accumulation, which is disabled by default.
DCB_RESET	Clears the bounding rectangle.
Return Value

If the function succeeds, the return value specifies the previous state of the bounding rectangle. This state can be a combination of the following values:

Value	Meaning
DCB_DISABLE	Boundary accumulation is off.
DCB_ENABLE	Boundary accumulation is on. DCB_ENABLE and DCB_DISABLE are mutually exclusive.
DCB_RESET	Bounding rectangle is empty.
DCB_SET	Bounding rectangle is not empty. DCB_SET and DCB_RESET are mutually exclusive.
Comments

The DCB_SET value is a combination of the bit values DCB_ACCUMULATE and DCB_RESET. Applications that check the DCB_RESET bit to determine whether the bounding rectangle is empty must also check the DCB_ACCUMULATE bit. The bounding rectangle is empty only if the DCB_RESET bit is 1 and the DCB_ACCUMULATE bit is 0.

See Also

»GetBoundsRect«


  SetBrushOrg

The SetBrushOrg function is obsolete. For Win32 applications, use the SetBrushOrgEx function.


  SetBrushOrgEx

BOOL SetBrushOrgEx(hdc, nXOrg, nYOrg, lppt)
HDC  hdc;   /* handle of device context */
int  nXOrg;   /* x-coordinate of new origin */
int  nYOrg;   /* y-coordinate of new origin */
LPPOINT  lppt;   /* points to previous brush origin */

The SetBrushOrgEx function sets the brush origin that GDI assigns to the next brush an application selects into the specified device context (DC).

Parameters

hdc

Identifies the DC.

nXOrg

Specifies the x-coordinate, in device units, of the new brush origin. This value must be in the range 0 through 7.

nYOrg

Specifies the y-coordinate, in device units, of the new brush origin. This value must be in the range 0 through 7.

lppt

Points to a POINT structure that receives the previous brush origin. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

This parameter can be NULL if the previous brush origin is not required.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A brush is a bitmap that Windows uses to paint the interiors of filled shapes.

The brush origin is a set of coordinates with values between 0 and 7, specifying the location of one pixel in the bitmap. The default brush origin coordinates are (0,0). For horizontal coordinates, value 0 corresponds to the leftmost column of pixels; value 7 corresponds to the rightmost column. For vertical coordinates, value 0 corresponds to the uppermost row of pixels; value 7 corresponds to the lowermost row. When Windows positions the brush at the start of any painting operation, it maps the pixel at the brush's origin to the upper-left corner of the application window's client area.

Windows automatically tracks the origin of all window-managed device contexts and adjusts their brushes as necessary to maintain an alignment of patterns on the surface. The brush origin that is set with this call is relative to the upper-left corner of the client area.

See Also

»GetBrushOrgEx«


  SetCapture

HWND SetCapture(hwnd)
HWND  hwnd;   /* handle of window to receive mouse capture */

The SetCapture function sets the mouse capture to the given window belonging to the current thread. Once a window has captured the mouse, all mouse input is directed to that window, regardless of whether the cursor is within the borders of that window. Only one window at a time can capture the mouse.

If the mouse cursor is over a window created by another thread, the system will direct mouse input to the given window only if a mouse button is down.

Parameters

hwnd

Identifies the window in the current thread that is to capture the mouse.

Return Value

If the function succeeds, the return value is the handle of the window that had previously captured the mouse. If there is no such window, the return value is NULL.

Comments

Only the foreground window can capture the mouse. When a background window attempts to do so, the window receives messages only for mouse events that occur when the cursor hot spot is within the visible portion of the window. Also, even if the foreground window has captured the mouse, the user can still click another window, bringing it to the foreground.

When the window no longer requires all mouse input, the thread that created the window should call the ReleaseCapture function to release the mouse.

This function cannot be used to capture mouse input meant for another process.

See Also

»GetCapture«, »ReleaseCapture«


  SetCaretBlinkTime

BOOL SetCaretBlinkTime(wMSeconds)
UINT  wMSeconds;   /* blink time, in milliseconds */

The SetCaretBlinkTime function sets the caret blink time to the specified number of milliseconds. The blink time is the elapsed time, in milliseconds, required to invert the caret's pixels.

Parameters

wMSeconds

Specifies the new blink time, in milliseconds.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The caret is a shared resource; there is only one caret in the system. A window should set the caret blink time only if it owns the caret. The window should restore the previous blink time before losing the keyboard focus or becoming inactive.

See Also

»GetCaretBlinkTime«


  SetCaretPos

BOOL SetCaretPos(nX, nY)
int  nX;   /* horizontal position  */
int  nY;   /* vertical position */

The SetCaretPos function moves the caret to the specified coordinates. If the window that owns the caret was created with the CS_OWNDC class style, then the specified coordinates are subject to the mapping mode of the device context associated with that window.

Parameters

nX

Specifies the new x-coordinate of the caret.

nY

Specifies the new y-coordinate of the caret.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

SetCaretPos moves the caret whether or not the caret is hidden.

The caret is a shared resource; there is only one caret in the system. A window can set the caret position only if it owns the caret.

See Also

»GetCaretPos«, »HideCaret«, »ShowCaret«


  SetClassLong

DWORD SetClassLong(hwnd, nIndex, lNewVal)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* index of value to change  */
LONG  lNewVal;   /* new value */

The SetClassLong function replaces the specified 32-bit (long) value at the specified offset into the extra class memory or the WNDCLASS structure for the class to which the given window belongs.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the 32-bit value to replace. To set a 32-bit value in the extra class memory, specify the positive, zero-based byte offset of the value to be set. Valid values are in the range zero through the number of bytes of extra class memory, minus four; for example, if you specified 12 or more bytes of extra class memory, a value of 8 would be an index to the third 32-bit integer. To set any other value from the WNDCLASS structure, specify one of the following values:

Value	Action
GCL_CBCLSEXTRA	Sets the size, in bytes, of the extra memory associated with the class. Setting this value does not change the number of extra bytes already allocated.
GCL_CBWNDEXTRA	Sets the size, in bytes, of the extra window memory associated with each window in the class. Setting this value does not change the number of extra bytes already allocated. For information on how to access this memory, see the descriptions of the »SetWindowLong« and »SetWindowWord« functions.
GCL_HBRBACKGROUND	Replaces the handle of the background brush associated with the class.
GCL_HCURSOR	Replaces the handle of the cursor associated with the class.
GCL_HICON	Replaces the handle of the icon associated with the class.
GCL_HMODULE	Replaces the handle of the module that registered the class.
GCL_MENUNAME	Replaces the address of the menu name string. The string identifies the menu resource associated with the class.
GCL_STYLE	Replaces the window-class style bits.
GCL_WNDPROC	Replaces the address of the window procedure associated with the class.
lNewVal

Specifies the replacement value.

Return Value

If the function succeeds, the return value is the previous value of the specified 32-bit integer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

If you use the SetClassLong function and the GCL_WNDPROC index to replace the window procedure, the given window procedure must conform to the guidelines specified in the description of the WindowProc callback function.

Calling SetClassLong with the GCL_WNDPROC index creates a subclass of the window class that affects all windows subsequently created with the class. An application cannot subclass a window created by another process.

Reserve extra class memory by specifying a nonzero value in the cbClsExtra member of the WNDCLASS structure used with the RegisterClass function.

Use the SetClassLong function with care. For example, it is possible to change the background color for a class by using SetClassLong, but this change does not immediately repaint all windows belonging to the class.

See Also

»GetClassLong«, »GetClassWord«, »RegisterClass«, »SetClassWord«, »SetWindowLong«, »SetWindowWord«, »WindowProc«


  SetClassWord

WORD SetClassWord(hwnd, nIndex, wNewWord)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* index of value to change  */
WORD  wNewWord;   /* new value */

The SetClassWord function replaces the 16-bit (word) value at the specified offset into the extra class memory for the window class to which the given window belongs.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the zero-based byte offset of the value to be replaced. Valid values are in the range zero through the number of bytes of class memory minus two; for example, if you specified 10 or more bytes of extra class memory, a value of 8 would be an index to the fifth 16-bit integer.

wNewWord

Specifies the replacement value.

Return Value

If the function succeeds, the return value is the previous value of the specified 16-bit integer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Reserve extra class memory by specifying a nonzero value in the cbClsExtra member of the WNDCLASS structure used with the RegisterClass function.

The GCW_ values are obsolete in the Win32 application programming interface (API). You must use the SetClassLong function to set the class values previously set by using the GCW_ values with the SetClassWord function.

See Also

»GetClassLong«, »GetClassWord«, »RegisterClass«, »SetClassLong«


  SetClipboardData

HANDLE SetClipboardData(uFormat, hData)
UINT  uFormat;   /* clipboard format  */
HANDLE  hData;   /* data handle */

The SetClipboardData function places data on the clipboard in the specified clipboard format. The window must be the current clipboard owner, and the application must have called the OpenClipboard function. (When responding to the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages, the clipboard owner must not call OpenClipboard before calling SetClipboardData.)

Parameters

uFormat

Specifies a clipboard format. This parameter can be a registered format or any of the standard clipboard formats listed in the Comments section. For information about registered clipboard formats, see the »RegisterClipboardFormat« function.

hData

Identifies the data in the specified format. This parameter can be NULL, indicating that the window provides data in the specified clipboard format (renders the format) on request. If a window delays rendering, it must process the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages.

Return Value

If the function succeeds, the return value is the handle of the data; otherwise, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

Once the hData parameter has been passed to SetClipboardData, it is owned by the system. The application can read the data, but must not free the handle or leave it locked.

If hData is a memory handle, it must be allocated by using the GlobalAlloc function with the GMEM_MOVEABLE and GMEM_DDESHARE flags.

The uFormat parameter can identify a registered clipboard format, or it can be one of the following values:

Value	Meaning
CF_BITMAP
	A handle of a bitmap (HBITMAP).
CF_DIB
	A memory object containing a BITMAPINFO structure followed by the bitmap bits.
CF_DIF
	Software Arts' Data Interchange Format.
CF_DSPBITMAP
	Bitmap display format associated with a private format. The hData parameter must be a handle of data that can be displayed in bitmap format in lieu of the privately formatted data.
CF_DSPENHMETAFILE
	Enhanced metafile display format associated with a private format. The hData parameter must be a handle of data that can be displayed in enhanced metafile format in lieu of the privately formatted data.
CF_DSPMETAFILEPICT
	Metafile-picture display format associated with a private format. The hData parameter must be a handle of data that can be displayed in metafile-picture format in lieu of the privately formatted data.
CF_DSPTEXT
	Text display format associated with a private format. The hData parameter must be a handle of data that can be displayed in text format in lieu of the privately formatted data.
CF_GDIOBJFIRST through CF_GDIOBJLAST
	Range of integer values for application-defined GDI object clipboard formats. Handles associated with clipboard formats in this range are automatically deleted (using the DeleteObject function) when the clipboard is emptied.
CF_ENHMETAFILE
	A handle of an enhanced metafile (HENHMETAFILE).
CF_METAFILEPICT
	Handle of a metafile picture format as defined by the METAFILEPICT structure. When passing a CF_METAFILEPICT handle by means of dynamic data exchange (DDE), the application responsible for deleting hData should also free the metafile referred to by the CF_METAFILEPICT handle.
CF_OEMTEXT
	Text format containing characters in the OEM character set. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
CF_OWNERDISPLAY
	Owner display format. The clipboard owner must display and update the clipboard viewer window, and receive the WM_ASKCBFORMATNAME, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_SIZECLIPBOARD, and WM_VSCROLLCLIPBOARD messages. The hData parameter must be NULL.
CF_PALETTE
	Handle of a color palette. Whenever an application places data in the clipboard that depends on or assumes a color palette, it should place the palette in the clipboard as well.
	If the clipboard contains data in the CF_PALETTE (logical color palette) format, the application should use the SelectPalette and RealizePalette functions to realize (compare) any other data in the clipboard against that logical palette.
	When displaying clipboard data, Windows Clipboard always uses as its current palette any object on the clipboard that is in the CF_PALETTE format.
CF_PENDATA
	Data for the pen extensions to the Windows operating system.
CF_PRIVATEFIRST through CF_PRIVATELAST
	Range of integer values for private clipboard formats. Handles associated with private clipboard formats are not freed automatically; the clipboard owner must free such handles, typically in response to the WM_DESTROYCLIPBOARD message.
CF_SYLK
	Microsoft Symbolic Link (SYLK) format.
CF_TEXT
	Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
CF_TIFF
	Tag image file format.
CF_UNICODETEXT
	Unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
Windows supports three clipboard formats for text: CF_UNICODETEXT, CF_TEXT, and CF_OEMTEXT. Specify CF_TEXT for ANSI text, CF_UNICODETEXT for Unicode text, and CF_OEMTEXT for text in the OEM character set. If any of the three text formats is placed on the clipboard, all three can be retrieved by using the GetClipboardData function. If necessary, Windows automatically converts data in an available text format to the requested format. An application can place more than one text format on the clipboard if it does so at one time (between the same calls to OpenClipboard and CloseClipboard).

Windows supports two clipboard formats for metafiles: CF_ENHMETAFILE and CF_METAFILEPICT. Specify CF_ENHMETAFILE for enhanced metafiles and CF_METAFILEPICT for Windows metafiles. If either of the two metafile formats is placed on the clipboard, both can be retrieved by GetClipboardData. If necessary, Windows automatically converts data in the available metafile format to the requested format. An application can place both metafile formats on the clipboard if it does so at one time (between the same calls to OpenClipboard and CloseClipboard).

See Also

»GetClipboardData«, »RegisterClipboardFormat«


  SetClipboardViewer

HWND SetClipboardViewer(hwnd)
HWND  hwnd;   /* handle of clipboard viewer */

The SetClipboardViewer function adds the specified window to the chain of clipboard viewers. Clipboard viewer windows receive a WM_DRAWCLIPBOARD message whenever the contents of the clipboard change.

Parameters

hwnd

Identifies the window to be added to the clipboard chain.

Return Value

If the function succeeds, the return value identifies the next window in the clipboard viewer chain. If an error occurs or there are no other windows in the clipboard viewer chain, the return value is NULL. To get extended error information, use the GetLastError information.

Comments

Windows that are part of the clipboard viewer chain, called clipboard viewer windows, must process the clipboard notification messages WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD. Each clipboard viewer window calls the SendMessage function to pass these messages to the next window in the clipboard viewer chain.

A clipboard viewer window must eventually remove itself from the clipboard viewer chain by calling the ChangeClipboardChain function — for example, in response to the WM_DESTROY message.

See Also

»ChangeClipboardChain«, »GetClipboardViewer«, »SendMessage«, »WM_CHANGECBCHAIN« »WM_DRAWCLIPBOARD«


  SetColorAdjustment

BOOL SetColorAdjustment(hdc, lpca)
HDC  hdc;   /* handle of device context */
LPCOLORADJUSTMENT  lpca;   /* address of coloradjustment structure */

The SetColorAdjustment function sets the color adjustment values for the given device context using the specified values.

Parameters

hdc

Identifies the device context.

lpca

Points to a COLORADJUSTMENT structure containing the color adjustment values.

The COLORADJUSTMENT structure has the following form:

typedef struct  tagCOLORADJUSTMENT {    /* ca */

    WORD  caSize;

    WORD  caFlags;

    WORD  caIlluminantIndex;

    WORD  caRedGamma;

    WORD  caGreenGamma;

    WORD  caBlueGamma;

    WORD  caReferenceBlack;

    WORD  caReferenceWhite;

    SHORT caContrast;

    SHORT caBrightness;

    SHORT caColorfulness;

    SHORT caRedGreenTint;

} COLORADJUSTMENT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The color adjustment values are used to adjust the input color of the source bitmap for calls to the StretchBlt and StretchDIBits functions when HALFTONE mode is set.

See Also

»SetStretchBltMode«, »StretchBlt«, »StretchDIBits«


  SetCommBreak

BOOL SetCommBreak(hCommDev)
HANDLE  hCommDev;   /* handle of the communications device */

The SetCommBreak function suspends character transmission for a given communications device and places the transmission line in a break state until the ClearCommBreak function is called.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetCommBreak function does not flush data that has not been transmitted.

See Also

»ClearCommBreak«


  SetCommMask

BOOL SetCommMask(hCommDev, fdwEvtMask)
HANDLE  hCommDev;   /* handle of the communications device  */
DWORD  fdwEvtMask;   /* mask that identifies enabled events */

The SetCommMask function specifies a set of events to be monitored for a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

fdwEvtMask

Specifies the events to be enabled. A value of zero disables all events. This parameter can be a combination of the following values:

Value	Meaning
EV_BREAK	A break was detected on input.
EV_CTS	The CTS (clear-to-send) signal changed state.
EV_DSR	The DSR (data-set-ready) signal changed state.
EV_ERR	A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING	A ring indicator was detected.
EV_RLSD	The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR	Any character was received and placed in the input buffer.
EV_RXFLAG	The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY	The last character in the output buffer was sent.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetCommMask function specifies the set of events that can be monitored for a particular communications resource. To wait for one of the events to occur, a handle to the communications resource can be specified in a call to the WaitCommEvent function. To get the current event mask of a communications resource, use the GetCommMask function.

If SetCommMask is called for a communications resource while a wait is pending for that resource, WaitCommEvent returns an error.

See Also

»GetCommMask«, »WaitCommEvent«


  SetCommState

BOOL SetCommState(hCommDev, lpdcb)
HANDLE  hCommDev;   /* handle of the communications device  */
LPDCB  lpdcb;   /* address of device control block structure */

The SetCommState function configures a communications device according to the specifications in a device control block (a DCB structure). The function reinitializes all hardware and control settings, but it does not empty output or input queues.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpdcb

Points to a DCB structure containing the configuration information for the specified communications device. The DCB structure has the following form:

typedef struct _DCB { /* dcb */

    DWORD DCBlength;           /* sizeof(DCB)                */

    DWORD BaudRate;            /* current baud rate          */

    DWORD fBinary: 1;          /* binary mode, no EOF check  */

    DWORD fParity: 1;          /* enable parity checking     */

    DWORD fOutxCtsFlow:1;      /* CTS output flow control    */

    DWORD fOutxDsrFlow:1;      /* DSR output flow control    */

    DWORD fDtrControl:2;       /* DTR flow control type      */

    DWORD fDsrSensitivity:1;   /* DSR sensitivity            */

    DWORD fTXContinueOnXoff:1; /* XOFF continues Tx          */

    DWORD fOutX: 1;        /* XON/XOFF out flow control      */

    DWORD fInX: 1;         /* XON/XOFF in flow control       */

    DWORD fErrorChar: 1;   /* enable error replacement       */

    DWORD fNull: 1;        /* enable null stripping          */

    DWORD fRtsControl:2;   /* RTS flow control               */

    DWORD fAbortOnError:1; /* abort reads/writes on error    */

    DWORD fDummy2:17;      /* reserved                       */

    WORD wReserved;        /* not currently used             */

    WORD XonLim;           /* transmit XON threshold         */

    WORD XoffLim;          /* transmit XOFF threshold        */

    BYTE ByteSize;         /* number of bits/byte, 4-8       */

    BYTE Parity;           /* 0-4=no,odd,even,mark,space     */

    BYTE StopBits;         /* 0,1,2 = 1, 1.5, 2              */

    char XonChar;          /* Tx and Rx XON character        */

    char XoffChar;         /* Tx and Rx XOFF character       */

    char ErrorChar;        /* error replacement character    */

    char EofChar;          /* end of input character         */

    char EvtChar;          /* received event character       */

} DCB;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetCommState function uses a DCB structure to specify the desired configuration. The GetCommState function returns the current configuration.

If you are interested in setting only a few members of the DCB structure, you should modify a DCB structure that has been filled in by a call to GetCommState. This ensures that the other members of the DCB structure have appropriate values.

The SetCommState function fails if the XonChar member of the DCB structure is equal to the XoffChar member.

When SetCommState is used to configure the 8250, the following restrictions apply to the values for the DCB structure's ByteSize and StopBits members:

•	The number of data bits must be 5 to 8 bits.

•	The use of 5 data bits with 2 stop bits is an invalid combination, as are 6, 7, or 8 data bits with 1.5 stop bits.

See Also

»BuildCommDCB«, »GetCommState«


  SetCommTimeouts

BOOL SetCommTimeouts(hCommDev, lpctmo)
HANDLE  hCommDev;   /* handle of the communications device */
LPCOMMTIMEOUTS  lpctmo;   /* address of comm timeout structure */

The SetCommTimeouts function sets the timeout parameters for all read and write operations on a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpctmo

Points to a COMMTIMEOUTS structure that contains the new timeout values. The COMMTIMEOUTS structure has the following form:

typedef struct _COMMTIMEOUTS { /* ctmo */

    DWORD ReadIntervalTimeout;

    DWORD ReadTotalTimeoutMultiplier;

    DWORD ReadTotalTimeoutConstant;

    DWORD WriteTotalTimeoutMultiplier;

    DWORD WriteTotalTimeoutConstant;

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetCommTimeouts«, »ReadFile«, »ReadFileEx«, »WriteFile«, »WriteFileEx«


  SetComputerName

BOOL SetComputerName(lpszName)
LPTSTR  lpszName;   /* address of new computer name */

The SetComputerName function sets the computer name to be used the next time the system is restarted.

Parameters

lpszName

Points to a null-terminated character string that specifies the new computer name. The name must not be longer than MAX_COMPUTERNAME_LENGTH characters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Applications using this function must have administrator rights.

See Also

»GetComputerName«


  SetConsoleActiveScreenBuffer

BOOL SetConsoleActiveScreenBuffer(hConsoleOutput)
HANDLE  hConsoleOutput;   /* handle of console screen buffer */

The SetConsoleActiveScreenBuffer function sets the specified screen buffer to be the currently displayed console screen buffer.

Parameters

hConsoleOutput

Identifies a console screen buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A console can have multiple screen buffers. SetConsoleActiveScreenBuffer determines which one is displayed. You can write to an inactive screen buffer and then use SetConsoleActiveScreenBuffer to display the buffer's contents.

See Also

»CreateConsoleScreenBuffer«


  SetConsoleCP

BOOL SetConsoleCP(IDCodePage)
UINT  IDCodePage;   /* code page to set */

The SetConsoleCP function sets the input code page used by the console associated with the calling process. A console uses its input code page to translate keyboard input into the corresponding character value.

Parameters

IDCodePage

Identifies the code page to set. The identifiers of the code pages available on the local computer are stored in the registry under the key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To determine a console's current input code page, use the GetConsoleCP function. To set and query a console's output code page, use the SetConsoleOutputCP and GetConsoleOutputCP functions.

See Also

»GetConsoleCP«, »GetConsoleOutputCP«, »SetConsoleOutputCP«


  SetConsoleCtrlHandler

BOOL SetConsoleCtrlHandler(pHandlerRoutine, fAdd)
PHANDLER_ROUTINE  pHandlerRoutine;   /* address of handler function  */
BOOL  fAdd;   /* handler to add or remove */

The SetConsoleCtrlHandler function adds or removes an application-defined HandlerRoutine function from the list of handler functions for the calling process. If no handler function is specified, the function sets an inheritable attribute that determines whether the calling process ignores CTRL+C signals.

Parameters

pHandlerRoutine

Points to the application-defined HandlerRoutine to add or remove. This parameter can be NULL.

fAdd

Specifies whether to add or remove the function pointed to by the pHandlerRoutine parameter from the handler list. If this parameter is TRUE, the handler is added; if it is FALSE, the handler is removed.

If the pHandlerRoutine parameter is NULL, a TRUE value causes the calling process to ignore CTRL+C input, and a FALSE value restores normal processing of CTRL+C input. This attribute of ignoring or processing CTRL+C is inherited by child processes.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Each console process has its own list of application-defined HandlerRoutine functions that handle CTRL+C and CTRL+BREAK signals. The handler functions also handle signals generated by the system when the user closes the console, logs off, or shuts down the system. Initially, the handler list for each process contains only a default handler function that calls the ExitProcess function. A console process adds or removes additional handler functions by calling the SetConsoleCtrlHandler function, which does not affect the list of handler functions for other processes. When a console process receives any of the control signals, its handler functions are called on a last-registered, first-called basis until one of the handlers returns TRUE. If none of the handlers returns TRUE, the default handler is called.

For console processes, the CTRL+C and CTRL+BREAK key combinations are normally treated as signals (SIGINT and SIGBREAK). When a console window with the keyboard focus receives a CTRL+C or CTRL+BREAK, the signal is normally passed to all processes sharing that console.

CTRL+BREAK is always treated as a signal, but the normal CTRL+C behavior can be changed in two ways that prevent the handler functions from being called.

•	The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT mode for a console's input buffer, so CTRL+C is reported as keyboard input rather than as a signal.

•	Calling SetConsoleCtrlHandler with the NULL and TRUE arguments causes the calling process to ignore CTRL+C signals. This attribute is inherited by child processes, but it can be enabled or disabled by any process without affecting existing processes.

A console process can use the GenerateConsoleCtrlEvent function to send a CTRL+C or CTRL+BREAK signal to a console process group.

The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off, or shuts down the system so that the process has an opportunity to clean up before termination.

See Also

»GenerateConsoleCtrlEvent«, »GetConsoleMode«, »SetConsoleMode«


  SetConsoleCursorInfo

BOOL SetConsoleCursorInfo(hConsoleOutput, pcci)
HANDLE  hConsoleOutput;   /* handle of console screen buffer */
PCONSOLE_CURSOR_INFO  pcci;   /* address of cursor information */

The SetConsoleCursorInfo function sets the size and visibility of the cursor for the specified console screen buffer.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_WRITE access.

pcci

Points to a CONSOLE_CURSOR_INFO structure containing the new specifications for the screen buffer's cursor. The CONSOLE_CURSOR_INFO structure has the following form:

typedef struct _CONSOLE_CURSOR_INFO { /* cci */

    DWORD  dwSize;

    BOOL   bVisible;

} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

When a screen buffer's cursor is visible, its appearance can vary, ranging from completely filling a character cell to showing up as a horizontal line at the bottom of the cell. The dwSize member of the CONSOLE_CURSOR_INFO structure specifies the percentage of a character cell that is filled by the cursor. If this member is less than 1 or greater than 100, SetConsoleCursorInfo fails.

See Also

»GetConsoleCursorInfo«, »SetConsoleCursorPosition«


  SetConsoleCursorPosition

BOOL SetConsoleCursorPosition(hConsoleOutput, coordCursor)
HANDLE  hConsoleOutput;   /* handle of console screen buffer  */
COORD  coordCursor;   /* new cursor position coordinates */

The SetConsoleCursorPosition function sets the cursor position in the specified console screen buffer.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_WRITE access.

coordCursor

Specifies a COORD structure containing the new cursor position. The coordinates are the column and row of a screen buffer character cell. The coordinates must be within the boundaries of the screen buffer. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The cursor position determines where characters written by the WriteFile or WriteConsole function, or echoed by the ReadFile or ReadConsole function, are displayed. To determine the current position of the cursor, use the GetConsoleScreenBufferInfo function.

If the new cursor position is not within the boundaries of the screen buffer's window, the window origin changes to make the cursor visible.

See Also

»GetConsoleCursorInfo«, »SetConsoleCursorInfo«


  SetConsoleMode

BOOL SetConsoleMode(hConsole, fdwMode)
HANDLE  hConsole;   /* handle of console input or screen buffer  */
DWORD  fdwMode;   /* input or output mode to set */

The SetConsoleMode function sets the input mode of a console's input buffer or the output mode of a console screen buffer.

Parameters

hConsole

Identifies a console input buffer or a screen buffer. The handle must have GENERIC_WRITE access.

fdwMode

Specifies the input or output mode to set. If the hConsole parameter is an input handle, the mode can be a combination of the following values. When a console is created, all input modes except ENABLE_WINDOW_INPUT are enabled by default.

Value	Meaning
ENABLE_LINE_INPUT	The ReadFile or ReadConsole function returns only when a carriage return character is read. If this mode is disabled, the functions return when one or more characters are available.
ENABLE_ECHO_INPUT	Characters read by the ReadFile or ReadConsole function are written to the active screen buffer as they are read. This mode can be used only if the ENABLE_LINE_INPUT mode is also enabled.
ENABLE_PROCESSED_INPUT	CTRL+C is processed by the system and is not placed in the input buffer. If the input buffer is being read by ReadFile or ReadConsole, other control keys are processed by the system and are not returned in the ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is also enabled, backspace, carriage return, and linefeed characters are handled by the system.
ENABLE_WINDOW_INPUT	User interactions that change the size of the console screen buffer are reported in the console's input buffer. Information about these events can be read from the input buffer by applications using the ReadConsoleInput function, but not by those using ReadFile or ReadConsole.
ENABLE_MOUSE_INPUT	If the mouse pointer is within the borders of the console window and the window has the keyboard focus, mouse events generated by mouse movement and button presses are placed in the input buffer. These events are discarded by ReadFile or ReadConsole, even when the ENABLE_MOUSE_INPUT mode is enabled.
If the hConsole parameter is a screen buffer handle, the mode can be a combination of the following values. When a screen buffer is created, both output modes are enabled by default.

Value	Meaning
ENABLE_PROCESSED_OUTPUT
	Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or ReadConsole function are parsed for ASCII control sequences and the correct action is performed. Backspace, tab, bell, carriage return, and linefeed characters are processed.
ENABLE_WRAP_AT_EOL_OUTPUT
	When writing with WriteFile or WriteConsole or echoing with ReadFile or ReadConsole, the cursor moves to the beginning of the next line when it reaches the end of the current row. This causes the lines displayed in the console window to scroll up automatically when the cursor advances beyond the last line in the window. It also causes the contents of the screen buffer to scroll up (discarding the top line of the screen buffer) when the cursor advances beyond the last line in the screen buffer. If this mode is disabled, the last character in the row is overwritten.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A console consists of an input buffer and one or more screen buffers. The mode of a console buffer determines how the console behaves during input or output (I/O) operations. One set of flag constants is used with input handles, and another set is used with screen buffer (output) handles. Setting the output modes of one screen buffer does not affect the output modes of other screen buffers.

The ENABLE_LINE_INPUT and ENABLE_ECHO_INPUT modes only affect processes that use ReadFile or ReadConsole to read from the console's input buffer. Similarly, the ENABLE_PROCESSED_INPUT mode primarily affects ReadFile and ReadConsole users, except that it also determines whether Ctrl+C input is reported in the input buffer (to be read by the ReadConsoleInput function) or is passed to a HandlerRoutine function defined by the application.

The ENABLE_WINDOW_INPUT and ENABLE_MOUSE_INPUT modes determine whether user interactions involving window resizing and mouse actions are reported in the input buffer or discarded. These events can be read by ReadConsoleInput, but they are always filtered by ReadFile and ReadConsole.

The ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT modes only affect processes using ReadFile or ReadConsole and WriteFile or WriteConsole.

To determine the current mode of a console input buffer or a screen buffer, use the GetConsoleMode function.

See Also

»GetConsoleMode«, »ReadConsole«, »ReadConsoleInput«, »ReadFile«, »WriteConsole«, »WriteFile«


  SetConsoleOutputCP

BOOL SetConsoleOutputCP(IDCodePage)
UINT  IDCodePage;   /* code page to set */

The SetConsoleOutputCP function sets the output code page used by the console associated with the calling process. A console uses its output code page to translate the character values written by the various output functions into the images displayed in the console window.

Parameters

IDCodePage

Identifies the code page to set. The identifiers of the code pages available on the local computer are stored in the registry under the key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To determine a console's current output code page, use the GetConsoleOutputCP function. To set and query a console's input code page, use the SetConsoleCP and GetConsoleCP functions.

See Also

»GetConsoleCP«, »GetConsoleOutputCP«, »SetConsoleCP«


  SetConsoleScreenBufferSize

BOOL SetConsoleScreenBufferSize(hConsoleOutput, coordSize)
HANDLE  hConsoleOutput;   /* handle of console screen buffer  */
COORD  coordSize;   /* new size in character rows and cols. */

The SetConsoleScreenBufferSize function changes the size of the specified console screen buffer.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_WRITE access.

coordSize

Specifies a COORD structure containing the new size, in rows and columns, of the screen buffer. The specified width and height cannot be less than the width and height of the screen buffer's window. The specified dimensions also cannot be less than the minimum size allowed by the system. This minimum depends on the current font size for the console (selected by the user) and the SM_CXMIN and SM_CYMIN values returned by the GetSystemMetrics function. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetConsoleScreenBufferInfo«, »SetConsoleWindowInfo«


  SetConsoleTextAttribute

BOOL SetConsoleTextAttribute(hConsoleOutput, wAttr)
HANDLE  hConsoleOutput;   /* handle of console screen buffer  */
WORD  wAttr;   /* text and background colors */

The SetConsoleTextAttribute function sets the foreground (text) and background color attributes of characters written to the screen buffer by the WriteFile or WriteConsole function, or echoed by the ReadFile or ReadConsole function. This function affects only text written after the function call.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_READ access.

wAttr

Specifies the foreground and background color attributes. Any combination of the following values can be specified: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces white text on a black background.

    FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To determine the current color attributes of a screen buffer, call the GetConsoleScreenBufferInfo function.

See Also

»GetConsoleScreenBufferInfo«, »ReadConsole«, »ReadFile«, »WriteConsole«, »WriteFile«


  SetConsoleTitle

BOOL SetConsoleTitle(lpszTitle)
LPTSTR  lpszTitle;   /* address of new title */

The SetConsoleTitle function sets the title bar string for the current console window.

Parameters

lpszTitle

Points to a null-terminated string that contains the string to appear in the title bar of the console window.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetConsoleTitle«


  SetConsoleWindowInfo

BOOL SetConsoleWindowInfo(hConsoleOutput, fAbsolute, psrctWindowRect)
HANDLE  hConsoleOutput;   /* handle of console screen buffer */
BOOL  fAbsolute;   /* coordinate type flag */
PSMALL_RECT  psrctWindowRect;   /* address of new window rectangle */

The SetConsoleWindowInfo function sets the current size and position of a console screen buffer's window.

Parameters

hConsoleOutput

Identifies a console screen buffer. The handle must have GENERIC_WRITE access.

fAbsolute

Specifies how the coordinates in the structure pointed to by the psrctWindowRect parameter are used. If fAbsolute is TRUE, the coordinates specify the new upper left and lower right corners of the window. If it is FALSE, the coordinates are offsets to the current window-corner coordinates.

psrctWindowRect

Points to a SMALL_RECT structure that contains values that determine the new upper left and lower right corners of the window. The SMALL_RECT structure has the following form:

typedef struct _SMALL_RECT { /* srct */

    SHORT Left;

    SHORT Top;

    SHORT Right;

    SHORT Bottom;

} SMALL_RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The function fails if the specified window rectangle extends beyond the boundaries of the screen buffer. This means that the Top and Left members of the psrctWindowRect rectangle (or the calculated top and left coordinates, if fAbsolute is FALSE) cannot be less than zero. Similarly, the Bottom and Right members (or the calculated bottom and right coordinates) cannot be greater than (screen buffer height −1) and (screen buffer width −1), respectively. The function also fails if the Right member (or calculated right coordinate) is less than or equal to the Left member (or calculated left coordinate) or if the Bottom member (or calculated bottom coordinate) is less than or equal to the Top member (or calculated top coordinate).

For consoles with more than one screen buffer, changing the window location for one screen buffer does not affect the window locations of the other screen buffers.

To determine the current size and position of a screen buffer's window, use the GetConsoleScreenBufferInfo function. This function also returns the maximum size of the window, given the current screen buffer size, the current font size, and the screen size. The GetLargestConsoleWindowSize function returns the maximum window size given the current font and screen and does not consider the size of the screen buffer.

SetConsoleWindowInfo can be used to scroll the contents of the screen buffer by shifting the position of the window rectangle without changing its size.

See Also

»GetConsoleScreenBufferInfo«, »GetLargestConsoleWindowSize«, »ScrollConsoleScreenBuffer«


  SetCurrentDirectory

BOOL SetCurrentDirectory(lpszCurDir)
LPTSTR  lpszCurDir;   /* address of name of new current directory */

The SetCurrentDirectory function changes the current directory for the current process.

Parameters

lpszCurDir

Points to a null-terminated string that specifies the path to the new current directory. This parameter may be a relative path or a fully qualified path. In either case, the fully qualified path of the specified directory is calculated and stored as the current directory.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Each process has a single current directory made up of two parts:

•	A disk designator that is either a drive letter followed by a colon, or a server name and share name: (\\servername\sharename)

•	A directory on the disk designator

See Also

»GetCurrentDirectory«


  SetCursor

HCURSOR SetCursor(hcur)
HCURSOR  hcur;   /* handle of cursor */

The SetCursor function establishes the cursor shape.

Parameters

hcur

Identifies the cursor. The cursor must have been loaded by the LoadCursor function or created by the CreateCursor function. If this parameter is NULL, the cursor is removed from the screen.

Return Value

The return value is the handle of the previous cursor, if there was one. If there was no previous cursor, the return value is NULL.

Comments

The cursor is set only if the new cursor is different from the previous cursor; otherwise, the function returns immediately.

The cursor is a shared resource. A window should set the cursor shape only when the cursor is in its client area or when the window is capturing mouse input. In systems without a mouse, the window should restore the previous cursor before the cursor leaves the client area or before it relinquishes control to another window.

If your application must set the cursor while it is in a window, make sure the class cursor for the given window's class is set to NULL. If the class cursor is not NULL, the system restores the class cursor each time the mouse is moved.

The cursor is not shown on the screen if the internal cursor display count is less than zero. This occurs if the application uses the ShowCursor function to hide the cursor more times than to show the cursor.

See Also

»LoadCursor«, »SetCursorPos«, »ShowCursor«


  SetCursorPos

BOOL SetCursorPos(X, Y)
int  X;   /* horizontal position  */
int  Y;   /* vertical position */

The SetCursorPos function moves the cursor to the specified screen coordinates. If the new coordinates are not within the screen rectangle set by the most recent ClipCursor function, Windows automatically adjusts the coordinates so that the cursor stays within the rectangle.

Parameters

X

Specifies the new x-coordinate (in screen coordinates) of the cursor.

Y

Specifies the new y-coordinate (in screen coordinates) of the cursor.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The cursor is a shared resource. A window should move the cursor only when the cursor is in its client area.

The calling process must have WINSTA_WRITEATTRIBUTES access to the window station.

See Also

»ClipCursor«, »GetCursorPos«, »SetCaretPos«, »SetCursor«, »ShowCursor«


  SetDebugErrorLevel

VOID SetDebugErrorLevel(dwLevel)
DWORD  dwLevel;   /* debugging error level */

The SetDebugErrorLevel function sets the minimum error level at which Windows will generate debugging events and pass them to a debugger.

Parameters

dwLevel

Specifies the minimum error level for debugging events. If an error is equal to or above this level, Windows generates a debugging event. This parameter must be one of the following values:

Value	Meaning
0	The kernel does not report errors. This is the default error level.
SLE_ERROR	Reports only ERROR level debugging events.
SLE_MINORERROR	Reports only MINORERROR level and ERROR level debugging events.
SLE_WARNING	Reports WARNING-level, MINORERROR level, and ERROR level debugging events.
Return Value

This function does not return a value.

Comments

The debugger calls this function to specify the types of errors that it wants to be notified about.

If the debugging error level is greater than the error that occurred, the value for the GetLastError function is set, but the kernel does not generate a debugging event.


  SetDIBits

int SetDIBits(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse)
HDC  hdc;   /* handle of device context */
HBITMAP  hbmp;   /* handle of bitmap */
UINT  uStartScan;   /* starting scan line */
UINT  cScanLines;   /* number of scan lines */
CONST VOID  *lpvBits;   /* array of bitmap bits */
LPBITMAPINFO  lpbmi;   /* address of structure with bitmap data  */
UINT  fuColorUse;   /* type of color indices to use */

The SetDIBits function sets the pixels in the given bitmap using the color data found in the given device-independent bitmap (DIB).

Parameters

hdc

Identifies a device context.

hbmp

Identifies the bitmap that is to be altered using the color data from the given DIB.

uStartScan

Specifies the starting scan line for the device-independent color data in the array pointed to by the lpvBits parameter.

cScanLines

Specifies the number of scan lines found in the array containing device-independent color data.

lpvBits

Points to the DIB color data, stored as an array of bytes. The format of the bitmap values depends on the biBitCount member of the BITMAPINFO structure pointed to by the lpbmi parameter.

lpbmi

Points to a BITMAPINFO data structure that contains information about the DIB. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuColorUse

Specifies whether the bmiColors member of the BITMAPINFO structure was provided and, if so, whether bmiColors contains explicit red, green, blue (RGB) values or palette indices. The fuColorUse parameter must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	The color table consists of an array of 16-bit indices into the logical palette of the device context identified by the hdc parameter.
DIB_RGB_COLORS	The color table is provided and contains literal RGB values.
DIB_PAL_INDICES	There is no color table for the bitmap. The array contains indices into the the system palette.
Return Value

If the function succeeds, the return value is the number of scan lines copied; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Optimal bitmap drawing speed is obtained when the bitmap bits are indices into the system palette.

Applications can retrieve the system palette colors and indices by calling the GetSystemPaletteEntries function. After the colors and indices are retrieved, the application can create the DIB. For more information about the system palette, Chapter 36, "Colors."

The device context identified by the hdc parameter is used only if the DIB_PAL_COLORS constant is set for the fuColorUse parameter; otherwise it is ignored.

The bitmap identified by the hbmp parameter must not be selected into a device context when the application calls this function.

The origin for device-independent bitmaps is the bottom left corner of the bitmap.

See Also

»GetSystemPaletteEntries«


  SetDIBitsToDevice

int SetDIBitsToDevice(hdc, XDest, YDest, dwWidth, dwHeight, XSrc, YSrc, uStartScan,
cScanLines, lpvBits, lpbmi, fuColorUse)
HDC  hdc;   /* handle of device context */
int  XDest;   /* x-coordinate of upper left corner of dest. rect. */
int  YDest;   /* y-coordinate of upper left corner of dest. rect. */
DWORD  dwWidth;   /* source rectangle width */
DWORD  dwHeight;   /* source rectangle height */
int  XSrc;   /* x-coordinate of upper left corner of source rect. */
int  YSrc;   /* y-coordinate of upper left corner of source rect. */
UINT  uStartScan;   /* first scan line in array */
UINT  cScanLines;   /* number of scan lines */
LPVOID  lpvBits;   /* address of array with DIB bits */
LPBITMAPINFO  lpbmi;   /* address of structure with bitmap info.  */
UINT  fuColorUse;   /* RGB or palette indices */

The SetDIBitsToDevice function sets the pixels in the given rectangle on the device that is associated with the destination device context using color data from a device-independent bitmap (DIB).

Parameters

hdc

Identifies the device context.

XDest

Specifies the x-coordinate, in logical units, of the upper left corner of the destination rectangle.

YDest

Specifies the y-coordinate, in logical units, of the upper left corner of the destination rectangle.

dwWidth

Specifies the width, in logical units,  of the DIB.

dwHeight

Specifies the height, in logical units,  of the DIB.

XSrc

Specifies the x-coordinate, in logical units, of the upper left corner of the DIB.

YSrc

Specifies the y-coordinate, in logical units, of the upper left corner of the DIB.

uStartScan

Specifies the starting scan-line in the DIB.

cScanLines

Specifies the number of DIB scan lines contained in the array pointed to by the lpvBits parameter.

lpvBits

Points to DIB color data stored as an array of bytes.

lpbmi

Points to a BITMAPINFO data structure that contains information about the DIB. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fuColorUse

Specifies whether the bmiColors member of the BITMAPINFO data structure contains explicit red, green, blue (RGB) values or indices into a palette. The fuColorUse parameter must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	The color table consists of an array of 16-bit indices into the currently selected logical palette.
DIB_PAL_INDICES	There is no color table for the bitmap. The array contains indices into the system palette. No color translation occurs.
DIB_RGB_COLORS	The color table contains literal RGB values.
Return Value

If the function succeeds, the return value is the number of scan lines set; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Optimal bitmap drawing speed is obtained when the bitmap bits are indices into the system palette.

Applications can retrieve the system palette colors and indices by calling the GetSystemPaletteEntries function. After the colors and indices are retrieved, the application can create the DIB. For more information about the system palette, Chapter 36, "Colors."

The device context identified by the hdc parameter is used only if the DIB_PAL_COLORS constant is set for fuColorUse; otherwise, it is ignored.

The bitmap identified by the hbmp parameter must not be selected into a device context when the application calls this function.

The origin of a device-independent bitmap is the bottom left corner of the bitmap, not the top left corner.

To reduce the amount of memory required to set bits from a large device-independent bitmap on a device surface, an application can band the output by repeatedly calling SetDIBitsToDevice, placing a different portion of the bitmap into the lpvBits array each time. The values of the uStartScan and cScanLines parameters identify the portion of the bitmap contained in the lpvBits array.

See Also

»SetDIBits«


  SetDlgItemInt

BOOL SetDlgItemInt(hwndDlg, idControl, uValue, fSigned)
HWND  hwndDlg;   /* handle of dialog box */
int  idControl;   /* identifier of control */
UINT  uValue;   /* value to set */
BOOL  fSigned;   /* signed or unsigned indicator */

The SetDlgItemInt function sets the text of a given control in a dialog box to the string representation of a given integer value.

Parameters

hwndDlg

Identifies the dialog box that contains the control.

idControl

Specifies the control to be changed.

uValue

Specifies the integer value used to generate the item text.

fSigned

Specifies whether the uValue parameter is signed or unsigned. If this parameter is TRUE, uValue is signed. If this parameter is TRUE and uValue is less than zero, a minus sign is placed before the first digit in the string. If this parameter is FALSE, uValue is unsigned.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE. Use the GetLastError function to obtain extended error information.

Comments

To set the new text, this function sends a WM_SETTEXT message to the given control.

See Also

»GetDlgItemInt«, »SetDlgItemText«


  SetDlgItemText

BOOL SetDlgItemText(hwndDlg, idControl, lpsz)
HWND  hwndDlg;   /* handle of dialog box */
int  idControl;   /* identifier of control  */
LPCTSTR  lpsz;   /* text to set */

The SetDlgItemText function sets the title or text of a control in a dialog box.

Parameters

hwndDlg

Identifies the dialog box that contains the control.

idControl

Identifies the control whose title or text is to be set.

lpsz

Points to the null-terminated string that contains the text to be copied to the control.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE. Use the GetLastError function to get extended error information.

Comments

The SetDlgItemText function sends a WM_SETTEXT message to the given control.

See Also

»GetDlgItemText«, »GetDlgItemInt«, »SetDlgItemInt«


  SetDoubleClickTime

BOOL SetDoubleClickTime(uInterval)
UINT  uInterval;   /* double-click interval */

The SetDoubleClickTime function sets the double-click time for the mouse. A double-click is a series of two clicks of a mouse button, the second occurring within a specified time after the first. The double-click time is the maximum number of milliseconds that may occur between the first and second clicks of a double-click.

Parameters

uInterval

Specifies the number of milliseconds that may occur between the first and second clicks of a double-click. If this parameter is set to zero, Windows uses the default double-click time of 500 milliseconds.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The SetDoubleClickTime function alters the double-click time for all windows in the system.

See Also

»GetDoubleClickTime«


  SetEndOfFile

BOOL SetEndOfFile(hFile)
HANDLE  hFile;   /* handle of file whose EOF is to be set */

The SetEndOfFile function moves the end-of-file position for the specified file to the current position of the file pointer.

Parameters

hFile

Identifies the file to have its end-of-file position moved. The file handle must have been created with GENERIC_WRITE access to the file.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function can be used to truncate or extend a file. If the file is extended, the contents of the file between the old end-of-file position and the new position are not defined.

See Also

»CreateFile«


  SetEnhMetaFileBits

HENHMETAFILE SetEnhMetaFileBits(cbBuffer, lpData)
UINT  cbBuffer;   /* buffer size */
LPBYTE  lpData;   /* buffer that contains enhanced metafile data */

The SetEnhMetaFileBits function creates a memory-based enhanced-format metafile from the supplied data.

Parameters

cbBuffer

Specifies the size, in bytes, of the data provided.

lpData

Points to a buffer that contains enhanced-metafile data. (It is assumed that the data in the buffer was obtained by calling the GetEnhMetaFileBits function.)

Return Value

If the function succeeds, the return value is a handle of a memory-based enhanced metafile; otherwise, it is NULL.

Comments

When the application no longer needs the enhanced-metafile handle, it should delete the handle by calling the DeleteEnhMetaFile function.

The SetEnhMetaFileBits function does not accept metafile data in the Windows format. To import Windows-format metafiles, use the SetWinMetaFileBits function.

See Also

»DeleteEnhMetaFile«, »GetEnhMetaFileBits«, »SetWinMetaFileBits«


  SetEnvironmentVariable

BOOL SetEnvironmentVariable(lpszName, lpszValue)
LPTSTR  lpszName;   /* address of environment variable name  */
LPTSTR  lpszValue;   /* address of new value for variable */

The SetEnvironmentVariable function sets the value of an environment variable for the current process.

Parameters

lpszName

Points to a null-terminated string that specifies the environment variable whose value is being set. The operating system creates the environment variable if it does not exist and lpszValue is not NULL.

lpszValue

Points to a null terminated string containing the new value of the specified environment variable. If this parameter is NULL, the variable is deleted from the current process's environment.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetEnvironmentVariable«


  SetErrorMode

UINT SetErrorMode(fuErrorMode)
UINT  fuErrorMode;   /* error mode */

The SetErrorMode function controls whether Windows handles serious errors or allows the calling application to handle them.

Parameters

fuErrorMode

Specifies the error mode. The flag can be a combination of the following values:

Value	Action
SEM_FAILCRITICALERRORS	Windows does not display the critical-error-handler message box and returns the error to the calling application.
SEM_NOGPFAULTERRORBOX	Windows does not display the general-protection-fault message box. This flag should be set only by debugging applications that handle general protection (GP) faults themselves.
SEM_NOOPENFILEERRORBOX	Windows does not display a message box when it fails to find a file.
Return Value

The return value is the previous state of the error-mode flag.


  SetEvent

BOOL SetEvent(hEvent)
HANDLE  hEvent;   /* handle of event object */

The SetEvent function sets the state of the specified event object to signaled.

Parameters

hEvent

Identifies the event object. The CreateEvent or OpenEvent function returns this handle, which must have EVENT_MODIFY_STATE access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The state of a manual-reset event object remains signaled until it is set explicitly to the nonsignaled state by the ResetEvent function. Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object, can be released while the object's state is signaled.

The state of an auto-reset event object remains signaled until a single waiting thread is released, at which time the system automatically sets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.

See Also

»CreateEvent«, »MsgWaitForMultipleObjects«, »OpenEvent«, »PulseEvent«, »ResetEvent«, »WaitForMultipleObjects«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WaitForSingleObjectEx«


  SetFileApisToOEM

VOID SetFileApisToOEM(VOID)

The SetFileApisToOEM function sets a group of Win32 APIs to produce OEM character set strings. This is useful for 8-bit console input and output.

Parameters

This function has no parameters.

Comments

The 8-bit console APIs use the OEM codepage. All other APIs use the ANSI codepage by default. This means that strings returned by the console APIs may not be processed correctly by the other APIs and vice versa. For example, if FindFirstFileA returns a string that contains certain extended ANSI characters, WriteConsoleA will not display the string properly.

The best long-term solution for a console application is to use Unicode. Short of that solution, a console application should use the SetFileApisToOEM function. That function changes the relevant Windows NT file functions so that they produce OEM character set strings rather than ANSI character set strings.

When dealing with command lines, a console  application should obtain the command line in Unicode form and convert it to OEM form using the relevant  character-to-OEM functions. Also, note that argv uses the ANSI character set.

Here is a list of Windows NT file functions that are involved in this situation:

_lopen	GetDriveType	LoadLibrary
CopyFile	GetFileAttributes	LoadLibraryEx
CreateDirectory	GetFullPathName	MoveFile
CreateFile	GetModuleFileName	MoveFileEx
CreateProcess	GetModuleHandle	OpenFile
DeleteFile	GetSystemDirectory	RemoveDirectory
FindFirstFile	GetTempFileName	SearchPath
FindNextFile	GetTempPath	SetCurrentDirectory
GetCurrentDirectory	GetVolumeInformation	SetFileAttrributes
GetDiskFreeSpace	GetWindowsDirectory	−
GetDiskFreeSpace	GetWindowsDirectory


  SetFileAttributes

BOOL SetFileAttributes(lpFileName, dwFileAttributes)
LPTSTR  lpFileName;   /* address of filename */
DWORD  dwFileAttributes;   /* address of attributes to set */

The SetFileAttributes function sets a file's attributes.

Parameters

lpFileName

Points to a string that specifies the name of the file whose attributes are to be set.

dwFileAttributes

Specifies the file attributes to set for the file. This parameter can be a combination of the following flags. However, all other flags override the FILE_ATTRIBUTE_NORMAL flag.

Attribute	Meaning
FILE_ATTRIBUTE_ARCHIVE
	The file is an archive file. Applications use this flag to mark files for backup or removal.
FILE_ATTRIBUTE_NORMAL
	The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_HIDDEN
	The file is hidden. It is not to be included in an ordinary directory listing.
FILE_ATTRIBUTE_READONLY
	The file is read only. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM
	The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY
	The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access, rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.
FILE_ATTRIBUTE_ATOMIC_WRITE
	The file is an atomic write file. Applications write to the file using atomic write semantics. If any write operation flushes data to the medium, all write operations up to that point are also flushed, as well as any file system structures. This ensures that the data is retrievable at a later time.
FILE_ATTRIBUTE_XACTION_WRITE
	Reserved for future use. Do not specify.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetFileAttributes«


  SetFilePointer

DWORD SetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod)
HANDLE  hFile;   /* handle of file */
LONG  lDistanceToMove;   /* number of bytes to move file pointer */
PLONG  lpDistanceToMoveHigh;   /* address of high-order word of distance to move */
DWORD  dwMoveMethod;   /* how to move */

The SetFilePointer function moves the file pointer of an open file.

Parameters

hFile

Identifies the file whose file pointer is to be moved. The file handle must have been created with GENERIC_READ or GENERIC_WRITE access to the file.

lDistanceToMove

Specifies the number of bytes to move the file pointer. A positive value moves the pointer forward in the file and a negative value moves it backward.

lpDistanceToMoveHigh

Points to the high-order word of the 64-bit distance to move. If the value of this parameter is NULL, this function can operate only on files whose maximum size is (232)−2. If this parameter is specified, the maximum file size is (264)−2. This parameter also receives the high-order word of the new value of the file pointer.

dwMoveMethod

Specifies the starting point for the file pointer move. This parameter can be one of the following values:

Value	Meaning
FILE_BEGIN	The starting point is zero or the beginning of the file. If FILE_BEGIN is specified, DistanceToMove is interpreted as an unsigned location for the new file pointer.
FILE_CURRENT	The current value of the file pointer is the starting point.
FILE_END	The current end-of-file position is the starting point.
Return Value

If the function succeeds, the return value is the low-order doubleword of the new file pointer, and, if lpDistanceToMoveHigh is non-NULL, the function puts the high-order doubleword of the new file pointer into the LONG pointed to by that parameter.

If the function fails, and lpDistanceToMoveHigh is NULL, the return value is 0xFFFFFFFF. Call GetLastError for extended error information.

If the function fails, and lpDistanceToMoveHigh is non-NULL, the return value is 0xFFFFFFFF and GetLastError will return a value other than NO_ERROR.

Comments

Using this function with a handle to a nonseeking device, such as a pipe or a communications device, has no meaning. Use the GetFileType function to determine the file type for hFile.

A multithreaded application should be careful when setting the file pointer. For example, an application whose threads share a file handle, update the file pointer, and read from the file must protect this sequence by using a critical section object or mutex object.

Note that, if the return value is 0xFFFFFFFF and lpDistanceToMoveHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded or failed. Here is some sample code that illustrates the point:

//

// Case One: calling the function with

//           lpDistanceToMoveHigh == NULL

// try to move hFile's file pointer some distance

dwPointer = SetFilePointer (hFile, lDistance,

                            NULL, FILE_BEGIN) ;

// if we failed ...

if (dwPointer == 0xFFFFFFFF) {

    // obtain the error code

    dwError = GetLastError() ;

    // deal with that failure

    .

    .

    .

    } // end of error handler

//

// Case Two: calling the function with

//           lpDistanceToMoveHigh != NULL

// try to move hFile's file pointer some huge distance

dwPointerLow = SetFilePointer (hFile, lDistanceLow,

                               & lDistanceHigh, FILE_BEGIN) ;

// if we failed ...

if (dwPointerLow == 0xFFFFFFFF

    &&

    (dwError = GetLastError()) != NO_ERROR ){

    // deal with that failure

    .

    .

    .

    } // end of error handler

See Also

»ReadFile«, »ReadFileEx«, »WriteFile«, »WriteFileEx«


  SetFileSecurity

BOOL SetFileSecurity(lpszFile, si, psd)
LPTSTR  lpszFile;   /* address of string for filename */
SECURITY_INFORMATION  si;   /* type of information to set */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */

The SetFileSecurity function sets the security of a file or directory object.

Parameters

lpszFile

Points to a null-terminated string specifying the file or directory for which security is set.

si

Specifies a SECURITY_INFORMATION structure identifying the contents of the security descriptor pointed to by the psd parameter.

psd

Points to a SECURITY_DESCRIPTOR structure.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetFileSecurity function is successful only if the following conditions are met:

•	If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.

•	If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.

•	If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

See Also

»GetFileSecurity«, »SetKernelObjectSecurity«, »SetPrivateObjectSecurity«, »SetUserObjectSecurity«


  SetFileTime

BOOL SetFileTime(hFile, lpftCreation, lpftLastAccess, lpftLastWrite)
HANDLE  hFile;   /* identifies the file */
LPFILETIME  lpftCreation;   /* time the file was created */
LPFILETIME  lpftLastAccess;   /* time the file was last accessed  */
LPFILETIME  lpftLastWrite;   /* time the file was last written */

The SetFileTime function sets the date and time that a file was created, last accessed, or last modified.

Parameters

hFile

Identifies the file for which to set the dates and times. The file handle must have been created with GENERIC_WRITE access to the file.

lpftCreation

Points to a FILETIME structure that contains the date and time the file was created. This parameter can be NULL if the application does not need to set this information. The file allocation table (FAT) file system does not support this time value, so this parameter may be ignored. Both the high-performance file system (HPFS) and the New Technology file system (NTFS) support the creation time value.

The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpftLastAccess

Points to a FILETIME structure that contains the date and time the file was last accessed. The last access time includes the last time the file was written to, read from, or (in the case of executable files) run. This parameter can be NULL if the application does not need to set this information. The FAT file system does not support this time value, so this parameter may be ignored. Both HPFS and NTFS support the access time value.

lpftLastWrite

Points to a FILETIME structure that contains the date and time the file was last written to. This parameter can be NULL if the application does not want to set this information. All file systems support this time value.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetFileSize«, »GetFileTime«, »GetFileType«


  SetFocus

HWND SetFocus(hwnd)
HWND  hwnd;   /* handle of window to receive focus */

The SetFocus function sets the keyboard focus to the given window. All subsequent keyboard input is directed to this window. The window, if any, that previously had the keyboard focus loses it.

Parameters

hwnd

Identifies the window that will receive the keyboard input. If this parameter is NULL, keystrokes are ignored.

Return Value

If the function succeeds, the return value is the handle of the window that previously had the keyboard focus. If there is no such window or if the hwnd parameter is invalid, the return value is NULL.

Comments

If the window identified by the hwnd parameter was created by the calling thread, the keyboard-focus status of the calling thread is set to hwnd. Otherwise, the keyboard-focus status of the calling thread is set to NULL, and the keyboard-focus status of the thread that created the window is set to hwnd.

The SetFocus function sends a WM_KILLFOCUS message to the window that loses the keyboard focus and a WM_SETFOCUS message to the window that receives the keyboard focus. It also activates either the window that receives the focus or the parent of the window that receives the focus.

If a window is active but does not have the focus (that is, no window has the focus), any key pressed will produce the WM_SYSCHAR, WM_SYSKEYDOWN, or WM_SYSKEYUP message. If the VK_MENU key is also pressed, the lParam parameter of the message will have bit 30 set. Otherwise, the messages produced do not have this bit set.

See Also

»GetActiveWindow«, »GetFocus«, »SetActiveWindow«, »SetCapture«, »WM_KILLFOCUS«, »WM_SETFOCUS«, »WM_SYSCHAR«, »WM_SYSKEYDOWN«, »WM_SYSKEYUP«


  SetForegroundWindow

BOOL SetForegroundWindow(hwnd)
HWND  hwnd;   /* handle of window to bring to foreground */

The SetForegroundWindow function puts the thread that created the given window into the foreground and activates the window. Keyboard input is directed to the window, and various visual cues are changed for the user.

Parameters

hwnd

Identifies the window that should be activated and brought to the foreground.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The foreground window is the window with which the user is working. The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.

See Also

»GetForegroundWindow«


  SetForm

BOOL SetForm(hPrinter, lpszForm, dwLevel, lpbForm)
HANDLE  hPrinter;   /* handle of printer object */
LPTSTR  lpszForm;   /* address of form name */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbForm;   /* address of structure array */

The SetForm function sets the form information for the given printer.

Parameters

hPrinter

Identifies the printer for which the form information is set.

lpszForm

Points to a null-terminated string specifying the form name for which the form information is set.

dwLevel

Specifies the version of the structure to which lpbForm points. This value must be 1.

lpbForm

Points to a FORM_INFO_1 structure. The FORM_INFO_1 structure has the following form:

typedef struct _FORM_INFO_1 { /* fi1 */

    LPTSTR pName;

    SIZEL  Size;

    RECTL  ImageableArea;

} FORM_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter is obtained by calling the OpenPrinter function.

See Also

»OpenPrinter«


  SetGraphicsMode

int SetGraphicsMode(hdc, iMode)
HDC  hdc;   /* handle of the device context  */
int  iMode;   /* graphics mode */

The SetGraphicsMode function sets the graphics mode for the specified device context.

Parameters

hdc

Identifies the device context.

iMode

Specifies the graphics mode. This parameter can be one of the following values:

Value	Meaning
GM_COMPATIBLE	Sets the graphics mode that is compatible with Windows 3.1. This is a default mode. If this value is specified, the application can only modify the world-to-device transform by calling functions that set window and viewport extents and origins, but not by using SetWorldTransform or ModifyWorldTransform; calls to those functions will fail. Examples of functions that set window and viewport extents and origins are SetViewportExtent and SetWindowExtent.
GM_ADVANCED	Sets the advanced graphics mode that allows world transformations. This value must be specified if the application will set or modify the world transformation for the specified device context. In this mode all graphics, including text output, fully comforms to the world-to-device transformation specified in the device context.
Return Value

If the function succeeds, the return value is the old graphics mode; otherwise, it is zero.

Comments

There are three areas in which graphics output differs according to the graphics mode:

1) Text Output: In the GM_COMPATIBLE mode, True Type (or vector font) text output behaves much the same way as raster font text output with respect to the world-to-device transform in the DC. The True Type text is always written from left to right and right side up, even if the rest of the graphics will be flipped in the x or y axis. Only the height of the True type (or vector font) text is scaled appropriately. The only way to write non-horizontal text in the GM_COMPATIBLE mode is to specify non-zero escapement and orientation for the logical font selected in this DC.

In the GM_ADVANCED mode, True Type (or vector font) text output fully conforms to the world-to-device transform in the DC. The raster fonts only have very limited transformation capabilities (stretching by some integer factors); GDI tries to produce the best output it can with raster fonts for non-trivial transforms.

2) Rectangle Exclusion If the default GM_COMPATIBLE graphics mode is set, the system excludes bottom and rightmost edges when it draws rectangles.

The GM_ADVANCED graphics mode is required if applications want to draw rectangles that are bottom right inclusive.

3) Arc Drawing If the default GM_COMPATIBLE graphics mode is set, GDI draws arcs using the current arc direction in the device space. With this convention, arcs do not respect page-to-device transforms that require a flip along the x or y axis.

If the GM_ADVANCED graphics mode is set, GDI always draws arcs in the counter-clockwise direction in logical space. This is equivalent to the statement that, in the GM_ADVANCED graphics mode, both arc control points and arcs themselves fully respect the device context's world-to-device transform.

See Also

»CreateDC«, »GetArcDirection«, »GetDC«, »SetArcDirection«


  SetHandleCount

UINT SetHandleCount(cHandles)
UINT  cHandles;   /* number of file handles needed */

The SetHandleCount function changes the number of file handles available to a task. For FAT-based file systems using the Win32 application programming interface (API), the default maximum number of file handles available to a process is 20. This function has no effect for HPFS- or NTFS-based file systems.

Parameters

cHandles

Specifies the number of file handles needed by the application. The maximum is 255.

Return Value

The return value specifies the number of file handles actually available to the application. It may be fewer than the number specified by the cHandles parameter.


  SetJob

BOOL SetJob(hPrinter, dwJob, dwLevel, lpbJob, dwCommand)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  dwJob;   /* job-identification value */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbJob;   /* address of job info structures  */
DWORD  dwCommand;   /* job-command value */

The SetJob function pauses, resumes, cancels, or restarts the specified print job on the given printer. The function can also be used to set print job parameters such as the job priority, the document name, and so forth.

Parameters

hPrinter

Identifies the printer.

dwJob

Specifies the print job.

dwLevel

Specifies the version of the structure to which lpbJob points. This value must be 0, 1, or 2.

lpbJob

Points to either a JOB_INFO_1 or JOB_INFO_2 structure. If dwLevel is 0, this pointer must be NULL; if dwLevel is 1, the array contains a JOB_INFO_1 structure and if dwLevel is 2, the array contains a JOB_INFO_2 structure.

The JOB_INFO_1 structure has the following form:

typedef struct _JOB_INFO_1 {    /* ji1 */

    DWORD  JobId;

    LPTSTR pPrinterName;

    LPTSTR pMachineName;

    LPTSTR pUserName;

    LPTSTR pDocument;

    LPTSTR pDatatype;

    LPTSTR pStatus;

    DWORD  Status;

    DWORD  Priority;

    DWORD  Position;

    DWORD  TotalPages;

    DWORD  PagesPrinted;

    SYSTEMTIME Submitted;

} JOB_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The JOB_INFO_2 structure has the following form:

typedef struct _JOB_INFO_2 { /* ji2 */

    DWORD      JobId;

    LPTSTR     pPrinterName;

    LPTSTR     pMachineName;

    LPTSTR     pUserName;

    LPTSTR     pDocument;

    LPTSTR     pNotifyName;

    LPTSTR     pDatatype;

    LPTSTR     pPrintProcessor;

    LPTSTR     pParameters;

    LPTSTR     pDriverName;

    LPDEVMODE  pDevMode;

    LPTSTR     pStatus;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD      Status;

    DWORD      Priority;

    DWORD      Position;

    DWORD      StartTime;

    DWORD      UntilTime;

    DWORD      TotalPages;

    DWORD      Size;

    SYSTEMTIME Submitted;

    DWORD      Time;

    DWORD      PagesPrinted ;

} JOB_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwCommand

Specifies the operation which should be performed. It can be one of the following values:

Value	Meaning
JOB_CONTROL_CANCEL	Deletes a print job.
JOB_CONTROL_PAUSE	Pauses a print job.
JOB_CONTROL_RESTART	Restarts a print job. A job can only be restarted if it was printing.
JOB_CONTROL_RESUME	Resumes a paused print job.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetJob function can be used to set various job parameters by supplying a pointer to a JOB_INFO_1 or JOB_INFO_2 structure that contains the necessary data.

To remove or delete all the print jobs for a particular printer, call the SetPrinter function and set the PRINTER_CONTROL_PURGE value.

The following fields of a JOB_INFO_1 or JOB_INFO_2 structure will be ignored on a call to SetJob:

JobId, pPrinterName, pMachineName, pUserName, pDrivername, Size, Submitted, and Time.

See Also

»OpenPrinter«, »SetJob«, »SetPrinter«


  SetKernelObjectSecurity

BOOL SetKernelObjectSecurity(hObject, si, psd)
HANDLE  hObject;   /* handle of object */
SECURITY_INFORMATION  si;   /* type of information to set */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */

The SetKernelObjectSecurity function sets the security of a kernel object. For example, this can be a process, thread, or event.

Parameters

hObject

Identifies a kernel object for which security information is set.

si

Specifies a SECURITY_INFORMATION structure identifying the contents of the security descriptor pointed to by the psd parameter.

psd

Points to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetKernelObjectSecurity function is successful only if the following conditions are met:

•	If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.

•	If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.

•	If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

See Also

»GetKernelObjectSecurity«, »SetFileSecurity«, »SetPrivateObjectSecurity«, »SetUserObjectSecurity«


  SetKeyboardState

BOOL SetKeyboardState(lpbKeyState)
LPBYTE  lpbKeyState;   /* address of array with virtual-key codes */

The SetKeyboardState function copies a 256-byte array of keyboard key states into the calling thread's keyboard-input state table. This is the same table accessed by the GetKeyboardState and GetKeyState functions. Changes made to this table do not affect keyboard input to any other thread.

Parameters

lpbKeyState

Points to a 256-byte array that contains keyboard key states.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Because the SetKeyboardState function alters the input state of the calling thread and not the global input state of the system, an application cannot use SetKeyboardState to set the NUM LOCK, CAPS LOCK, or SCROLL LOCK indicator lights on the keyboard.

For a complete table of virtual key codes, see Appendix B, "Virtual-Key Codes."

See Also

»GetKeyboardState«, »GetKeyState«, »GetAsyncKeyState«, »MapVirtualKey«


  SetLastError

VOID SetLastError(fdwError)
DWORD  fdwError;   /* per-thread error code */

The SetLastError function sets the last-error code for the calling thread.

Parameters

fdwError

Specifies the last-error code for this thread.

Comments

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no Win32 API error code has this bit set. If you are defining an error code for your application, set this bit to indicate that the error code has been defined by an application and to ensure that your error code does not conflict with any system-defined error codes.

This function is intended primarily for dynamic-link libraries (DLLs). Calling this function after an error occurs allows the DLL to emulate the behavior of the Win32 API.

Win32 API functions that return indications of failure call SetLastError when they fail. With one exception, they do NOT call SetLastError when they succeed. So, if three Win32 API function calls are made, and the first one fails and the second two succeed, the error code stored by the first one is still available after the second two succeed. The exception to this no-write-on-success rule is the TlsGetValue function, which needs to clear the last error code when it succeeds to allow checking the error-free retrieval of NULL values.

Applications can retrieve the value saved by this function by using the GetLastError function. The use of GetLastError is optional; an application need call it only if it is interested in knowing the specific reason for a function failure.

The last-error code value is kept in thread local storage so that multiple threads do not overwrite each other's values.

See Also

»GetLastError«, »SetLastErrorEx«, »TlsGetValue«


  SetLastErrorEx

VOID SetLastErrorEx(fdwError, fdwType)
DWORD  fdwError;   /* per-thread error code  */
DWORD  fdwType;   /* error type */

The SetLastErrorEx function sets the last-error code and type for the calling thread.

Parameters

fdwError

Specifies the last-error code for this thread.

fdwType

Specifies the error type. If this process is being controlled by a debugging process, the debugger may take action based on the error type. This parameter can have one of the following values:

Value	Meaning
SLE_ERROR	Invalid data was passed to the function, and complete failure has occurred.
SLE_MINORERROR	Invalid data was passed to the function, but the function has recovered.
SLE_WARNING	Potentially invalid data was passed to the function, but the function has recovered.
0	The last-error value is set without reporting anything to the debugger. This is equivalent to using the SetLastError function.
Comments

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no Win32 API error code has this bit set. If you are defining an error code for your application, set this bit to indicate that the error code has been defined by an application and to ensure that your error code does not conflict with any system-defined error codes.

This function is intended primarily for dynamic-link libraries (DLLs). Calling this function after an error occurs allows the DLL to emulate the behavior of the Win32 API.

The Win32 API functions that return indications of failure call the SetLastError function when they fail. If three Win32 API function calls are made and the first one fails and the second two succeed, the error code stored by the first one is still available after the second two succeed.

Applications can retrieve the value saved by this function by using the GetLastError function.

The last-error code value is kept in thread local storage so that multiple threads do not overwrite each other's values.

See Also

»GetLastError«, »SetLastError«


  SetLocalTime

BOOL SetLocalTime(lpst)
LPSYSTEMTIME  lpst;   /* address of local time to set */

The SetLocalTime function sets the current local time and date.

Parameters

lpst

Points to a SYSTEMTIME structure that contains the current local date and time. The SYSTEMTIME structure has the following form:

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The wDayOfWeek member of the SYSTEMTIME structure is ignored.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The application must have system-time privilege (the SE_SYSTEMTIME_NAME privilege) for this function to succeed. This privilege is disabled by default. Use the AdjustTokenPrivileges function to enable this privilege and again to disable it after the time has been set.

For more information about security privileges, see Chapter 49, "Security."

See Also

»AdjustTokenPrivileges«, »GetLocalTime«, »GetSystemTime«


  SetMailslotInfo

BOOL SetMailslotInfo(hMailslot, dwReadTimeout)
HANDLE  hMailslot;   /* mailslot handle */
DWORD  dwReadTimeout;   /* read time-out */

The SetMailslotInfo function sets the time-out value used by the given mailslot for a read operation.

Parameters

hMailslot

Identifies a mailslot. The CreateMailslot function must create this handle.

dwReadTimeout

Specifies the amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. The following values have special meanings:

Value	Meaning
0	Returns immediately if no message is present. (The system does not treat an immediate return as an error.)
MAILSLOT_WAIT_FOREVER	Waits forever for a message.
This time-out value applies to all subsequent read operations and to all inherited mailslot handles.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The initial time-out value used by a mailslot for a read operation is typically set by CreateMailslot when the mailslot is created.

See Also

»CreateMailslot«, »GetMailslotInfo«


  SetMapMode

int SetMapMode(hdc, fnMapMode)
HDC  hdc;   /* handle of device context */
int  fnMapMode;   /* new mapping mode */

The SetMapMode function sets the mapping mode of the given device context (DC)). The mapping mode defines the unit of measure used to transform page-space units into device-space units, and also defines the orientation of the device's x and y axes.

Parameters

hdc

Identifies the DC.

fnMapMode

Specifies the new mapping mode. It can be any one of the following values:

Value	Description
MM_ANISOTROPIC	Logical units are mapped to arbitrary units with arbitrarily scaled axes. Use the SetWindowExtEx and SetViewportExtEx functions to specify the units, orientation, and scaling that you want.
MM_HIENGLISH	Each logical unit is mapped to 0.001 inch. Positive x is to the right; positive y is up.
MM_HIMETRIC	Each logical unit is mapped to 0.01 millimeter. Positive x is to the right; positive y is up.
MM_ISOTROPIC	Logical units are mapped to arbitrary units with equally scaled axes; that is, one unit along the x-axis is equal to one unit along the y-axis. Use the SetWindowExtEx and SetViewportExtEx functions to specify the units and the orientation of the axes that you want. Graphics device interface makes adjustments as necessary to ensure the x and y units remain the same size (for example, if you set the window extent, the viewport will be adjusted to keep the units isotropic).
MM_LOENGLISH	Each logical unit is mapped to 0.01 inch. Positive x is to the right; positive y is up.
MM_LOMETRIC	Each logical unit is mapped to 0.1 millimeter. Positive x is to the right; positive y is up.
MM_TEXT	Each logical unit is mapped to one device pixel. Positive x is to the right; positive y is down.
MM_TWIPS	Each logical unit is mapped to one twentieth of a printer's point (1/1440 inch, also called a "twip"). Positive x is to the right; positive y is up.
Return Value

If the function succeeds, the return value identifies the previous mapping mode; otherwise, it is zero.

Comments

The MM_TEXT mode allows applications to work in device pixels, whose size varies from device to device.

The MM_HIENGLISH, MM_HIMETRIC, MM_LOENGLISH, MM_LOMETRIC, and MM_TWIPS modes are useful for applications drawing in physically meaningful units (such as inches or millimeters).

The MM_ISOTROPIC mode ensures a 1:1 aspect ratio.

The MM_ANISOTROPIC mode allows the x-coordinates and y-coordinates to be adjusted independently.

See Also

»GetMapMode«, »SetViewportExtEx«, »SetViewportOrgEx«, »SetWindowExtEx«, »SetWindowOrgEx«


  SetMapperFlags

DWORD SetMapperFlags(hdc, dwFlag)
HDC  hdc;   /* handle of device context  */
DWORD  dwFlag;   /* font-mapper flag */

The SetMapperFlags function alters the algorithm the font mapper uses when it maps logical fonts to physical fonts.

Parameters

hdc

Identifies the device context that contains the font-mapper flag.

dwFlag

Specifies whether the font mapper should attempt to match a font's aspect ratio to the current device's aspect ratio. If bit zero is set, the mapper selects only matching fonts.

Return Value

If the function succeeds, the return value is the previous value of the font-mapper flag; otherwise, it is GDI_ERROR. To get extended error information, use the GetLastError function.

Comments

If the dwFlag parameter is set and no matching fonts exist, Windows chooses a new aspect ratio and retrieves a font that matches this ratio.

The remaining bits of the dwFlag parameter must be zero.

See Also

»GetAspectRatioFilterEx«


  SetMenu

BOOL SetMenu(hwnd, hmenu)
HWND  hwnd;   /* handle of window */
HMENU  hmenu;   /* handle of menu */

The SetMenu function assigns a new menu to the given window.

Parameters

hwnd

Identifies the window to which the menu is to be assigned.

hmenu

Identifies the new menu. If this parameter is NULL, the window's current menu is removed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The window is redrawn to reflect the menu change.

The SetMenu function replaces the previous menu, if any, but it does not destroy it. An application should call the DestroyMenu function to accomplish this task.

See Also

»DestroyMenu«, »GetMenu«


  SetMenuItemBitmaps

BOOL SetMenuItemBitmaps(hmenu, uItem, fuFlags, hbmUnchecked, hbmChecked)
HMENU  hmenu;   /* handle of menu */
UINT  uItem;   /* menu item to receive new bitmaps */
UINT  fuFlags;   /* menu item flags */
HBITMAP  hbmUnchecked;   /* handle of unchecked bitmap  */
HBITMAP  hbmChecked;   /* handle of checked bitmap */

The SetMenuItemBitmaps function associates the given bitmap with a menu item. Whether the menu item is checked or unchecked, Windows displays the appropriate bitmap next to the menu item.

Parameters

hmenu

Identifies the menu containing the item to receive new check mark bitmaps.

uItem

Specifies the menu item to be changed, as determined by the fuFlags parameter.

fuFlags

Specifies how the uItem parameter is interpreted. The fuFlags parameter must be one of the following values:

Value	Meaning
MF_BYCOMMAND	Indicates that the uItem parameter gives the identifier of the menu item. MF_BYCOMMAND is the default if neither MF_BYCOMMAND nor MF_BYPOSITION is specified.
MF_BYPOSITION	Indicates that the uItem parameter gives the zero-based relative position of the menu item.
hbmUnchecked

Identifies the bitmap displayed when the menu item is not checked.

hbmChecked

Identifies the bitmap displayed when the menu item is checked.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If either the hbmUnchecked or hbmChecked parameter is NULL, Windows displays nothing next to the menu item for the corresponding check state. If both parameters are NULL, Windows displays the default check mark bitmap when the item is checked and removes the bitmap when the item is not checked.

When the menu is destroyed, these bitmaps are not destroyed; it is up to the application to destroy them.

The GetMenuCheckMarkDimensions function retrieves the dimensions of the default check mark used for menu items. These values are used to determine the appropriate size for the bitmaps supplied with this function.

See Also

»GetMenuCheckMarkDimensions«, »GetMenu«


  SetMetaFileBits

The SetMetaFileBits function has been deleted. For Win32 applications, use the SetMetaFileBitsEx function.

See Also

»SetMetaFileBitsEx«


  SetMetaFileBitsEx

HMETAFILE SetMetaFileBitsEx(nSize, lpData)
UINT  nSize;   /* size of Windows-format metafile */
LPBYTE  lpData;   /* address of buffer containing metafile data */

The SetMetaFileBitsEx function creates a memory-based Windows-format metafile from the supplied data.

This function is provided for compatibility with earlier versions of Microsoft Windows. For Win32 applications, use the SetEnhMetaFileBits function.

Parameters

nSize

Specifies the size, in bytes, of the Windows-format metafile.

lpData

Points to a buffer that contains the Windows-format metafile. (It is assumed that the data was obtained by using the GetMetaFileBitsEx function.)

Return Value

If the function succeeds, the return value is a handle of a memory-based Windows-format metafile; otherwise, it is NULL.

Comments

A Windows-format metafile does not support the new curve, path, and transformation functions such as PolyBezier, BeginPath, and SetWorldTransform. Applications that use these new functions and use metafiles to store pictures created by these functions should use the enhanced-format metafile functions.

To convert a Windows-format metafile into an enhanced-format metafile, use the SetWinMetaFileBits function.

When the application no longer needs the metafile handle returned by SetMetaFileBitsEx, it should delete it by calling the DeleteMetaFile function.

See Also

»DeleteMetaFile«, »GetMetaFileBitsEx«, »SetWinMetaFileBits«


  SetMetaRgn

int SetMetaRgn(hdc)
HDC  hdc;   /* handle of device context */

The SetMetaRgn function intersects the current clipping region for the given device context with the current metaregion and saves the combined region as the new metaregion for the given device context. The clipping region is reset to a null region.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value specifies the new clipping region's complexity. It can be any one of the following values:

Value	Meaning
NULLREGION	Region is empty.
SIMPLEREGION	Region is a single rectangle.
COMPLEXREGION	Region is more than one rectangle.
ERROR	An error occurred. (The previous clipping region is unaffected.)
Comments

The current clipping region of a device context is defined by the intersection of its clipping region and its metaregion.

The SetMetaRgn function should only be called after an application's original device context was saved by calling the SaveDC function.

See Also

»GetMetaRgn«


  SetMiterLimit

BOOL SetMiterLimit(hdc, eNewLimit, peOldLimit)
HDC  hdc;   /* handle of device context */
FLOAT  eNewLimit;   /* new miter limit */
PFLOAT  peOldLimit;   /* previous miter limit */

The SetMiterLimit function sets the limit for the length of miter joins for the given device context.

Parameters

hdc

Identifies the device context.

eNewLimit

Specifies the new miter limit for the device context.

peOldLimit

Points to a floating-point value that receives the previous miter limit. If this parameter is NULL, the previous miter limit is not returned.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The miter length is defined as the distance from the intersection of the line walls on the inside of the join to the intersection of the line walls on the outside of the join. The miter limit is the maximum allowed ratio of the miter length to the line width.

The default miter limit is 10.0.

See Also

»ExtCreatePen«


  SetNamedPipeHandleState

BOOL SetNamedPipeHandleState(hNamedPipe, lpdwMode, lpcbMaxCollect,
lpdwCollectDataTimeout)
HANDLE  hNamedPipe;   /* handle of named pipe */
LPDWORD  lpdwMode;   /* address of new pipe mode */
LPDWORD  lpcbMaxCollect;   /* address of max bytes before remote transmission */
LPDWORD  lpdwCollectDataTimeout;     /* address of max time before remote transmission */

The SetNamedPipeHandleState function sets the read mode and the blocking mode of the given named pipe. If the specified handle is to the client end of a named pipe, and the named pipe server process is on a remote computer, the function can also be used to control local buffering.

Parameters

hNamedPipe

Identifies the named pipe instance. This can be a handle to the server end of the pipe, as returned by the CreateNamedPipe function, or to the client end of the pipe, as returned by the CreateFile function. The handle must have GENERIC_WRITE access to the named pipe.

lpdwMode

Points to a 32-bit variable that supplies the new mode. The mode is a combination of a read-mode flag and a wait-mode flag. Set this parameter to NULL if the mode is not being set. Use one of the following read modes:

Value	Meaning
PIPE_READMODE_BYTE
	Data is read from the pipe as a stream of bytes. This is the default if no read mode flag is specified.
PIPE_READMODE_MESSAGE
	Data is read from the pipe as a stream of messages. The function fails if this flag is specified for a byte-type pipe.
Use one of the following wait modes:

Value	Meaning
PIPE_WAIT
	Blocking mode is enabled. This is the default if no wait mode flag is specified. When a blocking mode pipe handle is specified in the ReadFile, WriteFile, or ConnectNamedPipe function, the operations are not finished until there is data to read, all data is written, or a client is connected. This can mean waiting indefinitely in some situations for a client process to perform an action.
PIPE_NOWAIT
	Nonblocking mode is enabled. In this mode, ReadFile, WriteFile, and ConnectNamedPipe always return immediately. Note that nonblocking mode is supported for compatibility with Microsoft® LAN Manager version 2.0, and should not be used to achieve asynchronous I/O with named pipes.
lpcbMaxCollect

Points to a 32-bit variable that specifies the maximum number of bytes collected on the client computer before transmission to the server. This parameter must be NULL if the given pipe handle is to the server end of a named pipe, or if client and server processes are on the same machine. This parameter is ignored if the client process specified the FILE_FLAG_WRITE_THROUGH flag in the CreateFile function when the handle was created. Set this parameter to NULL if the collection count is not being set.

lpdwCollectDataTimeout

Points to a 32-bit variable that specifies the maximum time, in milliseconds, that can pass before a remote named pipe transfers information over the network. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe, or if client and server processes are on the same computer. This parameter is ignored if the client process specified the FILE_FLAG_WRITE_THROUGH flag in the CreateFile function when the handle was created. Set this parameter to NULL if the collection count is not being set.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»ConnectNamedPipe«, »CreateFile«, »CreateNamedPipe«, »GetNamedPipeHandleState«, »ReadFile«, »WriteFile«


  SetPaletteEntries

UINT SetPaletteEntries(hpal, iStart, cEntries, lppe)
HPALETTE  hpal;   /* handle of palette */
UINT  iStart;   /* index of first entry to set */
UINT  cEntries;   /* number of entries to set */
CONST PALETTEENTRY  *lppe;   /* address of array of structures */

The SetPaletteEntries function sets RGB (red, green, blue) color values and flags in a range of entries in a logical palette.

Parameters

hpal

Identifies the logical palette.

iStart

Specifies the first logical-palette entry to be set.

cEntries

Specifies the number of logical-palette entries to be set.

lppe

Points to the first member of an array of PALETTEENTRY structures containing the RGB values and flags. The PALETTEENTRY structure has the following form:

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the number of entries that were set in the logical palette; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

An application can determine whether or not a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

Even if a logical palette has been selected and realized, changes to the palette do not affect the physical palette in the surface. RealizePalette must be called again to set the new logical palette into the surface.

See Also

»GetDeviceCaps«, »RealizePalette«


  SetParent

HWND SetParent(hwndChild, hwndNewParent)
HWND  hwndChild;   /* handle of window whose parent is changing  */
HWND  hwndNewParent;   /* handle of new parent window */

The SetParent function changes the parent window of the given child window.

Parameters

hwndChild

Identifies the child window.

hwndNewParent

Identifies the new parent window. If this parameter is NULL, the desktop window becomes the new parent window.

Return Value

If the function succeeds, the return value is the handle of the previous parent window; otherwise, the return value is NULL. To get extended error information, use the GetLastError function.

Comments

An application can use the SetParent function to set the parent window of a pop-up, overlapped, or child window. The new parent window and the child window must belong to the same application.

If the window identified by the hwndChild parameter is visible, Windows performs the appropriate redrawing and repainting.

See Also

»GetParent«


  SetPixel

COLORREF SetPixel(hdc, X, Y, crColor)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of pixel */
int  Y;   /* y-coordinate of pixel */
COLORREF  crColor;   /* pixel color */

The SetPixel function sets the pixel at the specified coordinates to the specified color.

Parameters

hdc

Identifies the device context.

X

Specifies the x-coordinate, in logical units, of the point to be set.

Y

Specifies the y-coordinate, in logical units, of the point to be set.

crColor

Specifies the color to be used to paint the point.

Return Value

If the function succeeds, the return value is the original color of the pixel. If the specified coordinates correspond to a pixel outside the current clipping region, the return value is GDI_ERROR. If the function fails for any other reason, the return value is COLOR_INVALID. To get extended error information, use the GetLastError function.

Comments

The pixel at the specified coordinates must be within the boundaries of the current clipping region.

Not all devices support the SetPixel function. For more information, see the description of the »GetDeviceCaps« function.

See Also

»GetDeviceCaps«, »SetPixelV«


  SetPixelV

BOOL SetPixelV(hdc, X, Y, crColor)
HDC  hdc;   /* handle of device context */
int  X;   /* x-coordinate of pixel */
int  Y;   /* y-coordinate of pixel */
COLORREF  crColor;   /* new pixel color */

The SetPixelV function sets the pixel at the specified coordinates to the closest approximation of the specified color. The point must be in the clipping region and the visible part of the device surface.

Parameters

hdc

Identifies the device context.

X

Specifies the x-coordinate, in logical units, of the point to be set.

Y

Specifies the y-coordinate, in logical units, of the point to be set.

crColor

Specifies the color to be used to paint the point.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Not all devices support the SetPixelV function. For more information, see the RC_BITBLT capability in the »GetDeviceCaps« function.

SetPixelV is faster than SetPixel because it does not need to return the color value of the point actually painted.

See Also

»GetDeviceCaps«, »SetPixel«


  SetPolyFillMode

int SetPolyFillMode(hdc, iPolyFillMode)
HDC  hdc;   /* handle of device context */
int  iPolyFillMode;   /* polygon fill mode */

The SetPolyFillMode function sets the polygon fill mode for functions that fill polygons.

Parameters

hdc

Identifies the device context.

iPolyFillMode

Specifies the new fill mode. This parameter can be either of the following values:

Value	Meaning
ALTERNATE	Selects alternate mode (fills area between odd-numbered and even-numbered polygon sides on each scan line).
WINDING	Selects winding mode (fills any region with a nonzero winding value).
Return Value

The return value specifies the previous filling mode. If an error occurs, the return value is zero.

Comments

In general, the modes differ only in cases where a complex, overlapping polygon must be filled (for example, a five-sided polygon that forms a five-pointed star with a pentagon in the center). In such cases, ALTERNATE mode fills every other enclosed region within the polygon (that is, the points of the star), but WINDING mode fills all regions (that is, the points and the pentagon).

When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and even-numbered polygon sides on each scan line. That is, GDI fills the area between the first and second side, between the third and fourth side, and so on.

When the fill mode is WINDING, GDI fills any region that has a nonzero winding value. This value is defined as the number of times a pen used to draw the polygon would go around the region. The direction of each edge of the polygon is important.

See Also

»GetPolyFillMode«


  SetPrinter

BOOL SetPrinter(hPrinter, dwLevel, lpbPrinter, dwCommand)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbPrinter;   /* address of array containing printer data  */
DWORD  dwCommand;   /* printer-state command */

The SetPrinter function sets the specified printer by pausing printing, resuming printing, or clearing all print jobs. It can also be used to set printer data.

Parameters

hPrinter

Identifies the printer.

dwLevel

Specifies the version of the structure to which lpbPrinter points. This value must be 0, 1, or 2.

lpbPrinter

Points to an array of bytes that may contain printer data. If dwLevel is 0, this pointer must be NULL; if dwLevel is 1, the array contains a PRINTER_INFO_1 structure and if dwLevel is 2, the array contains a PRINTER_INFO_2 structure.

The PRINTER_INFO_1 structure has the following form:

typedef struct _PRINTER_INFO_1 { /* pri1 */

    DWORD  Flags;

    LPTSTR pDescription;

    LPTSTR pName;

    LPTSTR pComment;

} PRINTER_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The PRINTER_INFO_2 structure has the following form:

typedef struct _PRINTER_INFO_2 { /* pri2 */

    LPTSTR    pServerName;

    LPTSTR    pPrinterName;

    LPTSTR    pShareName;

    LPTSTR    pPortName;

    LPTSTR    pDriverName;

    LPTSTR    pComment;

    LPTSTR    pLocation;

    LPDEVMODE pDevMode;

    LPTSTR    pSepFile;

    LPTSTR    pPrintProcessor;

    LPTSTR    pDatatype;

    LPTSTR    pParameters;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD     Attributes;

    DWORD     Priority;

    DWORD     DefaultPriority;

    DWORD     StartTime;

    DWORD     UntilTime;

    DWORD     Status;

    DWORD     cJobs;

    DWORD     AveragePPM;

} PRINTER_INFO_2;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwCommand

Specifies the new printer state. This parameter can be zero or one of the following values. If it is zero, the printer retains its original state and the printer data is reconfigured by using the structure to which lpbPrinter points.

Value	Meaning
PRINTER_CONTROL_PAUSE	Pauses the printer.
PRINTER_CONTROL_PURGE	Deletes all print jobs in the printer.
PRINTER_CONTROL_RESUME	Resumes a paused printer.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The handle hPrinter is obtained by calling the OpenPrinter function.

To modify the current printer settings, an application should call GetPrinter to retrieve the current settings into a PRINTER_INFO_1 or PRINTER_INFO_2 structure, modify the members of that structure as necessary, and then call the SetPrinter function.

The following fields of a PRINTER_INFO_2 structure will be ignored on a call to the SetPrinter function:

pServerName, pPrinterName, and cJobs

Pausing a printer suspends scheduling of all print jobs for that printer, except for the one print job that may be currently printing. Print jobs can be submitted to a paused printer, but no jobs will be scheduled to print on that printer until printing is resumed. If a printer is cleared, all print jobs for that printer are deleted, except for the current print job.

See Also

»AddPrinter«, »GetPrinter«, »OpenPrinter«


  SetPrinterData

DWORD SetPrinterData(hPrinter, lpszType, dwType, lpbData, cbData)
HANDLE  hPrinter;   /* handle of printer object */
LPTSTR  lpszType;   /* address of data type */
DWORD  dwType;   /* flag for value type */
LPBYTE  lpbData;   /* address of array that specifies printer data  */
DWORD  cbData;   /* size, in bytes, of array */

The SetPrinterData function sets the configuration data for a printer.

Parameters

hPrinter

Identifies the printer for which the configuration data should be set.

lpszType

Points to a null-terminated string that specifies the type of data to be set.

dwType

Specifies the type of information to be stored as the value's data. This parameter can be one of the following values:

Value	Meaning
REG_BINARY	Binary data in any form.
REG_DWORD	A 32-bit number.
REG_DWORD_LITTLE_ENDIAN	A 32-bit number in little-endian format (same as REG_DWORD). In little-endian format, the most significant byte of a word is the high-order word. This is the most common format for computers running Windows NT.
REG_DWORD_BIG_ENDIAN	A 32-bit number in big-endian format. In big-endian format, the most significant byte of a word is the low-order word.
REG_EXPAND_SZ	A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
REG_LINK	A Unicode symbolic link.
REG_MULTI_SZ	An array of null-terminated strings, terminated by two null characters.
REG_NONE	No defined value type.
REG_RESOURCE_LIST	A device-driver resource list.
REG_SZ	A null-terminated string. It will be a UNICODE or ANSI string depending on whether you use the UNICODE or ANSI functions.
lpbData

Points to an array of bytes that contains the printer configuration data.

cbData

Specifies the size, in bytes, of the array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The handle hPrinter is obtained by calling the OpenPrinter function.

Existing configuration data for a printer can be retrieved by calling the GetPrinter function.

See Also

»GetPrinter«, »OpenPrinter«


  SetPriorityClass

BOOL SetPriorityClass(hProcess, fdwPriority)
HANDLE  hProcess;   /* handle to the process  */
DWORD  fdwPriority;   /* priority class value */

The SetPriorityClass function sets the priority class for the given process. This value together with the priority value of each thread of the process determines each thread's base priority level.

Parameters

hProcess

Identifies the process. The handle must have PROCESS_SET_INFORMATION access.

fdwPriority

Specifies the priority class for the process. Specify one of the following values:

Priority	Meaning
IDLE_PRIORITY_CLASS	Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS	Indicates a normal process with no special scheduling needs.
HIGH_PRIORITY_CLASS	Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
REALTIME_PRIORITY_CLASS	Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level will scheduling of threads at a lower level take place.

The base priority level of a thread is in the range 1 through 31. Following are the normal base priority levels for each priority class:

Class	Normal base priority
IDLE_PRIORITY_CLASS	4
NORMAL_PRIORITY_CLASS	9 if the window of the process is in the foreground; and 7 if the window is in the background
HIGH_PRIORITY_CLASS	13
REALTIME_PRIORITY_CLASS	24
The SetThreadPriority function enables setting the base priority level of a thread relative to the priority class of its process. For example, specifying THREAD_PRIORITY_HIGHEST in a call to SetThreadPriority for a thread of an IDLE_PRIORITY_CLASS process sets the thread's base priority level to 6.

For IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, and HIGH_PRIORITY_CLASS processes, the system dynamically boosts a thread's base priority level when events occur that are important to the thread. REALTIME_PRIORITY_CLASS processes do not receive dynamic boosts.

The initial priority class of a process can be specified in the CreateProcess function. If not specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS. In this case, the default priority class of the child process is IDLE_PRIORITY_CLASS.

Be very careful when manipulating priorities — to ensure that a high priority thread does not consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system.

The following table shows the base priority levels for each combination of priority class and thread priority value. Note that for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, and HIGH_PRIORITY_CLASS, this base level can receive dynamic boosts.

Base	Priority class/Thread priority
31	Real-time class, THREAD_PRIORITY_TIME_CRITICAL
26	Real-time class, THREAD_PRIORITY_HIGHEST
25	Real-time class, THREAD_PRIORITY_ABOVE_NORMAL
24	Real-time class, THREAD_PRIORITY_NORMAL
23	Real-time class, THREAD_PRIORITY_BELOW_NORMAL
22	Real-time class, THREAD_PRIORITY_LOWEST
16	Real-time class, THREAD_PRIORITY_IDLE
15	Idle, normal, or high class, THREAD_PRIORITY_TIME_CRITICAL High class, THREAD_PRIORITY_HIGHEST
14	High class, THREAD_PRIORITY_ABOVE_NORMAL
13	High class, THREAD_PRIORITY_NORMAL
12	High class, THREAD_PRIORITY_BELOW_NORMAL
11	High class, THREAD_PRIORITY_LOWEST  Foreground normal class, THREAD_PRIORITY_HIGHEST
10	Foreground normal class, THREAD_PRIORITY_ABOVE_NORMAL
9	Foreground normal class, THREAD_PRIORITY_NORMAL  Background normal class, THREAD_PRIORITY_HIGHEST
8	Foreground normal class, THREAD_PRIORITY_BELOW_NORMAL  Background normal class, THREAD_PRIORITY_ABOVE_NORMAL
7	Foreground normal class, THREAD_PRIORITY_LOWEST  Background normal class, THREAD_PRIORITY_NORMAL
6	Background normal class, THREAD_PRIORITY_BELOW_NORMAL  Idle class, THREAD_PRIORITY_HIGHEST
5	Background normal class, THREAD_PRIORITY_LOWEST  Idle class, THREAD_PRIORITY_ABOVE_NORMAL
4	Idle class, THREAD_PRIORITY_NORMAL
3	Idle class, THREAD_PRIORITY_BELOW_NORMAL
2	Idle class, THREAD_PRIORITY_LOWEST
1	Idle, normal, or high class, THREAD_PRIORITY_IDLE
See Also

»CreateProcess«, »CreateThread«, »GetPriorityClass«, »GetThreadPriority«, »SetThreadPriority«


  SetPrivateObjectSecurity

BOOL SetPrivateObjectSecurity(si, psdSource, lppsdTarget, pgm, hClientToken)
SECURITY_INFORMATION  si;   /* type of security information */
PSECURITY_DESCRIPTOR  psdSource;   /* address of SD to apply to object */
PSECURITY_DESCRIPTOR  *lppsdTarget;   /* address of object's SD */
PGENERIC_MAPPING  pgm;   /* address of access-mapping struct  */
HANDLE  hClientToken;   /* handle of client access token */

The SetPrivateObjectSecurity function modifies a private object's security descriptor.

Parameters

si

Specifies a SECURITY_INFORMATION structure identifying the contents of the security descriptor pointed to by the psdSource parameter.

psdSource

Points to a SECURITY_DESCRIPTOR structure to be applied to the object.

lppsdTarget

Points to a pointer to a SECURITY_DESCRIPTOR structure to be altered by this function. This security descriptor must be in self-relative form.

pgm

Points to a GENERIC_MAPPING structure specifying the mapping of generic to specific and standard access types for the object.

The GENERIC_MAPPING structure has the following form:

typedef struct _GENERIC_MAPPING { /* gm */

    ACCESS_MASK GenericRead;

    ACCESS_MASK GenericWrite;

    ACCESS_MASK GenericExecute;

    ACCESS_MASK GenericAll;

} GENERIC_MAPPING;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

hClientToken

Identifies the access token for the client on whose behalf the private object's security is being modified. This parameter is required to ensure that the client has provided a legitimate value for a new owner security identifier (SID). The token must be open for TOKEN_QUERY access.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The object's security descriptor must be in self-relative form.

If necessary, the SetPrivateObjectSecurity function allocates additional memory to produce a larger security descriptor.

The SetPrivateObjectSecurity function is successful only if the following conditions are met:

•	If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.

•	If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.

•	If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

The process calling this function must not be impersonating a client.

See Also

»CreatePrivateObjectSecurity«, »DestroyPrivateObjectSecurity«, »GetPrivateObjectSecurity«, »SetFileSecurity«, »SetKernelObjectSecurity«, »SetUserObjectSecurity«


  SetProcessShutdownParameters

BOOL SetProcessShutdownParameters(dwLevel, dwFlags)
DWORD  dwLevel;   /* shutdown priority */
DWORD  dwFlags;   /* shutdown flags */

The SetProcessShutdownParameters function sets shutdown parameters for the currently calling process. This function sets a process's shutdown order relative to the other processes in the system.

Parameters

dwLevel

Specifies the process's shutdown priority relative to other processes in the system. The system shuts down processes from high dwLevel values to low. The highest and lowest shutdown priorities are reserved for system components. This parameter must be in the following range of values:

Value	Meaning
000−0FF	System reserved last shutdown range.
100−1FF	Application reserved last shutdown range.
200−2FF	Application reserved "in between" shutdown range.
300−3FF	Application reserved first shutdown range.
400−4FF	System reserved first shutdown range.
All processes start at shutdown level 0x280.

dwFlags

Specifies a flags parameter. The flags can be added together:

Value	Meaning
SHUTDOWN_NORETRY	Specifies whether to retry the shutdown if the specified timeout period expires. If this flag is specified, the system terminates the process without displaying a retry dialog for the user.
Return Value

If the function is succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

Applications running in the system security context do not get shut down by the operating system. They get notified of shutdown or logoff through the callback installable via SetConsoleCtrlHandler. They also get notified in the order specified by the dwLevel parameter.

See Also

»GetProcessShutdownParameters«


  SetProp

BOOL SetProp(hwnd, lpsz, hData)
HWND  hwnd;   /* handle of window */
LPCTSTR  lpsz;   /* atom or address of string  */
HANDLE  hData;   /* handle of data */

The SetProp function adds a new entry or changes an existing entry in the property list of the given window. The function adds a new entry to the list if the given character string does not exist already in the list. The new entry contains the string and the handle. Otherwise, the function replaces the string's current handle with the given handle.

Parameters

hwnd

Identifies the window whose property list receives the new entry.

lpsz

Points to a null-terminated string or contains an atom that identifies a string. If this parameter is an atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value, must be placed in the low-order word of lpsz; the high-order word must be zero.

hData

Identifies data to be copied to the property list. The data handle can identify any value useful to the application.

Return Value

If the data handle and string are added to the property list, the return value is TRUE; otherwise, it is FALSE.

Comments

Before destroying a window (that is, before processing the WM_DESTROY message), an application must remove all entries it has added to the property list. The application must use the RemoveProp function to remove the entries.

See Also

»EnumProps«, »EnumPropsEx«, »GetProp«, »GlobalAddAtom«, »RemoveProp«


  SetRect

BOOL SetRect(lprc, nLeft, nTop, nRight, nBottom)
LPRECT  lprc;   /* address of structure with rectangle to set */
int  nLeft;   /* left side */
int  nTop;   /* top side */
int  nRight;   /* right side */
int  nBottom;   /* bottom side */

The SetRect function sets the coordinates of the specified rectangle. This is equivalent to assigning the left, top, right, and bottom arguments to the appropriate members of the RECT structure.

Parameters

lprc

Points to the RECT structure that contains the rectangle to be set. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

nLeft

Specifies the x-coordinate of the rectangle's upper left corner.

nTop

Specifies the y-coordinate of the rectangle's upper left corner.

nRight

Specifies the x-coordinate of the rectangle's lower right corner.

nBottom

Specifies the y-coordinate of the rectangle's lower right corner.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CopyRect«, »SetRectEmpty«, »RECT«


  SetRectEmpty

BOOL SetRectEmpty(lprc)
LPRECT  lprc;   /* address of struct. with rectangle to set to empty */

The SetRectEmpty function creates an empty rectangle in which all coordinates are set to zero.

Parameters

lprc

Points to the RECT structure that contains the coordinates of the rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CopyRect«, »SetRect«


  SetRectRgn

BOOL SetRectRgn(hrgn, nLeftRect, nTopRect, nRightRect, nBottomRect)
HRGN  hrgn;   /* handle of region */
int  nLeftRect;   /* x-coordinate of upper-left corner of rectangle */
int  nTopRect;   /* y-coordinate of upper-left corner of rectangle */
int  nRightRect;   /* x-coordinate of lower-right corner of rectangle */
int  nBottomRect;   /* y-coordinate of lower-right corner of rectangle */

The SetRectRgn function changes the given region into a rectangular region with the specified coordinates.

Parameters

hrgn

Identifies the region.

nLeftRect

Specifies the x-coordinate of the upper-left corner of the rectangular region.

nTopRect

Specifies the y-coordinate of the upper-left corner of the rectangular region.

nRightRect

Specifies the x-coordinate of the lower-right corner of the rectangular region.

nBottomRect

Specifies the y-coordinate of the lower-right corner of the rectangular region.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The region does not include the lower and right boundaries of the rectangle.

See Also

»CreateRectRgn«


  SetResourceHandler

The SetResourceHandler function has been deleted. Calculated resources do not work in the Win32 application environment.


  SetROP2

int SetROP2(hdc, fnDrawMode)
HDC  hdc;   /* handle of device context  */
int  fnDrawMode;   /* drawing mode */

The SetROP2 function sets the current foreground mix mode. GDI uses the foreground mix mode to combine pens and interiors of filled objects with the colors already on the screen. The foreground mix mode defines how colors from the brush or pen and the colors in the existing image are to be combined.

Parameters

hdc

Identifies the device context.

fnDrawMode

Specifies the new mix mode. This parameter can be any one of the following values:

Mix mode	Description
R2_BLACK	Pixel is always 0.
R2_WHITE	Pixel is always 1.
R2_NOP	Pixel remains unchanged.
R2_NOT	Pixel is the inverse of the screen color.
R2_COPYPEN	Pixel is the pen color.
R2_NOTCOPYPEN	Pixel is the inverse of the pen color.
R2_MERGEPENNOT	Pixel is a combination of the pen color and the inverse of the screen color.
R2_MASKPENNOT	Pixel is a combination of the colors common to both the pen and the inverse of the screen.
R2_MERGENOTPEN	Pixel is a combination of the screen color and the inverse of the pen color.
R2_MASKNOTPEN	Pixel is a combination of the colors common to both the screen and the inverse of the pen.
R2_MERGEPEN	Pixel is a combination of the pen color and the screen color.
R2_NOTMERGEPEN	Pixel is the inverse of the R2_MERGEPEN color.
R2_MASKPEN	Pixel is a combination of the colors common to both the pen and the screen.
R2_NOTMASKPEN	Pixel is the inverse of the R2_MASKPEN color.
R2_XORPEN	Pixel is a combination of the colors in the pen and in the screen, but not in both.
R2_NOTXORPEN	Pixel is the inverse of the R2_XORPEN color.
Return Value

If the function succeeds, the return value specifies the previous mix mode; otherwise, it is zero.

Comments

Mix modes define how GDI combines source and destination colors when drawing with the current pen. The mix modes are binary raster operation codes, representing all possible Boolean functions of two variables, using the binary operations AND, OR, and XOR (exclusive OR), and the unary operation NOT. The mix mode is for raster devices only; it is not available for vector devices.

See Also

»GetROP2«


  SetScrollPos

int SetScrollPos(hwnd, fnBar, nPos, fRedraw)
HWND  hwnd;   /* handle of window with scroll bar */
int  fnBar;   /* scroll bar flag */
int  nPos;   /* new position of scroll box  */
BOOL  fRedraw;   /* redraw flag */

The SetScrollPos function sets the position of the scroll box (thumb) in the given scroll bar and, if requested, redraws the scroll bar to reflect the new position of the scroll box.

Parameters

hwnd

Identifies a scroll bar control or a window with a standard scroll bar, depending on the value of the fnBar parameter.

fnBar

Specifies the scroll bar to be set. This parameter can be one of the following values:

Value	Meaning
SB_CTL	Sets the position of the scroll box in a scroll bar control. The hwnd parameter must be the handle of the scroll bar control.
SB_HORZ	Sets the position of the scroll box in a window's standard horizontal scroll bar.
SB_VERT	Sets the position of the scroll box in a window's standard vertical scroll bar.
nPos

Specifies the new position of the scroll box. The position must be within the scrolling range. For more information about the scrolling range, see the description of the »SetScrollRange« function.

fRedraw

Specifies whether the scroll bar is redrawn to reflect the new scroll box position. If this parameter is TRUE, the scroll bar is redrawn. If it is FALSE, the scroll bar is not redrawn.

Return Value

If the function succeeds, the return value is the previous position of the scroll box; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Setting the fRedraw parameter to FALSE is useful if the scroll bar is redrawn by a subsequent call to another function.

Since the messages that indicate scrollbar position are limited to 16 bits, there is a practical maximum value of 65535 for the nPos parameter.

See Also

»GetScrollPos«, »GetScrollRange«, »ScrollDC«, »ScrollWindow«, »SetScrollRange«


  SetScrollRange

BOOL SetScrollRange(hwnd, fnBar, nMinPos, nMaxPos, fRedraw)
HWND  hwnd;   /* handle of window with scroll bar */
int  fnBar;   /* scroll bar flag */
int  nMinPos;   /* minimum scrolling position */
int  nMaxPos;   /* maximum scrolling position  */
BOOL  fRedraw;   /* redraw flag */

The SetScrollRange function sets the minimum and maximum position values for the given scroll bar. It can also be used to hide or show a standard scroll bar.

Parameters

hwnd

Identifies a scroll bar control or a window with a standard scroll bar, depending on the value of the fnBar parameter.

fnBar

Specifies the scroll bar to be set. This parameter can be one of the following values:

Value	Meaning
SB_CTL	Sets the range of a scroll bar control. The hwnd parameter must be the handle of the scroll bar control.
SB_HORZ	Sets the range of a window's standard horizontal scroll bar.
SB_VERT	Sets the range of a window's standard vertical scroll bar.
nMinPos

Specifies the minimum scrolling position.

nMaxPos

Specifies the maximum scrolling position.

fRedraw

Specifies whether the scroll bar should be redrawn to reflect the change. If this parameter is TRUE, the scroll bar is redrawn. If it is FALSE, the scroll bar is not redrawn.

Return Value

If the function succeeds, the return value is TRUE; otherwise it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application should not call the SetScrollRange function to hide a scroll bar while processing a scroll bar message.

If the call to SetScrollRange immediately follows a call to the SetScrollPos function, the fRedraw parameter in SetScrollPos must be zero to prevent the scroll bar from being drawn twice.

The default range for a standard scroll bar is 0 through 100. The default range for a scroll bar control is empty (both the nMinPos and nMaxPos values are zero). The difference between the values specified by the nMinPos and nMaxPos parameters must not be greater than the value of MAXLONG.

Since the messages that indicate scrollbar position are limited to 16 bits, there is a practical maximum value of 65535 for the nMaxPos parameter.

See Also

»GetScrollPos«, »GetScrollRange«, »SetScrollPos«


  SetSecurityDescriptorDacl

BOOL SetSecurityDescriptorDacl(psd, fDaclPresent, pAcl, fDaclDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
BOOL  fDaclPresent;   /* flag for presence of discretionary ACL */
PACL  pAcl;   /* address of discretionary ACL */
BOOL  fDaclDefaulted;   /* flag for default discretionary ACL */

The SetSecurityDescriptorDacl function sets information in a discretionary access-control list (ACL). If a discretionary ACL is already present in the security descriptor, it is replaced.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure to which the function adds the discretionary ACL. This security descriptor must be in absolute format, meaning that its members must be pointers to other structures, rather than offsets to contiguous data.

fDaclPresent

Specifies a flag indicating the presence of a DACL in the security descriptor. If this parameter is TRUE, the function sets the SE_DACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pAcl and fDaclDefaulted parameters. If it is FALSE, the function clears the SE_DACL_PRESENT flag, and pAcl and fDaclDefaulted are ignored.

pAcl

Points to an ACL structure specifying the discretionary ACL for the security descriptor. If this parameter is NULL, a NULL discretionary ACL is assigned to the security descriptor, allowing all access to the object. The discretionary ACL is referenced by, not copied into, the security descriptor.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fDaclDefaulted

Specifies a flag indicating the source of the discretionary ACL. If this flag is TRUE, the discretionary ACL has been retrieved by some default mechanism. If FALSE, the discretionary ACL has been explicitly specified by a user. The function stores this value in the SE_DACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is not specified, the SE_DACL_DEFAULTED flag is cleared.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

There is an important difference between an empty and a nonexistent discretionary ACL. When a discretionary ACL is empty, it contains no access-control entries and no access rights have been explicitly granted. As a result, access to the object is implicitly denied. When an object has no DACL, on the other hand, no protection is assigned to the object, and any access request is granted.

There are three possible outcomes in different configurations of the fDaclPresent flag and the pAcl parameter:

•	When the pACL parameter points to a discretionary ACL and the fDaclPresent flag is TRUE, a discretionary ACL is specified and it must contain access-allowed ACEs to allow access to the object.

•	When the pACL parameter does not point to a discretionary ACL and the fDaclPresent flag is TRUE, a NULL discretionary ACL is specified. All access is allowed.

•	When the pACL parameter does not point to a discretionary ACL and the fDaclPresent flag is FALSE, a discretionary ACL can be provided for the object through an inheritance or default mechanism.

See Also

»GetSecurityDescriptorDacl«, »InitializeSecurityDescriptor«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorOwner«, »SetSecurityDescriptorSacl«


  SetSecurityDescriptorGroup

BOOL SetSecurityDescriptorGroup(psd, psidGroup, fGroupDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
PSID  psidGroup;   /* address of SID for group  */
BOOL  fGroupDefaulted;   /* flag for default */

The SetSecurityDescriptorGroup function sets the primary group information of an absolute-format security descriptor, replacing any primary group information already present in the security descriptor.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure whose primary group is set by this function. The function replaces any existing primary group with the new primary group.

psidGroup

Points to an SID structure the function sets as the security descriptor's new primary group. The SID structure is referenced by, not copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's primary group information. This marks the security descriptor as having no primary group.

fGroupDefaulted

Specifies a flag indicating whether the primary group information was derived from a default mechanism. If this flag is TRUE, it is default information, and the function stores this value as the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is zero, the SE_GROUP_DEFAULTED flag is cleared.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorGroup«, »InitializeSecurityDescriptor«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorOwner«, »SetSecurityDescriptorSacl«


  SetSecurityDescriptorOwner

BOOL SetSecurityDescriptorOwner(psd, psidOwner, fOwnerDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
PSID  psidOwner;   /* address of SID for owner  */
BOOL  fOwnerDefaulted;   /* flag for default */

The SetSecurityDescriptorOwner function sets the owner information of an absolute-format security descriptor. It replaces any owner information already present in the security descriptor.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure whose owner is set by this function. The function replaces any existing owner with the new owner.

psidOwner

Points to an SID structure the function sets as the security descriptor's new primary owner. The SID structure is referenced by, not copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's owner information. This marks the security descriptor as having no owner.

fOwnerDefaulted

Specifies a flag indicating whether the owner information is derived from a default mechanism. If this flag is TRUE, it is default information. The function stores this value as the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is zero, the SE_OWNER_DEFAULTED flag is cleared.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorOwner«, »InitializeSecurityDescriptor«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorSacl«


  SetSecurityDescriptorSacl

BOOL SetSecurityDescriptorSacl(psd, fSaclPresent, pAcl, fSaclDefaulted)
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */
BOOL  fSaclPresent;   /* flag for presence of system ACL */
PACL  pAcl;   /* address of system ACL */
BOOL  fSaclDefaulted;   /* flag for default system ACL */

The SetSecurityDescriptorSacl function sets information in a system access-control list (ACL). If there is already a system ACL present in the security descriptor, it is replaced.

Parameters

psd

Points to the SECURITY_DESCRIPTOR structure to which the function adds the system ACL. This security descriptor must be in absolute format, meaning that its members must be pointers to other structures, rather than offsets to contiguous data.

fSaclPresent

Specifies a flag indicating the presence of a system ACL in the security descriptor. If this parameter is TRUE, the function sets the SE_SACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pAcl and fSaclDefaulted parameters. If it is FALSE, the function does not set the SE_SACL_PRESENT flag, and pAcl and fSaclDefaulted are ignored.

pAcl

Points to an ACL structure that specifies the system ACL for the security descriptor. If this parameter is NULL, a NULL system ACL is assigned to the security descriptor. The system ACL is referenced by, not copied into, the security descriptor.

The ACL structure has the following form:

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

fSaclDefaulted

Specifies a flag indicating the source of the system ACL. If this flag is TRUE, the system ACL has been retrieved by some default mechanism. If it is FALSE, the system ACL has been explicitly specified by a user. The function stores this value in the SE_SACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is not specified, the SE_SACL_DEFAULTED flag is cleared.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetSecurityDescriptorSacl«, »InitializeSecurityDescriptor«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorOwner«


  SetServiceObjectSecurity

BOOL SetServiceObjectSecurity(schService, fdwSecurityInfo, psdSecurityDesc, )
SC_HANDLE  schService;   /* handle of service */
SECURITY_INFORMATION  fdwSecurityInfo;   /* type of security information requested */
PSECURITY_DESCRIPTOR  psdSecurityDesc;   /* address of security descriptor */

The SetServiceObjectSecurity function sets the security descriptor of a service object.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function. The access required for this handle depends on the security information specified in the fdwSecurityInfo parameter.

fdwSecurityInfo

Specifies the security information to be set. Any or all of the following flags can be specified:

Value	Meaning
OWNER_SECURITY_INFORMATION
	Sets the object's owner security identifier (SID). The schService handle must have WRITE_OWNER access, or the calling process must be the object's owner.
GROUP_SECURITY_INFORMATION
	Sets the object's primary group SID. The schService handle must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
	Sets the object's discretionary access control list (ACL). The schService handle must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
	Sets the object's system ACL. The calling process must have SeSecurityPrivilege privilege.
psdSecurityDesc

Points to a SECURITY_DESCRIPTOR structure containing the new security information. For a full description of the SECURITY_DESCRIPTOR structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with the required access, or the calling process is not the owner of the object.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_INVALID_PARAMETER
	The specified security information or security descriptor is invalid.
ERROR_SERVICE_MARKED_FOR_DELETE
	The specified service has been marked for deletion.
Comments

The SetServiceObjectSecurity function sets the specified portions of the service object's security descriptor, based on the information specified in the psdSecurityDesc buffer. This function replaces any or all of the security information associated with the service object, according to the flags set in the fdwSecurityInfo parameter and subject to the calling process's access rights.

The initial security descriptor of a service object is created by the service control manager, based on the security descriptor of the process that called the CreateService function to create the service. The security descriptor can be changed by calling the SetServiceObjectSecurity function.

See Also

»CreateService«, »OpenService«, »QueryServiceObjectSecurity«, »SECURITY_DESCRIPTOR«


  SetServiceStatus

BOOL SetServiceStatus(sshServiceStatus, lpssServiceStatus)
SERVICE_STATUS_HANDLE  sshServiceStatus;   /* service status handle */
LPSERVICE_STATUS  lpssServiceStatus;   /* address of status structure */

The SetServiceStatus function updates the service control manager's status information for the calling service.

Parameters

sshServiceStatus

Specifies a handle to the service control manager's status information structure for the current service. This handle is returned by the RegisterServiceCtrlHandler function.

lpssServiceStatus

Points to the SERVICE_STATUS structure the contains the latest status information for the calling service. The SERVICE_STATUS structure has the following form:

typedef struct _SERVICE_STATUS { /* ss */

    DWORD dwServiceType;

    DWORD dwCurrentState;

    DWORD dwControlsAccepted;

    DWORD dwWin32ExitCode;

    DWORD dwServiceSpecificExitCode;

    DWORD dwCheckPoint;

    DWORD dwWaitHint;

} SERVICE_STATUS, *LPSERVICE_STATUS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_INVALID_HANDLE	The specified handle is invalid.
ERROR_INVALID_DATA	The specified service status structure is invalid.
Comments

A Win32 service's ServiceMain function first calls the RegisterServiceCtrlHandler function to get the service's SERVICE_STATUS_HANDLE. Then it immediately calls the SetServiceStatus function to notify the service control manager of its SERVICE_START_PENDING status.

When a Win32 service receives a control request, the service's Handler function must call this function, even if the service's status did not change. A service can also use this function at any time and by any thread of the service to notify the service control manager of status changes. Examples of such unsolicited status updates include:

•	Checkpoint updates that occur when the service is in transition from one state to another (that is, SERVICE_START_PENDING).

•	An update made necessary by the expected occurrence of a fatal error that causes the service to stop.

A service can call this function only after it has called RegisterServiceCtrlHandler to get a service status handle.

See Also

»RegisterServiceCtrlHandler«, »SERVICE_STATUS«


  SetSoundNoise

The SetSoundNoise function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetStdHandle

BOOL SetStdHandle( IDStdHandle, hHandle)
DWORD  IDStdHandle;   /* input, output, or error device */
HANDLE  hHandle;   /* handle to be a standard handle */

The SetStdHandle function is used to set the handle for the standard input, standard output, or standard error device. The specified handle can be used by subsequent calls to the GetStdHandle function to refer to the input, output, or error device.

Parameters

IDStdHandle

Specifies the handle to be set. This parameter can have one of the following values:

Value	Meaning
STD_INPUT_HANDLE	Standard input handle
STD_OUTPUT_HANDLE	Standard output handle
STD_ERROR_HANDLE	Standard error handle
hHandle

Supplies the handle to store as standard input, standard output, or standard error.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The standard handles of a process may have been redirected by a call to SetStdHandle, in which case GetStdHandle will return the redirected handle. If the standard handles have been redirected, you can specify "CONIN$" in a call to the CreateFile function to get a handle of a console's input buffer. Similarly, you can specify "CONOUT$" to get a handle of the console's active screen buffer.

See Also

»GetStdHandle«


  SetStretchBltMode

int SetStretchBltMode(hdc, iStretchMode)
HDC  hdc;   /* handle of device context */
int  iStretchMode;   /* bitmap stretching mode */

The SetStretchBltMode function sets the bitmap stretching mode in the given device context.

Parameters

hdc

Identifies the device context.

iStretchMode

Specifies the stretching mode. It can be one of the following values:

Value	Description
BLACKONWHITE	Performs a Boolean AND operation using the color values for the eliminated and existing pixels. If the bitmap is a monochrome bitmap, this mode preserves black pixels at the expense of white pixels.
COLORONCOLOR	Deletes the pixels. This mode deletes all eliminated lines of pixels without trying to preserve their information.
WHITEONBLACK	Performs a Boolean OR operation using the color values for the eliminated and existing pixels. If the bitmap is a monochrome bitmap, this mode preserves white pixels at the expense of black pixels.
HALFTONE	Maps pixels from the source rectangle into blocks of pixels in the destination rectangle. The average color over the destination block of pixels approximates the color of the source pixels.
Return Value

If the function succeeds, the return value is the previous stretching-mode; otherwise, it is zero.

Comments

The stretching mode defines how Windows combines rows or columns of a bitmap with existing pixels on a display device when an application calls the StretchBlt function.

The BLACKONWHITE and WHITEONBLACK modes are typically used to preserve foreground pixels in monochrome bitmaps. The COLORONCOLOR mode is typically used to preserve color in color bitmaps.

The HALFTONE mode requires more processing of the source image than the other three modes; it is slower than the others but produces higher quality images.

See Also

»StretchBlt«


  SetSwapAreaSize

The SetSwapAreaSize function is obsolete.


  SetSysColors

BOOL SetSysColors(cDspElements, lpnDspElements, lpdwRgbValues)
int  cDspElements;   /* number of elements to change */
CONST INT  *lpnDspElements;   /* address of array of elements */
CONST COLORREF  *lpdwRgbValues;   /* address of array of RGB values */

The SetSysColors function sets the system colors for one or more display elements. Display elements are the various parts of a window and the Windows background that appear on the screen.

The SetSysColors function sends a WM_SYSCOLORCHANGE message to all windows to inform them of the change in color. It also directs Windows to repaint the affected portions of all currently visible windows.

Parameters

cDspElements

Specifies the number of display elements in the array pointed to by the lpnDspElements parameter.

lpnDspElements

Points to an array of integers that specify the display elements to be changed. This parameter must be one of the following values:

Value	Meaning
COLOR_ACTIVEBORDER	Active window border.
COLOR_ACTIVECAPTION	Active window caption.
COLOR_APPWORKSPACE	Background color of multiple document interface (MDI) applications.
COLOR_BACKGROUND	Desktop.
COLOR_BTNFACE	Face shading on push buttons.
COLOR_BTNSHADOW	Edge shading on push buttons.
COLOR_BTNTEXT	Text on push buttons.
COLOR_CAPTIONTEXT	Text in caption, size box, and scroll bar arrow box.
COLOR_GRAYTEXT	Grayed (disabled) text. This color is set to 0 if the current display driver does not support a solid gray color.
COLOR_HIGHLIGHT	Item(s) selected in a control.
COLOR_HIGHLIGHTTEXT	Text of item(s) selected in a control.
COLOR_INACTIVEBORDER	Inactive window border.
COLOR_INACTIVECAPTION	Inactive window caption.
COLOR_INACTIVECAPTIONTEXT	Color of text in an inactive caption.
COLOR_MENU	Menu background.
COLOR_MENUTEXT	Text in menus.
COLOR_SCROLLBAR	Scroll bar gray area.
COLOR_SHADOW	Color of automatic window shadows.
COLOR_WINDOW	Window background.
COLOR_WINDOWFRAME	Window frame.
COLOR_WINDOWTEXT	Text in windows.
lpdwRgbValues

Points to an array of unsigned long integers that contains the new red, green, blue (RGB) color value for each display element in the array pointed to by the lpnDspElements parameter.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetSysColors function changes the current Windows session only. The new colors are not saved when Windows terminates.

See Also

»GetSysColor«


  SetSysModalWindow

The SetSysModalWindow function has been deleted.


  SetSystemPaletteUse

UINT SetSystemPaletteUse(hdc, uUsage)
HDC  hdc;   /* handle of device context */
UINT  uUsage;   /* palette-usage flag */

The SetSystemPaletteUse function allows an application to specify whether the system palette contains 2 or 20 static colors. The default system palette contains 20 static colors. (Static colors cannot be changed when an application realizes a logical palette.)

Parameters

hdc

Identifies the device context. This device context must refer to a device that supports color palettes.

uUsage

Specifies the new use of the system palette. It can be either of these values:

Value	Meaning
SYSPAL_NOSTATIC	The system palette contains two static colors (black and white).
SYSPAL_STATIC	The system palette contains static colors that will not change when an application realizes its logical palette.
Return Value

If the function succeeds, the return value is the previous usage of the system palette (it can be either SYSPAL_NOSTATIC or SYSPAL_STATIC); otherwise, it is SYSPAL_ERROR. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

When an application window moves to the foreground and SYSPAL_NOSTATIC is set, the application must call GetSysColors to save the current system colors setting. It must also call SetSysColors to set reasonable values using only black and white. When the application returns to the background or terminates, the previous system colors must be restored.

If the function returns SYSPAL_ERROR, the given device context is invalid or does not support color palettes.

See Also

»GetDeviceCaps«, »GetSysColor«, »SetSysColors«


  SetSystemTime

BOOL SetSystemTime(lpst)
LPSYSTEMTIME  lpst;   /* address of system time to set */

The SetSystemTime function sets the current system time and date. The system time is expressed in the Universal Time Convention (UTC).

Parameters

lpst

Points to a SYSTEMTIME structure that contains the current system date and time. The SYSTEMTIME structure has the following form:

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The wDayOfWeek member of the SYSTEMTIME structure is ignored.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The application must have system-time privilege (the SE_SYSTEMTIME_NAME privilege) for this function to succeed. This privilege is disabled by default. Use the AdjustTokenPrivileges function to enable the privilege and again to disable it after the time has been set.

For more information about security privileges, see Chapter 49, "Security."

See Also

»AdjustTokenPrivileges«, »GetSystemTime«


  SetTapeParameters

DWORD SetTapeParameters(hDevice, dwOperation, lpTapeInformation)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwOperation;   /* type of information to set */
LPVOID  lpTapeInformation;   /* buffer for information to set */

The SetTapeParameters function either specifies the block size of a tape or configures the tape device.

Parameters

hDevice

Identifies the device for which to set configuration information. This handle is created by using CreateFile.

dwOperation

Specifies the type of information to set. This must be one of the following values:

Value	Description
SET_TAPE_MEDIA_INFORMATION	Sets the tape-specific information specified by the lpTapeInformation parameter.
GET_TAPE_DRIVE_INFORMATION	Sets the device-specific information specified by lpTapeInformation.
lpTapeInformation

Points to a structure that contains the information to set. If the dwOperation parameter is SET_TAPE_MEDIA_INFORMATION, lpTapeInformation points to a TAPE_SET_MEDIA_PARAMETERS structure.

The TAPE_SET_MEDIA_PARAMETERS structure has the following form:

typedef struct _TAPE_SET_MEDIA_PARAMETERS { /* tsmp */

    ULONG BlockSize;

} TAPE_SET_MEDIA_PARAMETERS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If dwOperation is SET_TAPE_DRIVE_INFORMATION, lpTapeInformation points to a TAPE_SET_DRIVE_PARAMETERS structure.

The TAPE_SET_DRIVE_PARAMETERS structure has the following form:

typedef struct _TAPE_SET_DRIVE_PARAMETERS {  /* tsdp */

    BOOLEAN ECC;

    BOOLEAN Compression;

    BOOLEAN DataPadding;

    BOOLEAN ReportSetmarks;

    ULONG   EOTWarningZoneSize;

} TAPE_SET_DRIVE_PARAMETERS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
See Also

»GetTapeParameters«


  SetTapePosition

DWORD SetTapePosition(hDevice, dwPositionMethod, dwPartition, dwOffsetLow,
lpdwOffsetHigh, bImmediate)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwPositionMethod;   /* type of positioning to perform */
DWORD  dwPartition;   /* new tape partition */
DWORD  dwOffsetLow;   /* low-order 32 bits of tape position */
DWORD  dwOffsetHigh;   /* high-order 32 bits of tape position  */
BOOL  bImmediate;   /* return after operation begins */

The SetTapePosition sets the tape position on the specified device.

Parameters

hDevice

Identifies the device on which to set the tape position. This handle is created by using the CreateFile function.

dwPositionMethod

Specifies the type of positioning to perform. This parameter must be one of the following values:

Value	Meaning
TAPE_ABSOLUTE_BLOCK	Moves the tape to the device-specific block address specified by the dwOffsetLow and dwOffsetHigh parameters. The dwPartition parameter is ignored.
TAPE_LOGICAL_BLOCK	Moves the tape to the block address specified by dwOffsetLow and dwOffsetHigh in the partition specified by dwPartition.
TAPE_REWIND	Moves the tape to the beginning of the current partition. The dwPartition, dwOffsetLow, and dwOffsetHigh parameters are ignored.
TAPE_SPACE_END_OF_DATA	Moves the tape to the end of the data on the partition specified by dwPartition.
TAPE_SPACE_FILEMARKS	Moves the tape forward (or backward) the number of filemarks specified by dwOffsetLow and dwOffsetHigh in the current partition. The dwPartition parameter is ignored.
TAPE_SPACE_RELATIVE_BLOCKS	Moves the tape forward (or backward) the number of blocks specified by dwOffsetLow and dwOffsetHigh in the current partition. The dwPartition parameter is ignored.
TAPE_SPACE_SEQUENTIAL_FMKS	Moves the tape forward (or backward) to the first occurrence of n filemarks in the current partition, where n is the number specified by dwOffsetLow and dwOffsetHigh. The dwPartition parameter is ignored.
TAPE_SPACE_SEQUENTIAL_SMKS	Moves the tape forward (or backward) to the first occurrence of n setmarks in the current partition, where n is the number specified by dwOffsetLow and dwOffsetHigh. The dwPartition parameter is ignored.
TAPE_SPACE_SETMARKS	Moves the tape forward (or backward) the number of setmarks specified by dwOffsetLow and dwOffsetHigh in the current partition. The dwPartition parameter is ignored.
dwPartition

Specifies the partition to position within. If dwPartition is zero, the current partition is used. Partitions are numbered logically from 1 through n, where 1 is the first partition on the tape and n is the last.

dwOffsetLow

Specifies the low-order 32 bits of the block address or count for the position operation specified by the dwPositionMethod parameter.

dwOffsetHigh

Specifies the high-order 32 bits of the block address or count for the position operation specified by the dwPositionMethod parameter. If the high-order 32 bits are not required, this parameter should be zero.

bImmediate

Indicates whether to return as soon as the move operation begins. If this parameter is TRUE, the function returns immediately; if FALSE, the function does not return until the move operation has been completed.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it is one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

If the offset specified by dwOffsetLow and dwOffsetHigh specifies the number of blocks, filemarks, or setmarks to move, a positive offset moves the tape forward to the end of the last block, filemark, or setmark. A negative offset moves the tape backward to the beginning of the last block, filemark, or setmark. If the offset is zero, the tape does not move.

Call the GetTapeParameters function to obtain information about the status, capabilities, and capacities of tape drives and media.

See Also

»GetTapeParameters«, »GetTapePosition«


  SetTextAlign

UINT SetTextAlign(hdc, fMode)
HDC  hdc;   /* handle of device context  */
UINT  fMode;   /* text-alignment flag */

The SetTextAlign function sets the text-alignment flags for the given device context.

Parameters

hdc

Identifies the device context.

fMode

Specifies the text alignment by using a mask of the values in the following list. Only one flag can be chosen from those that affect horizontal and vertical alignment. In addition, only one of the two flags that alter the current position can be chosen.

Value	Meaning
TA_BASELINE	The reference point will be on the base line of the text.
TA_BOTTOM	The reference point will be on the bottom edge of the bounding rectangle.
TA_TOP	The reference point will be on the top edge of the bounding rectangle.
TA_CENTER	The reference point will be aligned horizontally with the center of the bounding rectangle.
TA_LEFT	The reference point will be on the left edge of the bounding rectangle.
TA_RIGHT	The reference point will be on the right edge of the bounding rectangle.
TA_NOUPDATECP	The current position is not updated after each text output call. The reference point is passed to the text output function.
TA_UPDATECP	The current position is updated after each text output call. The current position is used as the reference point.
When the current font has a vertical default base line, as with Kanji, the following values must be used instead of TA_BASELINE and TA_CENTER:

Value	Meaning
VTA_BASELINE	The reference point will be on the base line of the text.
VTA_CENTER	The reference point will be aligned vertically with the center of the bounding rectangle.
The default values are TA_LEFT, TA_TOP, and TA_NOUPDATECP.

Return Value

If the function succeeds, the return value is the previous text-alignment setting; otherwise, it is GDI_ERROR. To get extended error information, use the GetLastError function.

Comments

The TextOut and ExtTextOut functions use the text-alignment flags to position a string of text on a display or other device. The flags specify the relationship between a reference point and a rectangle that bounds the text. The reference point is either the current position or a point passed to a text output function.

The rectangle that bounds the text is formed by the character cells in the text string.

See Also

»ExtTextOut«, »TextOut«


  SetTextCharacterExtra

int SetTextCharacterExtra(hdc, nCharExtra)
HDC  hdc;   /* handle of device context */
int  nCharExtra;   /* extra-space value */

The SetTextCharacterExtra function sets the intercharacter spacing. Intercharacter spacing is added to each character, including break characters, when Windows writes a line of text.

Parameters

hdc

Identifies the device context.

nCharExtra

Specifies the amount of extra space, in logical units, to be added to each character. If the current mapping mode is not MM_TEXT, the nCharExtra parameter is transformed and rounded to the nearest pixel.

Return Value

If the function succeeds, the return value is the previous intercharacter spacing.

See Also

»DrawText«, »TextOut«


  SetTextColor

COLORREF SetTextColor(hdc, crColor)
HDC  hdc;   /* handle of device context  */
COLORREF  crColor;   /* text color */

The SetTextColor function sets the text color for the given device context to the specified color.

Parameters

hdc

Identifies the device context.

crColor

Specifies the color of the text.

Return Value

If the function succeeds, the return value is a color reference for the previous text color; otherwise, it is CLR_INVALID. To get extended error information, use the GetLastError function.

Comments

The text color is used to draw the face of each character written by the TextOut and ExtTextOut functions.

The text color is also used in converting bitmaps from color to monochrome and vice versa.

See Also

»BitBlt«, »ExtTextOut«, »RGB«, »SetBkColor«, »StretchBlt«, »TextOut«


  SetTextJustification

BOOL SetTextJustification(hdc, nBreakExtra, nBreakCount)
HDC  hdc;   /* handle of device context */
int  nBreakExtra;   /* length of extra space, in logical units */
int  nBreakCount;   /* count of space characters in line of text */

The SetTextJustification function specifies the amount of space Windows should add to the break characters in a string of text. The space is added when an application calls the TextOut or ExtTextOut functions.

Parameters

hdc

Identifies the device context.

nBreakExtra

Specifies the total extra space, in logical units, to be added to the line of text. If the current mapping mode is not MM_TEXT, the value identified by the nBreakExtra parameter is transformed and rounded to the nearest pixel.

nBreakCount

Specifies the number of break characters in the line.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The break character is usually the space character (ASCII 32), but it may be defined by a font as some other character. The GetTextMetrics function can be used to retrieve a font's break character.

The TextOut function distributes the specified extra space evenly among the break characters in the line.

The GetTextExtentPoint function is always used with the SetTextJustification function. The GetTextExtentPoint function computes the width of a given line before justification. This width must be known before an appropriate nBreakExtra value can be computed.

SetTextJustification can be used to justify a line that contains multiple strings in different fonts. In this case, each string must be justified separately.

Because rounding errors can occur during justification, Windows keeps a running error term that defines the current error value. When justifying a line that contains multiple runs, GetTextExtentPoint automatically uses this error term when it computes the extent of the next run, allowing TextOut to blend the error into the new run. After each line has been justified, this error term must be cleared to prevent it from being incorporated into the next line. The term can be cleared by calling SetTextJustification with nBreakExtra set to zero.

See Also

»ExtTextOut«, »GetTextExtentPoint«, »GetTextMetrics«, »TextOut«


  SetThreadContext

BOOL SetThreadContext(hThread, lpContext)
HANDLE  hThread;   /* handle of thread with context */
LPCONTEXT  lpContext;   /* address of context structure */

The SetThreadContext function sets the context in the specified thread.

Parameters

hThread

Identifies an open handle of a thread whose context is to be written to. The handle must have THREAD_SET_CONTEXT access to the thread.

lpContext

Points to the address of a CONTEXT structure that contains the context to be set in the specified thread. The value of the ContextFlags member of this structure specifies which portions of a thread's context to set. Some values in the CONTEXT structure that cannot be set are silently set to the correct value. This includes bits in the CPU status register that specify the privileged processor mode, global enabling bits in the debugging register, and other states that must be controlled by the operating system.

Return Value

If the context was set, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The function allows the selective context to be set based on the value of the ContextFlags member of the context structure. The thread identified by the hThread handle is typically being debugged, but the function can also operate even when it is not being debugged.

See Also

»GetThreadContext«


  SetThreadLocale

BOOL SetThreadLocale (locale)
LCID  Locale;   /* locale identifier */

The SetThreadLocale function sets the calling thread's current locale.

When a thread is created, it is given the system default thread locale. The system reads the system default thread locale from the registry when the system boots. This system default can be modified for future process and thread creation using Control Panel's International applet.

Parameters

Locale

A 32-bit LCID value that will become the new locale for the calling thread.

For more information about locale identifiers, see Appendix C, "Locale Identifiers," in the Microsoft Win32 Programmer's Reference, Volume 2.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE/NULL. Call GetLastError for extended error information.

See Also

»GetThreadLocale«, »GetSystemDefaultLCID«, »GetUserDefaultLCID«


  SetThreadPriority

BOOL SetThreadPriority(hThread, nPriority)
HANDLE  hThread;   /* handle to the thread  */
int  nPriority;   /* thread priority level */

The SetThreadPriority function sets the priority value for the given thread. This value together with the priority class of the thread's process determines the thread's base priority level.

Parameters

hThread

Identifies the thread. The handle must have THREAD_SET_INFORMATION access.

nPriority

Specifies the priority value for the thread. This parameter can be one of the following values:

Priority	Meaning
THREAD_PRIORITY_IDLE
	Indicates a base priority level of 1 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 16 for REALTIME_PRIORITY_CLASS processes.
THREAD_PRIORITY_LOWEST
	Indicates 2 points below normal priority for the priority class.
THREAD_PRIORITY_BELOW_NORMAL
	Indicates 1 point below normal priority for the priority class.
THREAD_PRIORITY_NORMAL
	Indicates normal priority for the priority class.
THREAD_PRIORITY_ABOVE_NORMAL
	Indicates 1 point above normal priority for the priority class.
THREAD_PRIORITY_HIGHEST
	Indicates 2 points above normal priority for the priority class.
THREAD_PRIORITY_TIME_CRITICAL
	Indicates a base priority level of 15 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 31 for REALTIME_PRIORITY_CLASS processes.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level does scheduling of threads at a lower level take place.

The SetThreadPriority function enables setting the base priority level of a thread relative to the priority class of its process. For example, specifying THREAD_PRIORITY_HIGHEST in a call to SetThreadPriority for a thread of an IDLE_PRIORITY_CLASS process sets the thread's base priority level to 6. For a table that shows the base priority levels for each combination of priority class and thread priority value, see the »SetPriorityClass« function.

For IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, and HIGH_PRIORITY_CLASS processes, the system dynamically boosts a thread's base priority level when events occur that are important to the thread. REALTIME_PRIORITY_CLASS processes do not receive dynamic boosts.

All threads initially start at THREAD_PRIORITY_NORMAL. Use the GetPriorityClass and SetPriorityClass functions to get and set the priority class of a process. Use the GetThreadPriority function to get the priority value of a thread.

Use the priority class of a process to differentiate between applications that are time critical and those that have normal or below normal scheduling requirements. Use thread priority values to differentiate the relative priorities of the tasks of a process. For example, a thread that handles input for a window could have a higher priority level than a thread that performs CPU intensive calculations.

Be very careful when manipulating priorities — to ensure that a high priority thread does not consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system. Using REALTIME_PRIORITY_CLASS may cause disk caches to not flush, hang the mouse, and so on.

See Also

»GetThreadPriority«, »GetPriorityClass«, »SetPriorityClass«


  SetTimer

UINT SetTimer(hwnd, idTimer, uTimeout, tmprc)
HWND  hwnd;   /* handle of window for timer messages */
UINT  idTimer;   /* timer identifier */
UINT  uTimeout;   /* time-out value */
TIMERPROC  tmprc;   /* address of timer procedure */

The SetTimer function creates a timer with the specified time-out value.

Parameters

hwnd

Identifies the window to be associated with the timer. If this parameter is NULL, no window is associated with the timer and the idTimer parameter is ignored.

idTimer

Specifies a nonzero timer identifier. If the hwnd parameter is NULL, this parameter is ignored.

uTimeout

Specifies the time-out value, in milliseconds.

tmprc

Points to the function to be notified when the time-out value elapses. For more information, see the description of the »TimerProc« callback function.

If tmprc is NULL, the system posts a WM_TIMER message to the application queue. The hwnd member of the message's MSG structure contains the value of the hwnd parameter.

Return Value

If the function succeeds, the return value is an integer identifying the new timer. An application can pass this value, or the string identifier, if it exists, to the KillTimer function to destroy the timer. If the function fails to create a timer, the return value is zero.

Comments

An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer.

The wParam parameter of the WM_TIMER message contains idTimer.

See Also

»KillTimer«, »TimerProc«


  SetTimeZoneInformation

BOOL SetTimeZoneInformation(lptzi)
LPTIME_ZONE_INFORMATION  lptzi;   /* address of time-zone settings */

The SetTimeZoneInformation function sets the current time-zone parameters. These parameters control translations from Coordinated Universal Time (UTC) time to local time.

Parameters

lptzi

Points to a TIME_ZONE_INFORMATION structure that contains the time-zone parameters to set. The TIME_ZONE_INFORMATION structure has the following form:

typedef struct _TIME_ZONE_INFORMATION { /* tzi */

    LONG       Bias;

    WCHAR      StandardName[ 32 ];

    SYSTEMTIME StandardDate;

    LONG       StandardBias;

    WCHAR      DaylightName[ 32 ];

    SYSTEMTIME DaylightDate;

    LONG       DaylightBias;

} TIME_ZONE_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

All translations between UTC time and local time are based on the following formula:

UTC = local time + bias

The bias is the difference, in minutes, between UTC time and local time.

See Also

»GetTimeZoneInformation«


  SetTokenInformation

BOOL SetTokenInformation(hToken, tic, lpvInformation, cbInformation)
HANDLE  hToken;   /* handle of access token */
TOKEN_INFORMATION_CLASS  tic;   /* type of information to set */
LPVOID  lpvInformation;   /* address of information to set  */
DWORD  cbInformation;   /* size of information buffer */

The SetTokenInformation function sets various types of information for a specified access token. The information it sets replaces existing information. The calling process must have appropriate access rights to set the information.

Parameters

hToken

Identifies the access token for which information is to be set.

tic

Specifies a variable of the TOKEN_INFORMATION_CLASS enumerated type identifying the type of information the function sets. The valid values from TOKEN_INFORMATION_CLASS are TokenOwner, TokenPrimaryGroup, and TokenDefaultDacl. For more information about these values, see the description of the lpvInformation parameter.

The TOKEN_INFORMATION_CLASS enumerated type has the following form:

typedef enum tagTOKEN_INFORMATION_CLASS { /* tic */

    TokenUser = 1,

    TokenGroups,

    TokenPrivileges,

    TokenOwner,

    TokenPrimaryGroup,

    TokenDefaultDacl,

    TokenSource,

    TokenType,

    TokenImpersonationLevel,

    TokenStatistics

} TOKEN_INFORMATION_CLASS;

For a full description of this enumerated type, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpvInformation

Points to a buffer containing the information set in the access token. The structure of this buffer depends on the type of information specified by the tic parameter. The following three values are valid in calls to this function:

Token Information Class	Structure Provided
TokenOwner	TOKEN_OWNER structure. TOKEN_ADJUST_DEFAULT access is needed to set owner information. A valid owner value is a user or group identifier with an attribute allowing assignment as the owner of objects.
TokenPrimaryGroup	TOKEN_PRIMARY_GROUP structure. TOKEN_ADJUST_DEFAULT access is needed to set primary group information.
TokenDefaultDacl	TOKEN_DEFAULT_DACL structure. TOKEN_ADJUST_DEFAULT access is needed to set information in the default discretionary access-control list (ACL). The ACL structure provided as a new default discretionary ACL is not validated for correctness or consistency. If the lpvInformation parameter is NULL, the current default discretionary ACL is removed and no replacement is established.
The formats for the structures this function can set are listed in the Comments section.

cbInformation

Specifies the length, in bytes, of the buffer pointed to by lpvInformation.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To set privilege information, an application can call the AdjustTokenPrivileges function. To set a token's groups, an application can call the AdjustTokenGroups function.

Token-type information can be set only when an access token is created.

The TOKEN_OWNER structure has the following form:

typedef struct _TOKEN_OWNER { /* to */

    PSID Owner;

} TOKEN_OWNER;

The TOKEN_PRIMARY_GROUP structure has the following form:

typedef struct _TOKEN_PRIMARY_GROUP { /* tpg */

    PSID PrimaryGroup;

} TOKEN_PRIMARY_GROUP;

The TOKEN_DEFAULT_DACL structure has the following form:

typedef struct _TOKEN_DEFAULT_DACL {  /* tdd */

    PACL DefaultDacl;

} TOKEN_DEFAULT_DACL;

For a full description of these structures, see the Microsoft Win32 Programmer's Reference, Volume 5.

See Also

»AdjustTokenGroups«, »AdjustTokenPrivileges«, »GetTokenInformation«, »OpenProcessToken«, »OpenThreadToken«


  SetupComm

BOOL SetupComm(hCommDev, cbInQueue, cbOutQueue)
HANDLE  hCommDev;   /* handle of the communications device */
DWORD  cbInQueue;   /* size of the input buffer */
DWORD  cbOutQueue;   /* size of the output buffer */

The SetupComm function initializes the communications parameters for a given communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

cbInQueue

Specifies the recommended size, in bytes, of the device's internal input buffer.

cbOutQueue

Specifies the recommended size, in bytes, of the device's internal output buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

After a process uses the CreateFile function to open a handle to a communications device, it can call the SetupComm function to set the communications parameters for the device. If it does not set them, the device uses the default parameters upon the first call to another communications function.

The cbInQueue and cbOutQueue parameters specify the recommended sizes for the internal buffers used by the driver for the specified device. For example, YMODEM protocol packets are slightly larger than 1024 bytes. Therefore, a recommended buffer size might be 1200 bytes for YMODEM communications. For Ethernet-based communications, a recommended buffer size might be 1600 bytes, which is slightly larger than a single Ethernet frame.

The device driver receives the recommended buffer sizes, but is free to use any input/output buffering scheme, as long as it provides reasonable performance and data is not lost due to overrun (except under extreme circumstances). For example, the function can succeed even though the driver does not allocate a buffer, as long as some other portion of the operating system provides equivalent functionality.

If the device driver determines that the recommended buffer sizes involve transfers beyond its ability to handle, the function can fail.

See Also

»SetCommState«


  SetUserObjectSecurity

BOOL SetUserObjectSecurity(hObject, psi, psd)
HANDLE  hObject;   /* handle of user object */
PSECURITY_INFORMATION  psi;   /* address of security information */
PSECURITY_DESCRIPTOR  psd;   /* address of security descriptor */

The SetUserObjectSecurity function sets the security of a user object. This can be, for example, a window, menu, or DDE conversation.

Parameters

hObject

Identifies a user object for which security information is set.

psi

Points to a SECURITY_INFORMATION structure describing the security information being set.

psd

Points to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetUserObjectSecurity function applies changes specified in a security descriptor to the security descriptor assigned to a user object. The object's security descriptor must be in self-relative form. If necessary, this function allocates additional memory to increase the size of the security descriptor.

The SetUserObjectSecurity function is successful only if the following conditions are met:

•	If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.

•	If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.

•	If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

See Also

»GetUserObjectSecurity«, »SetFileSecurity«, »SetKernelObjectSecurity«, »SetPrivateObjectSecurity«


  SetViewportExt

The SetViewportExt function has been deleted. Win32 applications should use the SetViewportExtEx function.

See Also

»SetViewportExtEx«


  SetViewportExtEx

BOOL SetViewportExtEx(hdc, nXExtent, nYExtent, lpSize)
HDC  hdc;   /* handle of device context */
int  nXExtent;   /* new horizontal viewport extent */
int  nYExtent;   /* new vertical viewport extent  */
LPSIZE  lpSize;   /* original viewport extent */

The SetViewportExtEx function sets the horizontal and vertical extents of the viewport for the given device context by using the specified values.

Parameters

hdc

Identifies the device context.

nXExtent

Specifies the horizontal extent, in device units, of the viewport.

nYExtent

Specifies the vertical extent, in device units, of the viewport.

lpSize

Points to a SIZE structure. The previous viewport extents (in device units) are placed in this structure. If lpSize is NULL, nothing is returned. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

When the following mapping modes are set, calls to the SetWindowExtEx and SetViewportExtEx functions are ignored.

•	MM_HIENGLISH

•	MM_HIMETRIC

•	MM_LOENGLISH

•	MM_LOMETRIC

•	MM_TEXT

•	MM_TWIPS

When MM_ISOTROPIC mode is set, an application must call the SetWindowExtEx function before it calls SetViewportExtEx.

See Also

»GetViewportExtEx«, »SetWindowExtEx«


  SetViewportOrg

The SetViewportOrg function has been deleted. Win32 applications should use the SetViewportOrgEx function.

See Also

»SetViewportOrgEx«


  SetViewportOrgEx

BOOL SetViewportOrgEx(hdc, X, Y, lpPoint)
HDC  hdc;   /* handle of device context */
int  X;   /* new x-coordinate of viewport origin */
int  Y;   /* new y-coordinate of viewport origin */
LPPOINT  lpPoint;   /* address of structure receiving original origin */

The SetViewportOrgEx function sets the viewport origin of the given device context (DC) by using the specified coordinates.

Parameters

hdc

Identifies the DC.

X

Specifies the x-coordinate, in device units, of the new viewport origin.

Y

Specifies the y-coordinate, in device units, of the new viewport origin.

lpPoint

Points to a POINT structure. The previous viewport origin (in device coordinates) is placed in this structure. If lpPoint is NULL, nothing is returned. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetViewportOrgEx«, »SetWindowOrgEx«


  SetVoiceAccent

The SetVoiceAccent function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetVoiceEnvelope

The SetVoiceEnvelope function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetVoiceNote

The SetVoiceNote function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetVoiceQueueSize

The SetVoiceQueueSize function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetVoiceSound

The SetVoiceSound function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetVoiceThreshold

The SetVoiceThreshold function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SetVolumeLabel

BOOL SetVolumeLabel(lpRootPathName, lpVolumeName)
LPTSTR  lpRootPathName;   /* name of root directory of volume  */
LPTSTR  lpVolumeName;   /* name for the volume */

The SetVolumeLabel function sets a file system volume's label.

Parameters

lpRootPathName

Points to a null-terminated string specifying the root directory of a file system volume. This is the volume the function will label. If this parameter is NULL, the root of the current directory is used.

lpVolumeName

Points to a string specifying a name for the volume. If this parameter is NULL, the function deletes the specified volume's volume name.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. Call GetLastError for extended error information.

See Also

»GetVolumeInformation«


  SetWindowExt

The SetWindowExt function has been deleted. Win32 applications should use the SetWindowExtEx function.

See Also

»SetWindowExtEx«


  SetWindowExtEx

BOOL SetWindowExtEx(hdc, nXExtent, nYExtent, lpSize)
HDC  hdc;   /* handle of device context */
int  nXExtent;   /* new horizontal window extent */
int  nYExtent;   /* new vertical window extent  */
LPSIZE  lpSize;   /* original window extent */

The SetWindowExtEx function sets the horizontal and vertical extents of the window for the given device context (DC) by using the specified values.

Parameters

hdc

Identifies the DC.

nXExtent

Specifies the window's horizontal extent in logical units.

nYExtent

Specifies the window's vertical extent in logical units.

lpSize

Points to a SIZE structure. The previous window extents (in logical units) are placed in this structure. If lpSize is NULL, nothing is returned. The SIZE structure has the following form:

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

When the following mapping modes are set, calls to the SetWindowExtEx and SetViewportExtEx functions are ignored:

•	MM_HIENGLISH

•	MM_HIMETRIC

•	MM_LOENGLISH

•	MM_LOMETRIC

•	MM_TEXT

•	MM_TWIPS

When MM_ISOTROPIC mode is set, an application must call the SetWindowExtEx function before calling SetViewportExtEx.

See Also

»GetWindowExtEx«, »SetViewportExtEx«,


  SetWindowLong

LONG SetWindowLong(hwnd, nIndex, lNewLong)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* offset of value to set  */
LONG  lNewLong;   /* new value */

The SetWindowLong function changes an attribute of the given window. The function also sets a 32-bit (long) value at the specified offset into the extra window memory of the given window.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus four; for example, if you specified 12 or more bytes of extra memory, a value of 8 would be an index to the third long integer. To set any other value, specify one of the following values:

Value	Action
GWL_EXSTYLE	Sets a new extended window style.
GWL_STYLE	Sets a new window style.
GWL_WNDPROC	Sets a new address for the window procedure.
GWL_HINSTANCE	Sets a new application instance handle.
GWL_ID	Sets a new identifier of the window.
GWL_USERDATA	Sets the long value associated with the window. Each window has a corresponding long value intended for use by the application that created the window.
The following values are also available when the hwnd parameter identifies a dialog box:

Value	Action
DWL_DLGPROC	Sets the new address of the dialog box procedure.
DWL_MSGRESULT	Sets the return value of a message processed in the dialog box procedure.
DWL_USER	Sets new extra information that is private to the application, such as handles or pointers.
lNewLong

Specifies the replacement value.

Return Value

If the function succeeds, the return value is the previous value of the specified 32-bit integer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

If you use the SetWindowLong function and the GWL_WNDPROC index to replace the window procedure, the given window procedure must conform to the guidelines specified in the description of the WindowProc callback function.

Calling SetWindowLong with the GWL_WNDPROC index creates a subclass of the window class used to create the window. An application cannot subclass a window created by another process.

Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASS structure used with the RegisterClass function.

You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function.

See Also

»GetWindowLong«, »GetWindowWord«, »RegisterClass«, »SetParent«, »SetWindowWord«, »WindowProc«


  SetWindowOrg

The SetWindowOrg function has been deleted. Win32 applications should use the SetWindowOrgEx function.

See Also

»SetWindowOrgEx«


  SetWindowOrgEx

BOOL SetWindowOrgEx(hdc, X, Y, lpPoint)
HDC  hdc;   /* handle of device context */
int  X;   /* new x-coordinate of window origin */
int  Y;   /* new y-coordinate of window origin */
LPPOINT  lpPoint;   /* address of structure receiving original origin */

The SetWindowOrgEx function sets the window origin of the given device context (DC) by using the specified coordinates.

Parameters

hdc

Identifies the DC.

X

Specifies the logical x-coordinate of the new window origin.

Y

Specifies the logical y-coordinate of the new window origin.

lpPoint

Points to a POINT structure. The previous origin of the window is placed in this structure. If lpPoint is NULL, nothing is returned. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetViewportOrgEx«, »GetWindowOrgEx«, »SetViewportOrgEx«


  SetWindowPlacement

BOOL SetWindowPlacement(hwnd, lpwndpl)
HWND  hwnd;   /* handle of window */
CONST WINDOWPLACEMENT *  lpwndpl;       /* address of structure with position data */

The SetWindowPlacement function sets the show state and the restored, minimized, and maximized positions of the given window.

Parameters

hwnd

Identifies the window.

lpwndpl

Points to a WINDOWPLACEMENT structure that specifies the new show state and window positions. The WINDOWPLACEMENT structure has the following form:

typedef struct tagWINDOWPLACEMENT {     /* wndpl */

    UINT  length;

    UINT  flags;

    UINT  showCmd;

    POINT ptMinPosition;

    POINT ptMaxPosition;

    RECT  rcNormalPosition;

} WINDOWPLACEMENT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetWindowPlacement«


  SetWindowPos

BOOL SetWindowPos(hwnd, hwndInsertAfter, x, y, cx, cy, fuFlags)
HWND  hwnd;   /* handle of window */
HWND  hwndInsertAfter;   /* placement-order handle */
int  x;   /* horizontal position */
int  y;   /* vertical position */
int  cx;   /* width */
int  cy;   /* height */
UINT  fuFlags;   /* window-positioning flags */

The SetWindowPos function changes the size, position, and Z order of a child, pop-up, or top-level window. Child, pop-up, and top-level windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order.

Parameters

hwnd

Identifies the window.

hwndInsertAfter

Identifies the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values:

Value	Meaning
HWND_BOTTOM	Places the window at the bottom of the Z order. If the hwnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.
HWND_NOTOPMOST	Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.
HWND_TOP	Places the window at the top of the Z order.
HWND_TOPMOST	Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.
For rules about how this parameter is used, see the Comments section.

x

Specifies the new position of the left side of the window.

y

Specifies the new position of the top of the window.

cx

Specifies the new width of the window, in pixels.

cy

Specifies the new height of the window, in pixels.

fuFlags

Specifies the window sizing and positioning flags. This parameter can be a combination of the following values:

Value	Meaning
SWP_DRAWFRAME	Draws a frame (defined in the window's class description) around the window.
SWP_FRAMECHANGED	Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.
SWP_HIDEWINDOW	Hides the window.
SWP_NOACTIVATE	Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hwndInsertAfter parameter).
SWP_NOCOPYBITS	Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
SWP_NOMOVE	Retains the current position (ignores the x and y parameters).
SWP_NOSIZE	Retains the current size (ignores the cx and cy parameters).
SWP_NOREDRAW	Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need to be redrawn.
SWP_NOZORDER	Retains the current Z order (ignores the hwndInsertAfter parameter).
SWP_SHOWWINDOW	Displays the window.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the SWP_SHOWWINDOW or SWP_HIDEWINDOW flag is set, the window cannot be moved or sized.

All coordinates for child windows are client coordinates (relative to the upper left corner of the parent window's client area).

A window can be made a topmost window either by setting the hwndInsertAfter parameter to the HWND_TOPMOST flag and ensuring that the SWP_NOZORDER flag is not set, or by setting a window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed.

If neither the SWP_NOACTIVATE nor SWP_NOZORDER flag is specified (that is, when the application requests that a window be simultaneously activated and its position in the Z order changed), the value specified in hwndInsertAfter is used only in the following circumstances:

•	Neither the HWND_TOPMOST nor HWND_NOTOPMOST flag is specified in hwndInsertAfter.

•	The window identified by hwnd is not the active window.

An application cannot activate an inactive window without also bringing it to the top of the Z order. Applications can change an activated window's position in the Z order without restrictions, or it can activate a window and then move it to the top of the topmost or non-topmost windows.

A topmost window is no longer topmost if it is repositioned to the bottom (HWND_BOTTOM) of the Z order or after any non-topmost window. When a topmost window is made non-topmost, its owners and its owned windows are also made non-topmost windows.

A non-topmost window may own a topmost window, but not vice versa. Any window (for example, a dialog box) owned by a topmost window is itself made a topmost window, to ensure that all owned windows stay above their owner.

See Also

»MoveWindow«


  SetWindowsHook

HHOOK SetWindowsHook(nHookType, pfnHookProc)
int  nHookType;   /* type of hook to install */
HOOKPROC  pfnHookProc;   /* address of hook procedure */

The SetWindowsHook function is obsolete. For Win32 applications, use the SetWindowsHookEx function.


  SetWindowsHookEx

HHOOK SetWindowsHookEx(idHook, hkprc, hMod, dwThreadID)
int  idHook;   /* type of hook to install */
HOOKPROC  hkprc;   /* address of hook procedure */
HINSTANCE  hMod;   /* handle of application instance */
DWORD  dwThreadID;   /* identity of thread to install hook for */

The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. An application installs a hook procedure to monitor the system for certain types of events. A hook procedure can monitor events associated either with a specific thread or with all threads in the system.

Parameters

idHook

Specifies the type of hook procedure to be installed. This parameter can be one of the following values:

Value	Description
WH_CALLWNDPROC	Installs a hook procedure that monitors messages sent to a window procedure. For more information, see the description of the »CallWndProc« hook procedure.
WH_CBT	Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the description of the »CBTProc« hook procedure.
WH_DEBUG	Installs a hook procedure useful for debugging other hook procedures. For more information, see the description of the »DebugProc« hook procedure.
WH_GETMESSAGE	Installs a hook procedure that monitors messages posted to a message queue. For more information, see the description of the »GetMsgProc« hook procedure.
WH_JOURNALPLAYBACK	Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the description of the »JournalPlaybackProc« hook procedure.
WH_JOURNALRECORD	Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the description of the »JournalRecordProc« hook procedure.
WH_KEYBOARD	Installs a hook procedure that monitors keystroke messages. For more information, see the description of the »KeyboardProc« hook procedure.
WH_MOUSE	Installs a hook procedure that monitors mouse messages. For more information, see the description of the »MouseProc« hook procedure.
WH_MSGFILTER	Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. For more information, see the description of the »MessageProc« hook procedure.
WH_SHELL	Installs a hook procedure that receives notifications useful to shell applications. For more information, see the description of the »ShellProc« hook procedure.
WH_SYSMSGFILTER	Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see the description of the »SysMsgProc« hook procedure.
hkprc

Points to the hook procedure. If the dwThreadID parameter is zero or specifies the identifier of a thread created by a different process, the hkprc parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, hkprc can point to a hook procedure in the code associated with the current process.

hMod

Identifies the DLL containing the hook procedure pointed to by the hkprc parameter. The hMod parameter must be set to NULL if the dwThreadID parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.

dwThreadID

Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads.

Return Value

If the function succeeds, the return value is the handle of the hook procedure. Otherwise, the return value is NULL.

Comments

An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process.

Chaining to the next hook procedure (that is, calling the CallNextHookEx function) is optional. An application or library can call the next hook procedure either before or after any processing in its own hook procedure.

Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.

The scope of a hook depends on the hook type. Some hooks can be set only with system scope; others can also be set for only a specific thread, as shown in the following list:

Hook	Scope
WH_CALLWNDPROC	Thread or system
WH_CBT	Thread or system
WH_DEBUG	Thread or system
WH_GETMESSAGE	Thread or system
WH_JOURNALPLAYBACK	System only
WH_JOURNALRECORD	System only
WH_KEYBOARD	Thread or system
WH_MOUSE	Thread or system
WH_MSGFILTER	Thread or system
WH_SHELL	Thread or system
WH_SYSMSGFILTER	System only
For a given hook type, thread hooks are called first, then system hooks.

The system hooks are a shared resource, and installing one affects all applications. All system hook functions must be in libraries. System hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove the hook procedure.

See Also

»CallNextHookEx«, »UnhookWindowsHookEx«


  SetWindowText

BOOL SetWindowText(hwnd, lpsz)
HWND  hwnd;   /* handle of window or control  */
LPCTSTR  lpsz;   /* address of string */

The SetWindowText function changes the text of the given window's title bar (if it has one). If the given window is a control, the text of the control is changed.

Parameters

hwnd

Identifies the window or control whose text is to be changed.

lpsz

Points to a null-terminated string to be used as the new title or control text.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The SetWindowText function causes a WM_SETTEXT message to be sent to the given window or control. If the window is a list box control created with the WS_CAPTION style, however, SetWindowText sets the text for the control, not for the list box entries.

See Also

»GetWindowText«


  SetWindowWord

WORD SetWindowWord(hwnd, nIndex, wNewWord)
HWND  hwnd;   /* handle of window */
int  nIndex;   /* offset of value to set */
WORD  wNewWord;   /* new value */

The SetWindowWord function replaces the 16-bit (word) value at the specified offset into the extra window memory for the given window.

Parameters

hwnd

Identifies the window and, indirectly, the class to which the window belongs.

nIndex

Specifies the zero-based byte offset of the value to be replaced. Valid values are in the range zero through the number of bytes of window memory, minus two; for example, if you specified 10 or more bytes of extra window memory, a value of 8 would be an index to the fifth 16-bit integer.

wNewWord

Specifies the replacement value.

Return Value

If the function succeeds, the return value is the previous value of the specified 16-bit integer; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASS structure used with the RegisterClass function.

The GWW_ values are obsolete in the Win32 application programming interface (API). You must use the SetWindowLong function to set information about the window.

See Also

»GetParent«, »GetWindowLong«, »GetWindowWord«, »SetParent«, »SetWindowLong«


  SetWinMetaFileBits

HENHMETAFILE SetWinMetaFileBits(cbBuffer, lpbBuffer, hdcRef, lpmfp)
UINT  cbBuffer;   /* size of buffer */
LPBYTE  lpbBuffer;   /* address of buffered metafile data */
HDC  hdcRef;   /* handle of reference device context */
LPMETAFILEPICT  lpmfp;   /* suggested size of metafile picture */

The SetWinMetaFileBits function converts a metafile from the older Windows format to the new enhanced format and stores the new metafile in memory.

Parameters

cbBuffer

Specifies the size, in bytes, of the buffer that contains the Windows-format metafile.

lpbBuffer

Points to a buffer that contains the Windows-format metafile data. (It is assumed that the data was obtained by using the GetMetaFileBitsEx or GetWinMetaFileBits function.)

hdcRef

Identifies a reference device.

lpmfp

Points to a METAFILEPICT structure that contains the suggested size of the metafile picture and the mapping mode that was used when the picture was created. The METAFILEPICT structure has the following form:

typedef struct tagMETAFILEPICT { /* mfp */

    LONG      mm;

    LONG      xExt;

    LONG      yExt;

    HMETAFILE hMF;

} METAFILEPICT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is a handle of a memory-based enhanced metafile; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

Windows uses the reference device's resolution data and the data in the METAFILEPICT structure to scale a picture. If the hdcRef parameter is NULL, Windows uses resolution data for the current output device. If the lpmfp parameter is NULL, Windows uses the MM_ANISOTROPIC mapping mode to scale the picture so that it fits the entire device surface. The hMF field in the METAFILEPICT structure is not used.

When the application no longer needs the enhanced metafile handle, it should delete it by calling the DeleteEnhMetaFile function.

The handle returned by this function can be used with other enhanced-metafile functions.

If the reference device is not identical to the device in which the metafile was originally created, some GDI functions that use device units may not draw the picture correctly.

See Also

»DeleteEnhMetaFile«, »GetWinMetaFileBits«, »PlayEnhMetaFile«


  SetWorldTransform

BOOL SetWorldTransform(hdc, lpXform)
HDC  hdc;   /* handle of device context */
LPXFORM  lpXform;   /* address of transformation data */

The SetWorldTransform function sets a two-dimensional linear transformation between world space and page space for the given device context (DC). This transformation can be used to scale, rotate, shear, or translate graphics output.

Parameters

hdc

Identifies the device context (DC).

lpXform

Points to an XFORM structure that contains the transformation data. The XFORM structure has the following form:

typedef struct  tagXFORM {  /* xfrm */

    FLOAT eM11;

    FLOAT eM12;

    FLOAT eM21;

    FLOAT eM22;

    FLOAT eDx;

    FLOAT eDy;

} XFORM;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

For any coordinates (x, y) in world space, the transformed coordinates in page space (x', y') can be determined by the following algorithm:

x' = x * eM11 + y * eM21 + eDx,

y' = x * eM12 + y * eM22 + eDy,

Where the transformation matrix is represented by the following:

| eM11 eM12 0 |

| eM21 eM22 0 |

| eDx  eDy  1 |

The mapping mode (defined by the current window and viewport extents origins) serves to define units and scales.

The world transformation is usually used to scale or rotate logical images in a device-independent way.

The default world transformation is the identity matrix with zero offset.

The SetWorldTransform function will fail unless graphics mode for the given device context (DC) has been set to GM_ADVANCED by previosly calling the SetGraphicsMode function. Likewise, it will not be possible to reset the graphics mode for the DC to the default GM_COMPATIBLE mode, unless the world transform has first been reset to the dafault identity transform by calling SetWorldTransform or ModifyWorldTransform.

See Also

»GetWorldTransform«, »ModifyWorldTransform«, »SetGraphicsMode«, »SetMapMode«, »SetViewportExtEx«, »SetViewportOrgEx«, »SetWindowExtEx«, »SetWindowOrgEx«, »SetWorldTransform«


  ShellExecute

HINSTANCE ShellExecute(hwnd, lpszOp, lpszFile, lpszParams, lpszDir, wShowCmd)
HWND  hwnd;   /* handle of parent window */
LPCTSTR  lpszOp;   /* address of string for operation to perform */
LPCTSTR  lpszFile;   /* address of string for filename */
LPTSTR  lpszParams;   /* address of string for executable-file parameters */
LPCTSTR  lpszDir;   /* address of string for default directory  */
INT  wShowCmd;   /* whether file is shown when opened */

The ShellExecute function opens or prints the given file.

Parameters

hwnd

Identifies the parent window. This window receives any message boxes an application produces (for example, for error reporting).

lpszOp

Points to a null-terminated string specifying the operation to perform. This parameter can be "open" or "print". If this parameter is NULL, "open" is the default value.

lpszFile

Points to a null-terminated string specifying the file to open.

lpszParams

Points to a null-terminated string specifying parameters passed to the application when the lpszFile parameter specifies an executable (.EXE) file. If lpszFile specifies a document file, the lpsz Params parameter is NULL.

lpszDir

Points to a null-terminated string specifying the default directory.

wShowCmd

Specifies whether the application is shown when it is opened. If the lpszFile parameter specifies a document file, this parameter is zero.

Return Value

If the function succeeds, the return value is the instance handle of the application that was run. (This handle could also be the handle of a dynamic data exchange [DDE] server application.) If there is an error, the return value is less than or equal to 32. The possible error values are listed in the following Comments section.

Comments

The file specified by the lpszFile parameter can be a document file or an executable file. If it is a document file, this function opens or prints it, depending on the value of the lpszOp parameter. If it is an executable file, this function opens it, even if lpszOp specifies PRINT.

The ShellExecute function returns 31 if there is no association for the specified file type or if there is no association for the specified action within the file type. The following error values specific to the ShellExecute function have been defined:

Value	Meaning
SE_ERR_ASSOCINCOMPLETE	The filename association is incomplete or invalid.
SE_ERR_DDEBUSY	The DDE transaction could not be completed because other DDE transactions were being processed.
SE_ERR_DDEFAIL	The DDE transaction failed.
SE_ERR_DDETIMEOUT	The DDE transaction could not be completed because the request timed out.
SE_ERR_NOASSOC	There is no application associated with the given filename extension.
SE_ERR_SHARE	A sharing violation occurred.
Following are the other possible error values:

Value	Meaning
0	The system is out of memory or resources.
ERROR_FILE_NOT_FOUND	The specified file was not found.
ERROR_PATH_NOT_FOUND	The specified path was not found.
ERROR_BAD_FORMAT	The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
See Also

»FindExecutable«


  ShellProc

LRESULT CALLBACK ShellProc(nCode, wParam, lParam)
int  nCode;   /* hook code */
WPARAM  wParam;   /* event-specific information  */
LPARAM  lParam;   /* undefined */

The ShellProc hook procedure is an application-defined or library-defined callback function a shell application uses to receive useful notifications from the system.

Parameters

nCode

Specifies the hook code. This parameter can be one of the following values:

Value	Meaning
HSHELL_WINDOWCREATED	A top-level, unowned window has been created. The window exists when the system calls a ShellProc function.
HSHELL_WINDOWDESTROYED	A top-level, unowned window is about to be destroyed. The window still exists when the system calls a ShellProc function.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies additional information the shell application may require. If the nCode parameter is HSHELL_ACTIVATESHELLWINDOW, the wParam parameter is not used. If nCode is HSHELL_WINDOWCREATED or HSHELL_WINDOWDESTROYED, wParam specifies the handle of the window being created or destroyed, respectively.

lParam

Reserved; not used.

Return Value

The return value should be zero.

Comments

An application installs the hook procedure by specifying the WH_SHELL hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

ShellProc is a placeholder for the application-defined or library-defined function name.

See Also

»CallNextHookEx«, »SendMessage«, »SetWindowsHookEx«


  ShowCaret

BOOL ShowCaret(hwnd)
HWND  hwnd;   /* handle of window with caret */

The ShowCaret function makes the caret visible on the screen at the caret's current position. When the caret becomes visible, it begins flashing automatically.

Parameters

hwnd

Identifies the window that owns the caret. If this parameter is NULL, ShowCaret searches the current task for the window that owns the caret.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

ShowCaret shows the caret only if the given window owns the caret, the caret has a shape, and the caret has not been hidden two or more times in a row. If one or more of these conditions is not met, ShowCaret does nothing and returns FALSE.

Hiding is cumulative. If your application calls HideCaret five times in a row, it must also call ShowCaret five times before the caret reappears.

The caret is a shared resource; there is only one caret in the system. A window should show a caret only when the window has the keyboard focus or is active.

See Also

»CreateCaret«, »DestroyCaret«, »GetCaretPos«, »HideCaret«, »SetCaretPos«


  ShowCursor

int ShowCursor(bShow)
BOOL  bShow;   /* cursor visibility flag */

The ShowCursor function displays or hides the cursor.

Parameters

bShow

Specifies whether the internal display counter is to be incremented or decremented. If bShow is TRUE, the display count is incremented by one. If bShow is FALSE, the display count is decremented by one.

Return Value

The return value specifies the new display counter.

Comments

This function sets an internal display counter that determines whether the cursor should be displayed. The cursor is displayed only if the display count is greater than or equal to 0. If a mouse is installed, the initial display count is 0. If no mouse is installed, it is −1.

See Also

»ClipCursor«, »GetCursorPos«, »SetCursor«, »SetCursorPos«


  ShowOwnedPopups

BOOL ShowOwnedPopups(hwnd, fShow)
HWND  hwnd;   /* handle of window */
BOOL  fShow;   /* window visibility flag */

The ShowOwnedPopups function shows or hides all pop-up windows owned by the given window.

Parameters

hwnd

Identifies the window that owns the pop-up windows to be shown or hidden.

fShow

Specifies whether pop-up windows are to be shown or hidden. If this parameter is TRUE, all hidden pop-up windows are shown. If this parameter is FALSE, all visible pop-up windows are hidden.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The ShowOwnedPopups function shows only windows hidden by a previous call to ShowOwnedPopups. For example, if a pop-up window is hidden by using the ShowWindow function, calling ShowOwnedPopups subsequently with the fShow parameter set to TRUE does not cause the window to be shown.

See Also

»IsWindowVisible«, »ShowWindow«


  ShowScrollBar

BOOL ShowScrollBar(hwnd, fnBar, fShow)
HWND  hwnd;   /* handle of window with scroll bar */
int  fnBar;   /* scroll bar flag */
BOOL  fShow;   /* scroll bar visibility flag */

The ShowScrollBar function shows or hides the given scroll bar.

Parameters

hwnd

Identifies a scroll bar control or a window with a standard scroll bar, depending on the value of the fnBar parameter.

fnBar

Specifies the scroll bar(s) to be shown or hidden. This parameter can be one of the following values:

Value	Meaning
SB_BOTH	Shows or hides a window's standard horizontal and vertical scroll bars.
SB_CTL	Shows or hides a scroll bar control. The hwnd parameter must be the handle of the scroll bar control.
SB_HORZ	Shows or hides a window's standard horizontal scroll bars.
SB_VERT	Shows or hides a window's standard vertical scroll bar.
fShow

Specifies whether the scroll bar is shown or hidden. If this parameter is TRUE, the scroll bar is shown; otherwise, it is hidden.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

While processing a scroll bar message, an application should not call this function to hide a scroll bar.

See Also

»GetScrollPos«, »GetScrollRange«, »ScrollDC«, »ScrollWindow«, »SetScrollPos«, »SetScrollRange«


  ShowWindow

BOOL ShowWindow(hwnd, nCmdShow)
HWND  hwnd;   /* handle of window */
int  nCmdShow;   /* show state of window */

The ShowWindow function sets the given window's show state.

Parameters

hwnd

Identifies the window.

nCmdShow

Specifies how the window is to be shown. This parameter can be one of the following values:

Value	Meaning
SW_SHOWDEFAULT	Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application. An application should call ShowWindow with this flag to set the initial show state of its main window.
SW_HIDE	Hides the window and activates another window.
SW_MINIMIZE	Minimizes the specified window and activates the next top-level window in the Z order.
SW_RESTORE	Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_SHOW	Activates the window and displays it in its current size and position. However, if the first call by an application to ShowWindow has nCmdShow set to SW_SHOW, the system uses the startup information mentioned in the description of the SW_SHOWDEFAULT flag. For additional information, see the Comments section.
SW_SHOWMAXIMIZED	Activates the window and displays it as a maximized window.
SW_SHOWMINIMIZED	Activates the window and displays it as a minimized window.
SW_SHOWMINNOACTIVE	Displays the window as a minimized window. The active window remains active.
SW_SHOWNA	Displays the window in its current state. The active window remains active.
SW_SHOWNOACTIVATE	Displays a window in its most recent size and position. The active window remains active.
SW_SHOWNORMAL	Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
Return Value

If the window was previously visible, the return value is TRUE. If the window was previously hidden, the return value is FALSE.

Comments

The ShowWindow function must be called only once per program with the nCmdShow parameter from the WinMain function. Subsequent calls to ShowWindow must use one of the values in the preceding list, instead of the one specified by nCmdShow from WinMain.

As noted in the discussion of the nCmdShow parameter, an application should call ShowWindow with nCmdShow set to the SW_SHOWDEFAULT flag to use application startup information that affects how a window is displayed. For example, Windows Program Manager specifies that applications start with a minimized main window. Win32 applications also use the application startup information when calling ShowWindow for the first time and set nCmdShow to the SW_SHOW flag. This behavior is designed for the following situations:

•	Applications that create their main window by calling CreateWindow with the WS_VISIBLE flag set.

•	Applications that create their main window by calling CreateWindow without the WS_VISIBLE flag set, and later call ShowWindow with the SW_SHOW flag set to make it visible.

See Also

»CreateWindow«, »ShowOwnedPopups«


  SizeofResource

DWORD SizeofResource(hModule, hrsrc)
HINSTANCE  hModule;   /* resource-module handle  */
HRSRC  hrsrc;   /* resource handle */

The SizeofResource function returns the size, in bytes, of the given resource.

Parameters

hModule

Identifies the module whose executable file contains the resource.

hrsrc

Identifies the resource. This handle must be created by using the FindResource or FindResourceEx function.

Return Value

If the function succeeds, the return value is the number of bytes in the resource; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The value returned may be larger than the actual resource because of alignment. An application should not rely upon this value for the exact size of a resource.

See Also

»FindResource«, »FindResourceEx« »LoadResource«, »LockResource«


  Sleep

VOID Sleep(cMilliseconds)
DWORD  cMilliseconds;   /* sleep time in milliseconds */

The Sleep function suspends the execution of the current thread for a specified interval.

Parameters

cMilliseconds

Specifies the time, in milliseconds, for which to suspend execution. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution. A value of INFINITE causes an infinite delay.

Return Value

This function does not return a value.

Comments

A thread can relinquish the remainder of its timeslice by calling this function with a sleep time of zero milliseconds.

See Also

»SleepEx«


  SleepEx

DWORD SleepEx(dwTimeout, fAlertable)
DWORD  dwTimeout;   /* time-out interval in milliseconds  */
BOOL  fAlertable;   /* return if I/O is completed? */

The SleepEx function causes the current thread to enter a waiting state until the specified interval of time has passed, or until an I/O completion callback function is called.

This function is available only in the Win32 API.

Parameters

dwTimeout

Specifies the time, in milliseconds, that the delay is to occur. A value of zero causes the function to return immediately. A value of INFINITE causes an infinite delay.

fAlertable

Specifies whether the function may terminate early due to an I/O completion callback. If fAlertable is FALSE, the function does not return until the time-out period has elapsed. If an I/O completion callback occurs, the function does not return and the I/O completion function is not executed.

If fAlertable is TRUE and the thread that called this function is the same thread that called the extended I/O function (ReadFileEx or WriteFileEx), the function returns when either the time-out period has elapsed or when an I/O completion callback occurs. If an I/O completion callback occurs, the I/O completion function is executed.

Return Value

The return value is zero if the specified time interval expired.

The return value is WAIT_IO_COMPLETION if the function returned due to one or more I/O completion callbacks. This can happen only if fAlertable is TRUE, and if the thread that called the SleepEx function is the same thread that called the extended I/O function.

Comments

This function can be used with the ReadFileEx or WriteFileEx functions to suspend a thread until an I/O operation has been completed. These functions specify a completion routine that is to be executed when the I/O operation has been completed. For the completion routine to be executed, the thread that called the I/O function must be in an alertable wait when the completion callback occurs. A thread goes into an alertable wait by calling either SleepEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx with the function's fAlertable parameter set to TRUE.

A thread can relinquish the remainder of its timeslice by calling this function with a sleep time of zero milliseconds.

See Also

»ReadFileEx«, »Sleep«, »WaitForMultipleObjectsEx«, »WaitForSingleObjectEx«, »WriteFileEx«


  sndPlaySound

BOOL sndPlaySound(lpszSoundName, fuOptions)
LPCTSTR  lpszSoundName;   /* name of sound to play  */
UINT  fuOptions;   /* options flags */

The sndPlaySound function plays a waveform sound specified by a filename or by an entry in the [sounds] section of the registry. If the sound can not be found, the function plays the default sound specified by the SystemDefault entry in the [sounds] section of the registry. If there is no SystemDefault entry or if the default sound can't be found, the function makes no sound and returns FALSE.

Parameters

lpszSoundName

Specifies the name of the sound to play. The function searches the [sounds] section of the registry for an entry with this name and plays the associated waveform file. If no entry by this name exists, the function assumes the name is the name of a waveform file. If this parameter is NULL, any currently playing sound is stopped.

fuOptions

Specifies options for playing the sound. This value can be one or more of the following flags:

Value	Meaning
SND_SYNC	The sound is played synchronously, and the function does not return until the sound ends.
SND_ASYNC	The sound is played asynchronously, and the function returns immediately after beginning the sound. To terminate an asynchronously played sound, call SndPlaySound with the lpszSoundName parameter set to NULL.
SND_NODEFAULT	If the sound can not be found, the function returns silently without playing the default sound.
SND_MEMORY	The parameter specified by lpszSoundName points to an in-memory image of a waveform sound.
SND_LOOP	The sound continues to play repeatedly until sndPlaySound is called again with the lpszSoundName parameter set to NULL. You must also specify the SND_ASYNC flag to loop sounds.
SND_NOSTOP	If a sound is currently playing, the function immediately returns FALSE without playing the requested sound.
Return Value

If the sound is played, the return value is TRUE; otherwise it is FALSE.

Comments

The sound must fit in available physical memory and be playable by an installed waveform audio device driver. The directories searched for sound files are, in order, the current directory, the Windows directory, the Windows system directory, the directories listed in the PATH environment variable, and the directories mapped in a network. See the Win32 »OpenFile« function for more information about the directory search order.

If you specify the SND_MEMORY flag, the lpszSoundName parameter must point to an in-memory image of a waveform sound. If the sound is stored as a resource, use the LoadResource and LockResource functions to load and lock the resource and get a pointer to it. If the sound is not a resource, use the GlobalAlloc function with the GMEM_MOVEABLE flag set to allocate memory for the sound, and the GlobalLock function to lock the memory.

See Also

»MessageBeep«, »PlaySound«


  StartDoc

int StartDoc(hdc, lpdi)
HDC  hdc;   /* handle of device context */
LPDOCINFO  lpdi;   /* address of structure with file names */

The StartDoc function starts a print job. This function replaces the STARTDOC printer escape.

Parameters

hdc

Identifies the device context for the print job.

lpdi

Points to a DOCINFO structure containing the name of the document file and the name of the output file. The DOCINFO structure has the following form:

typedef struct {    /* di */

    int    cbSize;

    LPTSTR lpszDocName;

    LPTSTR lpszOutput;

} DOCINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is greater than zero. This value is the job identifier for the document.

If the function fails, the return value is SP_ERROR. To get extended error information, use the GetLastError function.

Comments

Applications should call the StartDoc function immediately before beginning a print job. Using this function ensures that multipage documents are not interspersed with other print jobs.

Applications can use the value returned by StartDoc to retrieve or set the priority of a print job. Call the GetJob or SetJob function and supply this value as one of the required arguments.

See Also

»EndDoc«, »GetJob«, »SetJob«


  StartDocPrinter

DWORD StartDocPrinter(hPrinter, dwLevel, lpbDocInfo)
HANDLE  hPrinter;   /* handle of printer object */
DWORD  dwLevel;   /* structure level */
LPBYTE  lpbDocInfo;   /* address of structure */

The StartDocPrinter function informs the print spooler that a document is to be spooled for printing.

Parameters

hPrinter

Identifies the printer.

dwLevel

Specifies the version of the structure to which lpbDocInfo points. This value must be 1.

lpbDocInfo

Points to a DOC_INFO_1 structure. The DOC_INFO_1 structure has the following form:

typedef struct _DOC_INFO_1 { /* dci1 */

    LPTSTR pDocName;

    LPTSTR pOutputFile;

    LPTSTR pDatatype;

} DOC_INFO_1;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value identifies the print job; otherwise, it is zero. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter is obtained by calling the OpenPrinter function.

The return value will never be greater than ((231) − 1).

See Also

»OpenPrinter«


  StartPage

int StartPage(hDC)
HDC  hDC;   /* handle of device context */

The StartPage function prepares the printer driver to accept data.

Parameters

hDC

Identifies the device context for the print job.

Return Value

If the function succeeds, the return value is greater than zero.

If the function fails, the return value is SP_ERROR. To get extended error information, use the GetLastError function.

Comments

The system disables the ResetDC function between calls to the StartPage and EndPage functions. This means that an application cannot change the device mode except at page boundaries.

See Also

»EndPage«, »ResetDC«


  StartPagePrinter

BOOL StartPagePrinter(hPrinter)
HANDLE  hPrinter;   /* handle of printer object */

The StartPagePrinter function informs the spooler that a page is about to be printed on the given printer.

Parameters

hPrinter

Identifies a printer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The printer handle hPrinter is obtained by calling the OpenPrinter function.

When an application has finished writing a page, it should call the EndPagePrinter function to inform the spooler that the page is complete.

See Also

»EndPagePrinter«, »OpenPrinter«


  StartService

BOOL StartService(schService, dwNumServiceArgs, *lpszServiceArgs)
SC_HANDLE  schService;   /* handle of service */
DWORD  dwNumServiceArgs;   /* number of arguments */
LPCTSTR  *lpszServiceArgs;   /* address of array of argument string pointers */

The StartService function starts the execution of a service.

Parameters

schService

Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_START access.

dwNumServiceArgs

Specifies the number of argument strings in the lpszServiceArgs array. If lpszServiceArgs is NULL, this parameter can be zero.

lpszServiceArgs

Points to an array of pointers that point to null-terminated argument strings passed to a Win32 service. Driver services do not receive these arguments. If no arguments are passed to the service being started, this parameter can be NULL. The new service accesses these arguments through its ServiceMain function. Note that in the array of arguments passed to the ServiceMain function, the first argument (argv[0]) is the name of the service by default, followed by the arguments, if any, in the lpszServiceArgs array.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_ACCESS_DENIED
	The specified handle was not opened with SERVICE_START access.
ERROR_INVALID_HANDLE
	The specified handle is invalid.
ERROR_PATH_NOT_FOUND
	The service binary file could not be found.
ERROR_SERVICE_ALREADY_RUNNING
	An instance of the service is already running.
ERROR_SERVICE_DATABASE_LOCKED
	The database is locked.
ERROR_SERVICE_DEPENDENCY_DELETED
	The service depends on a service that does not exist or has been marked for deletion.
ERROR_SERVICE_DEPENDENCY_FAIL
	The service depends on another service that has failed to start.
ERROR_SERVICE_DISABLED
	The service has been disabled.
ERROR_SERVICE_LOGON_FAILED
	The service could not be logged on.
ERROR_SERVICE_MARKED_FOR_DELETE
	The service has been marked for deletion.
ERROR_SERVICE_NO_THREAD
	A thread could not be created for the Win32 service.
ERROR_SERVICE_REQUEST_TIMEOUT
	The service did not respond to the start request in a timely fashion.
Comments

When a driver service is started, the StartService function does not return until the device driver is done initializing.

When a Win32 service is started, the service control manager spawns the service process, if necessary. If the specified service shares a process with other services, the required process may already exist. The StartService function does not wait for the first status update from the new service (which may take a while). Instead, it returns when the service control manager receives notification from the service control dispatcher that the ServiceMain thread for this service was created successfully.

For a Win32 service, the service control manager sets the following default status values before returning from StartService:

•	Current state of the service is set to SERVICE_START_PENDING.

•	Controls accepted is set to none (zero).

•	The CheckPoint value is set to zero.

•	The WaitHint time is set to 2 seconds.

The calling process can determine if the new service has finished its initialization by calling the QueryServiceStatus function periodically to query the service's status.

This function cannot be called from within a service.

See Also

»ControlService«, »CreateService«, »OpenService«, »QueryServiceStatus«


  StartServiceCtrlDispatcher

BOOL StartServiceCtrlDispatcher(lpsteServiceTable)
LPSERVICE_TABLE_ENTRY  lpsteServiceTable;   /* address of service table */

The StartServiceCtrlDispatcher function connects the main thread of a service process to the service control manager, which causes the thread to be the service control dispatcher thread for the calling process.

Parameters

lpsteServiceTable

Points to an array of SERVICE_TABLE_ENTRY structures containing one entry for each service that can execute in the calling process. The members of the last entry in the table must have NULL values to designate the end of the table. The SERVICE_TABLE_ENTRY structure has the following form:

typedef struct _SERVICE_TABLE_ENTRY { /* ste */

    LPTSTR lpServiceName;

    LPSERVICE_MAIN_FUNCTION lpServiceProc;

} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_INVALID_DATA	The specified dispatch table contains entries that are not in the proper format.
Comments

When the service control manager starts a service process, it waits for the process to call the StartServiceCtrlDispatcher function. The main thread of a service process should make this call as soon as possible after it starts up. If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager and does not return until all running services in the process have terminated. The service control manager uses this connection to send control and service start requests to the main thread of the service process. The main thread acts as a dispatcher by invoking the appropriate Handler function to handle control requests or by creating a new thread to execute the appropriate ServiceMain function when a new service is started.

The lpsteServiceTable parameter contains an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored.

If a service runs in its own process, the main thread of the service process should immediately call StartServiceCtrlDispatcher. All initialization tasks are done in the service's ServiceMain function when the service is started.

If multiple services share a process and some common process-wide initialization needs to be done before any ServiceMain function is called, the main thread can do the work before calling StartServiceCtrlDispatcher, as long as it takes less than 30 seconds. Otherwise, another thread must be created to do the process-wide initialization, while the main thread calls StartServiceCtrlDispatcher and becomes the service control dispatcher. Any service specific initialization should still be done in the individual service main functions.

See Also

»ControlService«, »RegisterServiceCtrlHandler«, »ServiceMain«


  StartSound

The StartSound function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  StopSound

The StopSound function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  StretchBlt

BOOL StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop)
HDC  hdcDest;   /* handle of destination device context */
int  nXOriginDest;   /* x-coordinate of upper left corner of dest. rect. */
int  nYOriginDest;   /* y-coordinate of upper left corner of dest. rect. */
int  nWidthDest;   /* width of destination rectangle */
int  nHeightDest;   /* height of destination rectangle */
HDC  hdcSrc;   /* handle of source device context */
int  nXOriginSrc;   /* x-coordinate of upper left corner of source rectangle */
int  nYOriginSrc;   /* y-coordinate of upper left corner of source rectangle */
int  nWidthSrc;   /* width of source rectangle */
int  nHeightSrc;   /* height of source rectangle */
DWORD  dwRop;   /* raster operation code */

The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary. Windows stretches or compresses the bitmap according to the stretching mode currently set in the destination device context.

Parameters

hdcDest

Identifies the destination device context.

nXOriginDest

Specifies the x-coordinate, in logical units, of the upper left corner of the destination rectangle.

nYOriginDest

Specifies the y-coordinate, in logical units, of the upper left corner of the destination rectangle.

nWidthDest

Specifies the width, in logical units, of the destination rectangle.

nHeightDest

Specifies the height, in logical units, of the destination rectangle.

hdcSrc

Identifies the source device context.

nXOriginSrc

Specifies the x-coordinate, in logical units, of the upper left corner of the source rectangle.

nYOriginSrc

Specifies the y-coordinate, in logical units, of the upper left corner of the source rectangle.

nWidthSrc

Specifies the width, in logical units, of the source rectangle.

nHeightSrc

Specifies the height, in logical units, of the source rectangle.

dwRop

Specifies the raster operation to be performed. Raster operation codes define how Windows combines colors in output operations that involve a brush, a source bitmap, and a destination bitmap.

See the »BitBlt« function for a list of common raster operation codes.

For further information on raster operations, and complete lists of all the raster operation codes, see Appendix F, "Raster Operation Codes."

Return Value

If the function was successful, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

StretchBlt stretches or compresses the source bitmap in memory and then copies the result to the destination rectangle. The color data for pattern or destination pixels is merged after the stretching or compression occurs.

When an enhanced metafile is being recorded, an error occurs (and the function returns FALSE) if the source device context identifies an enhanced-metafile device context.

If the specified raster operation requires a brush, Windows uses the brush currently selected into the destination device context.

The destination coordinates are transformed by using the transformation currently specified for the destination device context; the source coordinates are transformed by using the transformation currently specified for the source device context.

If the source transformation has a rotation or shear, an error occurs.

If destination, source, and pattern bitmaps do not have the same color format, StretchBlt converts the source and pattern bitmaps to match the destination bitmap.

If StretchBlt must convert a monochrome bitmap to a color bitmap, it sets white bits (1) to the background color and black bits (0) to the foreground color. To convert a color bitmap to a monochrome bitmap, it sets pixels that match the background color to white (1) and sets all other pixels to black (0). The foreground and background colors of the device context with color are used.

StretchBlt creates a mirror image of a bitmap if the signs of the nWidthSrc and nWidthDest parameters or of the nHeightSrc and nHeightDest parameters differ. If nWidthSrc and nWidthDest have different signs, the function creates a mirror image of the bitmap along the x-axis. If nHeightSrc and nHeightDest have different signs, the function creates a mirror image of the bitmap along the y-axis.

Not all devices support the StretchBlt function. For more information, see the description of the »GetDeviceCaps« function.

See Also

»BitBlt«, »GetDeviceCaps«, »MaskBlt«, »PlgBlt«, »SetStretchBltMode«


  StretchDIBits

int StretchDIBits(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth,
nSrcHeight, lpBits, lpBitsInfo, iUsage, dwRop)
HDC  hdc;   /* handle of device context */
int  XDest;   /* x-coordinate of upper left corner of dest. rect. */
int  YDest;   /* y-coordinate of upper left corner of dest. rect. */
int  nDestWidth;   /* width of destination rectangle */
int  nDestHeight;   /* height of destination rectangle */
int  XSrc;   /* x-coordinate of upper left corner of source rect. */
int  YSrc;   /* y-coordinate of upper left corner of source rect. */
int  nSrcWidth;   /* width of source rectangle */
int  nSrcHeight;   /* height of source rectangle */
CONST VOID  *lpBits;   /* address of bitmap bits */
LPBITMAPINFO  lpBitsInfo;   /* address of bitmap data */
UINT  iUsage;   /* usage */
DWORD  dwRop;   /* raster operation code */

The StretchDIBits function copies the color data for a rectangle of pixels in a device-independent bitmap (DIB) to the given destination rectangle. If the destination rectangle is larger than the source rectangle, this function stretches the rows and columns of color data to fit the destination rectangle. If the destination rectangle is smaller than the source rectangle, this function compresses the rows and columns by using the specified raster operation.

Parameters

hdc

Identifies the destination device context.

XDest

Specifies the x-coordinate, in logical units, of the upper left corner of the destination rectangle.

YDest

Specifies the y-coordinate, in logical units, of the upper left corner of the destination rectangle.

nDestWidth

Specifies the width, in logical units, of the destination rectangle.

nDestHeight

Specifies the height, in logical units, of the destination rectangle.

XSrc

Specifies the x-coordinate, in pixels, of the source rectangle in the DIB.

YSrc

Specifies the y-coordinate, in pixels, of the source rectangle in the DIB.

nSrcWidth

Specifies the width, in pixels, of the source rectangle in the DIB.

nSrcHeight

Specifies the height, in pixels, of the source rectangle in the DIB.

lpBits

Points to the DIB bits, which are stored as an array of bytes.

lpBitsInfo

Points to a BITMAPINFO structure that contains information about the DIB. The BITMAPINFO structure has the following form:

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

iUsage

Specifies whether the bmiColors member of the BITMAPINFO structure was provided and, if so, whether bmiColors contains explicit red, green, blue (RGB) values or indices. The iUsage parameter must be one of the following values:

Value	Description
DIB_PAL_COLORS	The array contains 16-bit indices into the logical palette of the source device context.
DIB_RGB_COLORS	The color table contains literal RGB values.
DIB_PAL_INDICES	There is no color table for the bitmap. The DIB itself contains indices into the system palette. No color translation occurs.
dwRop

Specifies how the source pixels, the destination device context's current brush, and the destination pixels are to be combined to form the new image.

Return Value

If the function succeeds, the return value is the number of scan lines copied; otherwise, it is GDI_ERROR. To get extended error information, use the GetLastError function.

Comments

The origin of a DIB is the lower-left corner.

StretchDIBits creates a mirror image of a bitmap if the signs of the nSrcWidth and nDestWidth parameters, or of the nSrcHeight and nDestHeight parameters differ. If nSrcWidth and nDestWidth have different signs, the function creates a mirror image of the bitmap along the x-axis. If nSrcHeight and nDestHeight have different signs, the function creates a mirror image of the bitmap along the y-axis.

See Also

»SetMapMode«, »SetStretchBltMode«


  StrokeAndFillPath

BOOL StrokeAndFillPath(hdc)
HDC  hdc;   /* handle of device context */

The StrokeAndFillPath function closes any open figures in a path, strokes the outline of the path by using the current pen, and fills its interior by using the current brush.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get the error value, which may be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

Comments

The device context identified by the hdc parameter must contain a closed path.

The StrokeAndFillPath function has the same effect as closing all the open figures in the path, and stroking and filling the path separately, except that the filled region will not overlap the stroked region even if the pen is wide.

See Also

»BeginPath«, »FillPath«, »SetPolyFillMode« »StrokePath«,


  StrokePath

BOOL StrokePath(hdc)
HDC  hdc;   /* handle of device context */

The StrokePath function renders the specified path by using the current pen.

Parameters

hdc

Identifies a device context that contains a closed path.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get the error value, which may be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

Comments

The device context identified by the hdc parameter must contain a closed path.

See Also

»BeginPath«, »EndPath« »ExtCreatePen«,


  SuspendThread

DWORD SuspendThread(hThread)
HANDLE  hThread;   /* handle to the thread */

The SuspendThread function suspends the given thread.

Parameters

hThread

Identifies the thread. The handle must have THREAD_SUSPEND_RESUME access.

Return Value

If the function succeeds, the return value is the thread's previous suspend count; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

Comments

If the function is succeeds, execution of the specified thread is suspended and the thread's suspend count is incremented.

Suspending a thread causes the thread to stop executing user-mode (application) code.

Each thread has a suspend count (with a maximum value of MAXIMUM_SUSPEND_COUNT). If the suspend count is greater than zero, the thread is suspended; otherwise, the thread is not suspended and is eligible for execution. Calling SuspendThread causes the target thread's suspend count to be incremented. Attempting to increment past the maximum suspend count causes an error without incrementing the count.

The ResumeThread function decrements the suspend count of a suspended thread.

See Also

»ResumeThread«


  SwapMouseButton

BOOL SwapMouseButton(fSwap)
BOOL  fSwap;   /* reverse or restore buttons */

The SwapMouseButton function reverses or restores the meaning of the left and right mouse buttons.

Parameters

fSwap

Specifies whether the mouse button meanings are reversed or restored. If this parameter is TRUE, the left button generates right-button messages and the right button generates left-button messages. If this parameter is FALSE, the buttons are restored to their original meanings.

Return Value

If the meaning of the mouse buttons was reversed previously, before the function was called, the return value is TRUE; otherwise, it is FALSE.

Comments

Button swapping is provided as a convenience to people who use the mouse with their left hands. The SwapMouseButton function is usually called by Control Panel only. Although an application is free to call the function, the mouse is a shared resource and reversing the meaning of its buttons affects all applications.


  SwitchStackBack

The SwitchStackBack function has been deleted.


  SwitchStackTo

The SwitchStackTo function has been deleted.


  SyncAllVoices

The SyncAllVoices function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  SysMsgProc

LRESULT CALLBACK SysMsgProc(nCode, wParam, lParam)
int  nCode;   /* message flag */
WPARAM  wParam;   /* undefined */
LPARAM  lParam;   /* address of structure with message data */

The SysMsgProc hook procedure is a library-defined callback function the system calls after an input event occurs in a dialog box, message box, menu, or scroll bar, but before the message generated by the input event is processed. The hook procedure can monitor messages for any dialog box, message box, menu, or scroll bar in the system.

Parameters

nCode

Specifies the type of input event that generated the message. This parameter can be one of the following values:

Value	Meaning
MSGF_DIALOGBOX	The input event occurred in a message box or dialog box.
MSGF_MENU	The input event occurred in a menu.
MSGF_SCROLLBAR	The input event occurred in a scroll bar.
MSGF_NEXTWINDOW	The input event occurred as a result of the user's pressing the ALT+TAB key combination to activate a different window.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam

Specifies a NULL value.

lParam

Points to an MSG message structure. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the hook procedure processes the message, the return value must be a nonzero value. Otherwise, it must be zero.

Comments

An application installs the hook procedure by specifying the WH_SYSMSGFILTER hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

SysMsgProc is a placeholder for the library-defined function name.

See Also

»CallNextHookEx«, »SetWindowsHookEx«


  SystemParametersInfo

BOOL SystemParametersInfo(wAction, wParam, lpvParam, fUpdateProfile)
UINT  wAction;   /* system parameter to query or set */
UINT  wParam;   /* depends on action to be taken */
PVOID  lpvParam;   /* depends on action to be taken  */
UINT  fUpdateProfile;   /* user profile update flag */

The SystemParametersInfo function queries or sets system-wide parameters. This function can also update the user profile while setting a parameter.

Parameters

wAction

Specifies the system-wide parameter to query or set. This parameter can be one of the following values:

Value	Action
SPI_GETBEEP	Retrieves a BOOL value that indicates whether the warning beeper is on or off.
SPI_GETBORDER	Retrieves the border multiplier factor that determines the width of a window's sizing border.
SPI_GETFASTTASKSWITCH	Determines whether fast task switching is on or off.
SPI_GETGRIDGRANULARITY	Retrieves the current granularity value of the desktop sizing grid.
SPI_GETICONTITLELOGFONT	Retrieves the logical font information for the current icon-title font.
SPI_GETICONTITLEWRAP	Determines whether icon-title wrapping is on or off.
SPI_GETKEYBOARDDELAY	Retrieves the keyboard repeat-delay setting.
SPI_GETKEYBOARDSPEED	Retrieves the keyboard repeat-speed setting.
SPI_GETMENUDROPALIGNMENT	Determines whether pop-up menus are left aligned or right aligned relative to the corresponding menu-bar item.
SPI_GETMOUSE	Retrieves the mouse speed and the x and y mouse threshold values.
SPI_GETSCREENSAVEACTIVE	Retrieves a BOOL value that indicates whether screen saving is on or off.
SPI_GETSCREENSAVETIMEOUT	Retrieves the screen saver time-out value.
SPI_ICONHORIZONTALSPACING	Sets the width, in pixels, of an icon cell.
SPI_ICONVERTICALSPACING	Sets the height, in pixels, of an icon cell.
SPI_LANGDRIVER	Identifies the language driver.
SPI_SETBEEP	Turns the warning beeper on or off.
SPI_SETBORDER	Sets the border multiplier factor that determines the width of a window's sizing border.
SPI_SETDESKPATTERN	Sets the current desktop pattern by causing the Windows USER.EXE program to read the Pattern= parameter from the WIN.INI file.
SPI_SETDESKWALLPAPER	Specifies the filename that contains the bitmap to be used as the desktop wallpaper.
SPI_SETDOUBLECLICKTIME	Sets the double-click time for the mouse. The double-click time is the maximum number of milliseconds that can occur between the first and second clicks of a double-click.
SPI_SETDOUBLECLKHEIGHT	Sets the height of the rectangle within which the second click of a double-click must fall for it to be registered as a double-click.
SPI_SETDOUBLECLKWIDTH	Sets the width of the rectangle within which the second click of a double-click must fall for it to be registered as a double-click.
SPI_SETFASTTASKSWITCH	Turns fast task switching on or off.
SPI_SETGRIDGRANULARITY	Sets the granularity of the desktop sizing grid.
SPI_SETICONTITLELOGFONT	Sets the font that is used for icon titles.
SPI_SETICONTITLEWRAP	Turns icon-title wrapping on or off.
SPI_SETKEYBOARDDELAY	Sets the keyboard repeat-delay setting.
SPI_SETKEYBOARDSPEED	Sets the keyboard repeat-speed setting.
SPI_SETMENUDROPALIGNMENT	Sets the alignment value of pop-up menus.
SPI_SETMOUSE	Sets the mouse speed and the x and y mouse threshold values.
SPI_SETMOUSEBUTTONSWAP	Swaps or restores the meaning of the left and right mouse buttons.
SPI_SETSCREENSAVEACTIVE	Sets the state of the screen saver.
SPI_SETSCREENSAVETIMEOUT	Sets the screen saver time-out value.
wParam

Depends on the wAction parameter. See the Comments section for details.

lpvParam

Depends on the wAction parameter. See the Comments section for details.

fUpdateProfile

If a system parameter is being set, specifies whether the user profile is to be updated, and if so, whether the WM_WININICHANGE message is to be broadcast to all top-level windows to notify them of the change. This parameter can be one of the following values:

Value	Action
SPIF_UPDATEINIFILE	Writes the new system-wide parameter setting to the user profile.
SPIF_SENDWININICHANGE	Broadcasts the WM_WININICHANGE message after updating the user profile.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

This function is intended for use with applications such as Control Panel that allow the user to customize the Windows environment.

The following table describes the wParam and lpvParam parameters for each SPI_ constant:

Constant	wParam	lpvParam
SPI_GETBEEP	0	Points to a BOOL variable that receives TRUE if the beeper is on, FALSE if it is off.
SPI_GETBORDER	0	Points to an integer variable that receives the border multiplier factor.
SPI_GETFASTTASKSWITCH	0	Points to a BOOL variable that receives TRUE if fast task switching is on, FALSE if it is off.
SPI_GETGRIDGRANULARITY	0	Points to an integer variable that receives the grid-granularity value.
SPI_GETICONTITLELOGFONT	Specifies the size of a LOGFONT structure.	Points to a LOGFONT structure that receives the logical font information.
SPI_GETICONTITLEWRAP	0	Points to a BOOL variable that receives TRUE if wrapping is on, FALSE if wrapping is off.
SPI_GETKEYBOARDDELAY	0	Points to an integer variable that receives the keyboard repeat-delay setting.
SPI_GETKEYBOARDSPEED	0	Points to a WORD variable that receives the current keyboard repeat-speed setting.
SPI_GETMENUDROPALIGNMENT	0	Points to a BOOL variable that receives TRUE if pop-up menus are right aligned, FALSE if they are left aligned.
SPI_GETMOUSE	0	Points to an integer array where lpiMouse[0] receives MouseThreshold1, lpiMouse[1] receives MouseThreshold2, and lpiMouse[2] receives MouseSpeed.
SPI_GETSCREENSAVEACTIVE	0	Points to a BOOL variable that receives TRUE if the screen saver is active, FALSE if it is not.
SPI_GETSCREENSAVETIMEOUT	0	Points to an integer variable that receives the screen saver time-out value, in milliseconds.
SPI_ICONHORIZONTALSPACING	Specifies the icon cell width.	NULL
SPI_ICONVERTICALSPACING	Specifies the icon cell height.	NULL
SPI_LANGDRIVER	0	Points to a string containing the new language driver filename.
SPI_SETBEEP	Specifies TRUE to turn the beeper on, FALSE to turn the beeper off.	NULL
SPI_SETBORDER	Specifies the border multiplier factor.	NULL
SPI_SETDESKPATTERN	0	NULL
SPI_SETDESKWALLPAPER	0	Points to a string that specifies the name of the bitmap file.
SPI_SETDOUBLECLICKTIME	Specifies the double-click time, in milliseconds.	NULL
SPI_SETDOUBLECLKHEIGHT	Specifies the double-click height, in pixels.	NULL
SPI_SETDOUBLECLKWIDTH	Specifies the double-click width, in pixels.	NULL
SPI_SETFASTTASKSWITCH	Specifies TRUE to turn fast task switching on, FALSE to turn it off.	NULL
SPI_SETGRIDGRANULARITY	Specifies the grid granularity.
SPI_SETICONTITLELOGFONT	Specifies the size of a LOGFONT structure.	Points to a LOGFONT structure that contains the logical font information to set.
SPI_SETICONTITLEWRAP	Specifies TRUE to turn wrapping on, FALSE to turn wrapping off.	NULL
SPI_SETKEYBOARDDELAY	Specifies the keyboard-delay setting.	NULL
SPI_SETKEYBOARDSPEED	Specifies the repeat-speed setting.	NULL
SPI_SETMENUDROPALIGNMENT	Specifies TRUE to use right alignment, FALSE to use left alignment.	NULL
SPI_SETMOUSE	0	Points to an integer array where lpiMouse[0] receives xMouseThreshold, lpiMouse[1] receives yMouseThreshold, and lpiMouse[2] receives MouseSpeed.
SPI_SETMOUSEBUTTONSWAP	Specifies TRUE to reverse the meaning of the left and right mouse buttons, FALSE to restore the buttons to their original meanings.	NULL
SPI_SETSCREENSAVEACTIVE	Specifies TRUE to activate screen saving, FALSE to deactivate screen saving.	NULL
SPI_SETSCREENSAVETIMEOUT	Specifies the idle time-out duration, in seconds, before the screen is saved.	NULL


  SystemTimeToFileTime

BOOL SystemTimeToFileTime(lpst, lpft)
LPSYSTEMTIME  lpst;   /* address of system time to convert  */
LPFILETIME  lpft;   /* address of buffer for converted file time */

The SystemTimeToFileTime function converts a system time to a file time.

Parameters

lpst

Points to a SYSTEMTIME structure that contains the time to be converted. The SYSTEMTIME structure has the following form:

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The wDayOfWeek member of the SYSTEMTIME structure is ignored.

lpft

Points to a FILETIME structure to receive the converted system time. The FILETIME structure has the following form:

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»DosDateTimeToFileTime«, »FileTimeToDosDateTime«, »FileTimeToSystemTime«


  TabbedTextOut

LONG TabbedTextOut(hdc, x, y, lpString, nCount, nTabPositions, lpnTabStopPositions,
nTabOrigin)
HDC  hdc;   /* handle of device context */
int  x;   /* x-coordinate of starting position */
int  y;   /* y-coordinate of starting position */
LPCTSTR  lpString;   /* address of string */
int  nCount;   /* number of characters in string */
int  nTabPositions;   /* number of tabs in array */
LPINT  lpnTabStopPositions;   /* address of array for tab positions  */
int  nTabOrigin;   /* x-coordinate for tab expansion */

The TabbedTextOut function writes a character string at a specified location, expanding tabs to the values specified in an array of tab-stop positions. Text is written in the currently selected font.

Parameters

hdc

Identifies the device context.

x

Specifies the x-coordinate of the starting point of the string, in logical units.

y

Specifies the y-coordinate of the starting point of the string, in logical units.

lpString

Points to the character string to draw.

nCount

Specifies the number of characters in the string.

nTabPositions

Specifies the number of values in the array of tab-stop positions.

lpnTabStopPositions

Points to an array containing the tab-stop positions, in device units. The tab stops must be sorted in increasing order; the smallest x-value should be the first item in the array.

nTabOrigin

Specifies the x-coordinate of the starting position from which tabs are expanded, in logical units.

Return Value

If the function succeeds, the return value is the dimensions, in logical units, of the string. The height is in the high-order word and the width is in the low-order word.

Comments

If the nTabPositions parameter is zero and the lpnTabStopPositions parameter is NULL, tabs are expanded to eight times the average character width.

If nTabPositions is 1, the tab stops are separated by the distance specified by the first value in the lpnTabStopPositions array.

If the lpnTabStopPositions array contains more than one value, a tab stop is set for each value in the array, up to the number specified by nTabPositions.

The nTabOrigin parameter allows an application to call the TabbedTextOut function several times for a single line. If the application calls TabbedTextOut more than once with the nTabOrigin set to the same value each time, the function expands all tabs relative to the position specified by nTabOrigin.

By default, the current position is not used or updated by the TabbedTextOut function. If an application needs to update the current position when it calls TabbedTextOut, the application can call the SetTextAlign function with the wFlags parameter set to TA_UPDATECP. When this flag is set, Windows ignores the x and y parameters on subsequent calls to the TabbedTextOut function, using the current position instead.

See Also

»DrawText«, »GetTabbedTextExtent«, »GrayString«, »SetTextAlign«, »TextOut«


  TerminateProcess

BOOL TerminateProcess(hProcess, uExitCode)
HANDLE  hProcess;   /* handle to the process */
UINT  uExitCode;   /* exit code for the process */

The TerminateProcess function terminates the given process and all of its threads.

Parameters

hProcess

Identifies the process to terminate. The handle must have PROCESS_TERMINATE access.

uExitCode

Specifies the exit code for the process and for all threads terminated as a result of this call. Use the GetExitCodeProcess function to retrieve the process's exit code. Use the GetExitCodeThread function to retrieve a thread's exit code.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The TerminateProcess function is used to unconditionally cause a process to exit. Use it only in extreme circumstances. The state of global data maintained by DLLs may be compromised if TerminateProcess is used rather that ExitProcess.

TerminateProcess causes all threads within a process to terminate, and causes a process to exit, but DLLs attached to the process are not notified that the process is terminating.

Terminating a process causes the following:

1.	All of the object handles opened by the process are closed.

2.	All of the threads in the process terminate their execution.

3.	The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.

4.	The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.

5.	The termination status of the process changes from STILL_ACTIVE to the exit code of the process.

Terminating a process does not cause child processes to be terminated.

Terminating a process does not necessarily remove the process object from the system. A process object is deleted when the last handle to the process is closed.

See Also

»ExitProcess«, »OpenProcess«


  TerminateThread

BOOL TerminateThread(hThread, dwExitCode)
HANDLE  hThread;   /* handle to the thread */
DWORD  dwExitCode;   /* exit code for the thread */

The TerminateThread function terminates a thread.

Parameters

hThread

Identifies the thread to terminate. The handle must have THREAD_TERMINATE access.

dwExitCode

Specifies the exit code for the thread. Use the GetExitCodeThread function to retrieve a thread's exit code.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.

If the target thread is the last thread of a process when this function is called, the thread's process is also terminated.

The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.

Terminating a thread does not necessarily remove the thread object from the system. A thread object is deleted when the last thread handle is closed.

See Also

»ExitThread«


  TextOut

BOOL TextOut(hdc, nXStart, nYStart, lpszString, cbString)
HDC  hdc;   /* handle of device context */
int  nXStart;   /* x-coordinate of starting position */
int  nYStart;   /* y-coordinate of starting position */
LPCTSTR  lpszString;   /* address of string */
int  cbString;   /* number of characters in string */

The TextOut function writes a character string at the specified location, using the currently selected font.

Parameters

hdc

Identifies the device context.

nXStart

Specifies the logical x-coordinate of the reference point that Windows uses to align the string.

nYStart

Specifies the logical y-coordinate of the reference point that Windows uses to align the string.

lpszString

Points to the string to be drawn.

cbString

Specifies the number of characters in the string.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The interpretation of the reference point depends on the current text-alignment mode. An application can retrieve this mode by calling the GetTextAlign function; an application can alter this mode by calling the SetTextAlign function.

By default, the current position is not used or updated by this function. However, an application can call the SetTextAlign function with the fMode parameter set to TA_UPDATECP to permit Windows to use and update the current position each time the application calls TextOut for a given device context. When this flag is set, Windows ignores the nXStart and nYStart parameters on subsequent TextOut calls.

When the TextOut function is placed inside a path bracket, the system generates a path for the TrueType text that includes each character plus its character box. Thus, the region generated by this path is the area enclosed by the character box and the outline of the TrueType text. That is, the region generated is the character box minus the text, rather than the text itself. This is not intuitive. However, you can obtain the region enclosed by the outline of the TrueType text by setting the background mode to transparent before placing the TextOut function in the path bracket. Here is some sample code that shows the non-intuitive situation and the commented-out fix to that situation :

// obtain the window's client rectangle

GetClientRect(hwnd, &r);

// THE FIX: by setting the background mode

// to transparent, the region is the text itself

// SetBkMode(hdc, TRANSPARENT);

// bracket begin a path

BeginPath(hdc);

// send some text on out into the world

TextOut(hdc, r.left, r.top, "Windows NT Rules Well & Wisely", 4);

// bracket end a path

EndPath(hdc);

// derive a region from that path

SelectClipPath(hdc, RGN_AND);

// this generates the same result as SelectClipPath()

// SelectClipRgn(hdc, PathToRegion(hdc));

// okay, fill the region with grayness

FillRect(hdc, &r, GetStockObject(GRAY_BRUSH));

See Also

»GetTextAlign«, »SetTextAlign«, »TabbedTextOut«


  Throw

The Throw function has been deleted.

Structured exception handling is built into the Win32 application programming interface. For more information about structured exception handling, see Chapter 64, "Structured Exception Handling."


  timeBeginPeriod

MMRESULT timeBeginPeriod(cMilliseconds)
UINT  cMilliseconds;   /* new minimum timer period in milliseconds */

The timeBeginPeriod function sets the minimum (lowest number of milliseconds) timer resolution that an application or driver will use. Call this function immediately before starting to use timer-event services, and call the timeEndPeriod function immediately after finishing with the timer-event services.

Parameters

cMilliseconds

Specifies the minimum timer-event resolution, in milliseconds, that the application or driver will use.

Return Value

If the function succeeds, the return value is zero. If the resolution value specified in the cMilliseconds parameter is out of range, the return value is TIMERR_NOCANDO.

Comments

For each call to the timeBeginPeriod function, you must call the timeEndPeriod function with a matching cMilliseconds value. An application or driver can make multiple calls to timeBeginPeriod, as long as each timeBeginPeriod call is matched with a timeEndPeriod call.

See Also

»timeEndPeriod«, »timeSetEvent«


  timeEndPeriod

MMRESULT timeEndPeriod(cMilliseconds)
UINT  cMilliseconds;   /* old timer period in milliseconds */

The timeEndPeriod function clears a previously set minimum (lowest number of milliseconds) timer resolution that an application or driver will use. Call this function immediately after using timer event services.

Parameters

cMilliseconds

Specifies the minimum timer-event resolution value specified in the previous call to the timeBeginPeriod function.

Return Value

If the function succeeds, the return value is zero. If the resolution value specified in the cMilliseconds parameter is out of range, the return value is TIMERR_NOCANDO.

Comments

For each call to the timeBeginPeriod function, you must call the timeEndPeriod function with a matching cMilliseconds value. An application or driver can make multiple calls to timeBeginPeriod, as long as each timeBeginPeriod call is matched with a timeEndPeriod call.

See Also

»timeBeginPeriod«, »timeSetEvent«


  timeGetDevCaps

MMRESULT timeGetDevCaps(lptc, cbtc)
LPTIMECAPS  lptc;   /* address of structure for returned capabilities  */
UINT  cbtc;   /* size of structure in bytes */

The timeGetDevCaps function queries the timer device to determine its capabilities.

Parameters

lptc

Points to a TIMECAPS structure that receives information about the capabilities of the timer device. The TIMECAPS structure has the following form:

typedef struct timecaps_tag {

    UINT  wPeriodMin;

    UINT  wPeriodMax;

} TIMECAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbtc

Specifies the size, in bytes, of the TIMECAPS structure.

Return Value

If the function succeeds, the return value is zero. If the function fails to return the timer device capabilities, the return value is TIMERR_NOCANDO.


  timeGetSystemTime

MMRESULT timeGetSystemTime(lpmmt, cbmmt)
LPMMTIME  lpmmt;   /* address of structure for returned time  */
UINT  cbmmt;   /* size of structure in bytes */

The timeGetSystemTime function retrieves the number of milliseconds elapsed since Windows was started.

Parameters

lpmmt

Points to an MMTIME structure that receives the time. The MMTIME structure has the following form:

typedef struct mmtime_tag {

    WORD  wType;

    union {

        DWORD  ms;

        DWORD  sample;

        DWORD  cb;

        struct {

            BYTE  hour;

            BYTE  min;

            BYTE  sec;

            BYTE  frame;

            BYTE  fps;

            BYTE  dummy;

        } smpte;

        struct {

            DWORD  songptrpos;

        } midi;

    } u;

} MMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmmt

Specifies the size, in bytes, of the MMTIME structure.

Return Value

The return value is zero, and the ms member of the MMTIME structure contains the number of milliseconds elapsed since Windows was started.

Comments

The only difference between this function and the timeGetTime function is that this function uses the standard multimedia time structure MMTIME to return time. The timeGetTime function has less overhead than timeGetSystemTime.

See Also

»timeGetTime«


  timeGetTime

DWORD timeGetTime(VOID)

The timeGetTime function returns the number of milliseconds elapsed since Windows was started.

Return Value

The return value is the number of milliseconds elapsed since Windows was started.

Comments

The only difference between this function and the timeGetSystemTime function is that timeGetSystemTime uses the standard multimedia time structure MMTIME to return time. The timeGetTime function has less overhead than timeGetSystemTime.

See Also

»timeGetSystemTime«


  timeKillEvent

MMRESULT timeKillEvent(IDEvent)
UINT  IDEvent;   /* identifies event to be destroyed */

The timeKillEvent function destroys a specified timer callback event.

Parameters

IDEvent

Identifies the event to be destroyed.

Return Value

If the function succeeds, the return value is zero. If the specified timer event does not exist, the return value is TIMERR_NOCANDO.

Comments

The timer-event identifier specified by IDEvent must be an identifier returned by timeSetEvent.

See Also

»timeSetEvent«


  TimeProc

void CALLBACK TimeProc(IDEvent, uReserved, dwUser, dwReserved1, dwReserved2)
UINT  IDEvent;   /* identifies timer event */
UINT  uReserved;   /* not used */
DWORD  dwUser;   /* application-defined instance data */
DWORD  dwReserved1;   /* not used */
DWORD  dwReserved2;   /* not used */

The TimeProc function is an application-defined callback function that may be called once or periodically upon the occurence of a timer event, depending upon parameters sent to the timeSetEvent function.

messages.

Parameters

IDEvent

The identifier of the timer event. This is the identifier returned by timeSetEvent.

uReserved

Not used.

dwUser

User instance data supplied to the dwUser parameter of timeSetEvent.

dwReserved1

Not used.

dwReserved2

Not used.

Comments

TimeProc is a placeholder for an application-defined function name.

There are several differences between TimeProc functions under Windows NT and under Windows 3.1 :

•	Under Windows 3.1, a TimeProc function is called at interrupt time. The call to a TimeProc function occurs on a separate thread under Windows NT.

•	Under Windows 3.1, a TimeProc function has to be in a dynamic link library. Under Windows NT, there is no such restriction.

•	Under Windows 3.1, a TimeProc function must be exported in a .DEF file. Under Windows NT, that is not necessary.

If source code must be compatible with Windows 3.1, it should follow the Windows 3.1 rules as noted briefly above and specified more fully in the Windows 3.1 documentation.

One other item should be noted carefully. There is a limited set of APIs that a Windows 3.1 TimeProc function may call. In Win32, that strict limitation has been removed. However, it is strongly recommended that a Windows NT TimeProc function restrain its calls to APIs in the same set, with the addition of the API SetEvent. Here is the Windows NT recommended list:

EnterCriticalSection	PostThreadMessage
LeaveCriticalSection	SetEvent
midiOutLongMsg	timeGetSystemTime
midiOutShortMsg	timeGetTime
OutputDebugStr	timeKillEvent
PostMessage	timeSetEvent
If an application's TimeProc function does stray from this list, it should be careful not to call APIs that take a long time to complete. Calls to such functions may interfere with other uses of the timeXXX APIs because TimeProcs are all called from the same thread within a given Process.

If a Win32 TimeProc shares data with other code, a Critical Section or similar mutual exclusion mechanism should be used to protect the integrity of the data. This Critical Section should not be held when calling timeKillEvent, or a deadlock can occur.

See Also

»timeSetEvent«, »MidiProc«, »WaveProc«


  TimerProc

VOID CALLBACK TimerProc(hwnd, uMsg, idEvent, dwTime)
HWND  hwnd;   /* handle of window for timer messages */
UINT  uMsg;   /* WM_TIMER message */
UINT  idEvent;   /* timer identifier */
DWORD  dwTime;   /* current system time */

The TimerProc function is an application-defined callback function that processes WM_TIMER messages.

Parameters

hwnd

Identifies the window associated with the timer.

uMsg

Specifies the WM_TIMER message.

idEvent

Specifies the timer's identifier.

dwTime

Specifies the system time, in Universal Time Convention (UTC) format.

Return Value

This function does not return a value.

Comments

TimerProc is a placeholder for the application-defined function name.

See Also

»KillTimer«, »SetTimer«


  timeSetEvent

UINT timeSetEvent(wDelay, wResolution, lptc, dwUser, fuCallbackType)
UINT  wDelay;   /* specifies event period */
UINT  wResolution;   /* specifies delay accuracy */
LPTIMECALLBACK  lptc;   /* address of callback function */
DWORD  dwUser;   /* application-defined data */
UINT  fuCallbackType;   /* callback type flags */

The timeSetEvent function sets up a timed callback event. The event can be a one-time event or a periodic event. Once activated, the event calls the specified callback function.

Parameters

wDelay

Specifies the event period in milliseconds. If the delay is less than the minimum period supported by the timer, or greater than the maximum period supported by the timer, the function returns an error.

wResolution

Specifies the accuracy of the delay in milliseconds. The resolution of the timer event increases with smaller wResolution values. To reduce system overhead, use the maximum wResolution value appropriate for your application.

lptc

Points to a callback function that is called once upon expiration of a one-shot event or periodically upon expiration of periodic events. For more information on the callback function, see the description of the »TimeProc« function.

dwUser

Contains user-supplied callback data.

fuCallbackType

Specifies the type of timer event, using one of the following flags:

Value	Meaning
TIME_ONESHOT	Event occurs once, after wPeriod milliseconds.
TIME_PERIODIC	Event occurs every wPeriod milliseconds.
Return Value

If the function succeeds, the return value is an identifier code that identifies the timer event. The ID code is also passed to the callback function. If the timer event was not created, the return value is zero.

Comments

Using this function to generate a high-frequency periodic-delay event (with a period less than 10 milliseconds) can consume a significant portion of the system CPU bandwidth. Any call to timeSetEvent for a periodic-delay timer must be paired with a call to the timeKillEvent function.

See Also

»timeBeginPeriod«, »timeEndPeriod«, »timeKillEvent«


  TlsAlloc

DWORD TlsAlloc(VOID)

The TlsAlloc function allocates a TLS (thread local storage) index. Any thread of the process can subsequently use this index to store and retrieve values that are local to the thread.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is a TLS index; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

Comments

The threads of the process can use the TLS index in subsequent calls to the TlsFree, TlsSetValue, or TlsGetValue functions.

TLS indices are typically allocated during process or DLL initialization. Once allocated, each thread of the process can use a TLS index to access its own TLS storage slot. To store a value in its slot, a thread specifies the index in a call to TlsSetValue. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.

The constant TLS_MINIMUM_AVAILABLE defines the minimum number of TLS indices available in each process. This minimum is guaranteed to be at least 64 for all systems.

TLS indices are not valid across process boundaries. A DLL cannot assume that an index assigned in one process is valid in another process.

A DLL might use TlsAlloc, TlsSetValue, TlsGetValue, and TlsFree as follows:

1.	When a DLL attaches to a process, the DLL uses TlsAlloc to allocate a TLS index. The DLL then allocates some dynamic storage and uses the TLS index in a call to TlsSetValue to store the address in the TLS slot. This concludes the per-thread initialization for the initial thread of the process. The TLS index is stored in a global or static variable of the DLL.

2.	Each time the DLL attaches to a new thread of the process, the DLL allocates some dynamic storage for the new thread and uses the TLS index in a call to TlsSetValue to store the address in the TLS slot. This concludes the per-thread initialization for the new thread.

3.	Each time an initialized thread makes a DLL call requiring the data in its dynamic storage, the DLL uses the TLS index in a call to TlsGetValue to retrieve the address of the dynamic storage for that thread.

See Also

»TlsFree«, »TlsGetValue«, »TlsSetValue«


  TlsFree

BOOL TlsFree(dwTlsIndex)
DWORD  dwTlsIndex;   /* TLS index to free */

The TlsFree function releases a thread local storage (TLS) index, making it available for reuse.

Parameters

dwTlsIndex

Specifies a TLS index that was allocated by the TlsAlloc function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the threads of the process have allocated dynamic storage and used the TLS index to store pointers to this storage, they should free the storage before calling TlsFree. The TlsFree function does not free any dynamic storage that has been associated with the TLS index. It is expected that DLLs call this function (if at all) only during their process detach routine.

For a brief discussion of typical uses of the TLS functions, see the Comments section of »TlsAlloc«.

See Also

»TlsAlloc«, »TlsGetValue«, »TlsSetValue«


  TlsGetValue

LPVOID TlsGetValue(dwTlsIndex)
DWORD  dwTlsIndex;   /* TLS index to retrieve value for */

The TlsGetValue function retrieves the value in the calling thread's thread local storage (TLS) slot for a specified TLS index. Each thread of a process has its own slot for each TLS index.

Parameters

dwTlsIndex

Specifies a TLS index that was allocated by the TlsAlloc function.

Return Value

If the function succeeds, the return value is the value stored in the calling thread's TLS slot associated with the specified index; otherwise, it is zero. To get extended error information, use the GetLastError function.

Note that the data stored in a TLS slot can have a value of zero. In this case, the return value is zero and GetLastError returns NO_ERROR. See the Comments section for some further explanation.

Comments

TLS indexes are typically allocated by the TlsAlloc function during process or DLL initialization. Once allocated, each thread of the process can use a TLS index to access its own TLS storage slot for that index. The storage slot for each thread is initialized to NULL. A thread specifies a TLS index in a call to TlsSetValue, to store a value in its slot. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.

TlsSetValue and TlsGetValue were implemented with speed as the primary goal. These functions perform minimal parameter validation and error checking. In particular, this function succeeds if dwTlsIndex is in the range (0 through TLS_MINIMUM_AVAILABLE − 1). It is up to the programmer to ensure that the index is valid.

Win32 API functions that return indications of failure call SetLastError when they fail. They generally do not call SetLastError when they succeed. The TlsGetValue function is an exception to this general rule. The TlsGetValue function calls SetLastError to clear a thread's last error when it succeeds. That allows checking for the error-free retrieval of NULL values.

See Also

»TlsAlloc«, »TlsSetValue«, »TlsFree«, »SetLastError«, »GetLastError«


  TlsSetValue

BOOL TlsSetValue(dwTlsIndex, lpvTlsValue)
DWORD  dwTlsIndex;   /* TLS index to set value for  */
LPVOID  lpvTlsValue;   /* value to be stored */

The TlsSetValue function stores a value in the calling thread's thread local storage (TLS) slot for a specified TLS index. Each thread of a process has its own slot for each TLS index.

Parameters

dwTlsIndex

Specifies a TLS index that was allocated by the TlsAlloc function.

lpvTlsValue

Specifies the value to be stored in the calling thread's TLS slot specified by dwTlsIndex.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

TLS indexes are typically allocated by the TlsAlloc function during process or DLL initialization. Once allocated, each thread of the process can use a TLS index to access its own TLS storage slot for that index. The storage slot for each thread is initialized to NULL. A thread specifies a TLS index in a call to TlsSetValue, to store a value in its slot. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.

TlsSetValue and TlsGetValue were implemented with speed as the primary goal. These functions perform minimal parameter validation and error checking. In particular, this function succeeds if dwTlsIndex is in the range (0 through TLS_MINIMUM_AVAILABLE − 1). It is up to the programmer to ensure that the index is valid.

See Also

»TlsAlloc«, »TlsGetValue«, »TlsFree«


  ToAscii

int ToAscii(uVirtKey, uScanCode, lpbKeyState, lpwTransKey, fuState)
UINT  uVirtKey;   /* virtual-key code */
UINT  uScanCode;   /* scan code */
PBYTE  lpbKeyState;   /* address of key-state array */
LPWORD  lpwTransKey;   /* buffer for translated key  */
UINT  fuState;   /* active-menu flag */

The ToAscii function translates the specified virtual-key code and keyboard state to the corresponding Windows character or characters.

Parameters

uVirtKey

Specifies the virtual-key code to be translated.

uScanCode

Specifies the hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up.

lpbKeyState

Points to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of one key. If the high-order bit of a byte is set, the key is down.

lpwTransKey

Points to the buffer that will receive the translated Windows character or characters.

fuState

Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.

Return Value

If the specified key is a dead key, the return value is negative. Otherwise, it is one of the following values:

Value	Meaning
2	Two characters were copied to the buffer. This usually happens when a dead-key character (accent or diacritic) stored in the keyboard layout cannot be composed with the specified virtual key to form a single character.
1	One Windows character was copied to the buffer.
0	The specified virtual key has no translation for the current state of the keyboard.
Comments

The parameters supplied to the ToAscii function might not be sufficient to translate the virtual-key code, because a previous dead key is stored in the keyboard layout.

Typically, ToAscii performs the translation based on the virtual-key code. In some cases, however, bit 15 of the uScanCode parameter may be used to distinguish between a key press and a key release.

See Also

»OemKeyScan«, »ToUnicode«, »VkKeyScan«


  ToUnicode

int ToUnicode(wVirtKey, wScanCode, lpKeyState, pwszBuff, cchBuff, wFlags)
UINT  wVirtKey;   /* virtual-key code */
UINT  wScanCode;   /* scan code */
PBYTE  lpKeyState;   /* address of key-state array */
LPWSTR  pwszBuff;   /* buffer for translated key */
int  cchBuff;   /* size of translated key buffer */
UINT  wFlags;   /* set of function-conditioning flags */

The ToUnicode function translates the specified virtual-key code and keyboard state to the corresponding Unicode character or characters.

Parameters

wVirtKey

Specifies the virtual-key code to be translated.

wScanCode

Specifies the hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up.

lpKeyState

Points to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of one key. If the high-order bit of a byte is set, the key is down.

pwszBuff

Points to the buffer that receives the translated Unicode character or characters.

cchBuff

Specifies the size in characters of the buffer pointed to by pwszBuff.

wFlags

A set of bit flags that condition the behavior of the function.

Bits	Meaning
0	Must be set to 1 if a menu is active, cleared to 0 otherwise.
1−31	Reserved.
Return Value

The function returns one of the following values:

Value	Meaning
2 or more	Two or more characters were written to the buffer specified by pwszBuff. The most common cause for this is that a dead-key character (accent or diacritic) stored in the keyboard layout could not  be combined with the specified virtual key to form a single character.
1	One character was written to the buffer specified by pwszBuffer.
0	The specified virtual key has no translation for the current state of the keyboard. Nothing was written to the buffer specified by pwszBuffer.
-1	The specified virtual key is a dead-key character (accent or diacritic). This value is returned regardless of the keyboard layout, even if several characters have been typed and are stored in the keyboard state. If possible, even with Unicode keyboard layouts, the function has written a spacing version of the dead-key character to the buffer specified by pwszBuffer. For example, the function writes the character SPACING ACUTE (0x00B4) rather than the character NON_SPACING ACUTE (0x0301).
Comments

The parameters supplied to the ToUnicode function might not be sufficient to translate the virtual-key code because a previous dead key is stored in the keyboard layout.

Typically, ToUnicode performs the translation based on the virtual-key code. In some cases, however, bit 15 of the wScanCode parameter may be used to distinguish between a key press and a key release.

See Also

»ToAscii«, »VkKeyScan«


  TrackPopupMenu

BOOL TrackPopupMenu(hmenu, fuFlags, x, y, nReserved, hwnd, lprc)
HMENU  hmenu;   /* handle of pop-up menu */
UINT  fuFlags;   /* screen-position and mouse-button flags */
int  x;   /* horizontal screen position */
int  y;   /* vertical screen position */
int  nReserved;   /* reserved */
HWND  hwnd;   /* handle of owner window */
CONST RECT  *lprc;   /* address of structure with rectangle */

The TrackPopupMenu function displays the given floating pop-up menu at the specified location and tracks the selection of items on the pop-up menu. The floating pop-up menu can appear anywhere on the screen.

Parameters

hmenu

Identifies the pop-up menu to be displayed. This handle is obtained by calling CreatePopupMenu to create a new pop-up menu or by calling GetSubMenu to retrieve the handle of a pop-up menu associated with an existing menu item.

fuFlags

Specifies a screen-position flag and a mouse-button flag. The screen-position flag must be one of the following values:

Value	Meaning
TPM_CENTERALIGN	Centers the pop-up menu horizontally relative to the coordinate specified by the x-parameter.
TPM_LEFTALIGN	Positions the pop-up menu so that its left side is aligned with the coordinate specified by the x-parameter.
TPM_RIGHTALIGN	Positions the pop-up menu so that its right side is aligned with the coordinate specified by the x-parameter.
The mouse-button flag must be one of the following values:

Value	Meaning
TPM_LEFTBUTTON	Causes the pop-up menu to track the left mouse button.
TPM_RIGHTBUTTON	Causes the pop-up menu to track the right mouse button.
x

Specifies the horizontal position, in screen coordinates, of the pop-up menu. Depending on the value of the fuFlags parameter, the pop-up menu can be left-aligned, right-aligned, or centered relative to this position.

y

Specifies the vertical position, in screen coordinates, of the top of the menu on the screen.

nReserved

Reserved; must be zero.

hwnd

Identifies the window that owns the pop-up menu. This window receives all messages from the menu. The window does not receive a WM_COMMAND message from the menu until the TrackPopupMenu function returns.

lprc

Points to a RECT structure that contains the screen coordinates of a rectangle in which the user can select without dismissing the pop-up menu. If this parameter is NULL, the pop-up menu is dismissed if the user clicks outside the pop-up menu. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»CreatePopupMenu«, »GetSubMenu«


  TransactNamedPipe

BOOL TransactNamedPipe(hNamedPipe, lpvWriteBuf, cbWriteBuf, lpvReadBuf,
cbReadBuf, lpcbRead, lpo)
HANDLE  hNamedPipe;   /* handle of named pipe */
LPVOID  lpvWriteBuf;   /* address of the write buffer */
DWORD  cbWriteBuf;   /* size of the write buffer in bytes */
LPVOID  lpvReadBuf;   /* address of the read buffer */
DWORD  cbReadBuf;   /* size of the read buffer in bytes */
LPDWORD  lpcbRead;   /* address of variable for bytes actually read  */
LPOVERLAPPED  lpo;   /* address of overlapped structure */

The TransactNamedPipe function combines into a single network operation the functions that write a message to and read a message from the given named pipe.

Parameters

hNamedPipe

Identifies the named pipe returned by the CreateNamedPipe or CreateFile function.

lpvWriteBuf

Points to the buffer containing the data written to the pipe.

cbWriteBuf

Specifies the size, in bytes, of the write buffer.

lpvReadBuf

Points to the buffer that receives the data read from the pipe.

cbReadBuf

Specifies the size, in bytes, of the read buffer.

lpcbRead

Points to the variable that receives the number of bytes read from the pipe.

lpo

Points to an OVERLAPPED structure. If this parameter is NULL or if the FILE_FLAG_OVERLAPPED flag was not specified in the CreateNamedPipe or CreateFile function when the handle was created, TransactNamedPipe does not return until the operation is finished.

If lpo is not NULL and FILE_FLAG_OVERLAPPED was specified when the handle was created, TransactNamedPipe is executed as an overlapped operation. The OVERLAPPED structure should contain a manual reset event object (which can be created using the CreateEvent function). If the operation cannot be completed immediately, TransactNamedPipe returns FALSE and GetLastError returns ERROR_IO_PENDING. In this situation, the event object is set to the not-signaled state before TransactNamedPipe returns, and is set to the signaled state when the transaction has finished. For more information about overlapped operations, see Chapter 54, "Pipes."

The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The TransactNamedPipe function fails if the server did not create the pipe as a message-type pipe, or if the pipe handle is not in message-read mode. A pipe handle can be set to message-read mode with the SetNamedPipeHandleState function. The wait mode of the specified pipe handle (blocking or nonblocking) has no effect on the TransactNamedPipe function.

This function cannot be completed successfully until data is written into the lpvReadBuf buffer. The lpo parameter is available to enable the calling thread to perform other tasks while the operation is executing in the background.

If the message to be read is longer than cbReadBuf, TransactNamedPipe returns FALSE, and the GetLastError function returns ERROR_MORE_DATA. The remainder of the message can be read by a subsequent call to ReadFile, ReadFileEx, or PeekNamedPipe.

See Also

»CreateEvent«, »CreateFile«, »CreateNamedPipe«, »PeekNamedPipe«, »ReadFile«, »ReadFileEx«, »SetNamedPipeHandleState«


  TranslateAccelerator

int TranslateAccelerator(hwnd, haccl, lpmsg)
HWND  hwnd;   /* handle of destination window */
HACCEL  haccl;   /* handle of accelerator table */
LPMSG  lpmsg;   /* address of structure with message */

The TranslateAccelerator function processes accelerator keys for menu commands. The function translates a WM_KEYDOWN or WM_SYSKEYDOWN message to a WM_COMMAND or WM_SYSCOMMAND message (if there is an entry for the key in the specified accelerator table) and then sends the WM_COMMAND or WM_SYSCOMMAND message directly to the appropriate window procedure. TranslateAccelerator does not return until the window procedure has processed the message.

Parameters

hwnd

Identifies the window whose messages are to be translated.

haccl

Identifies an accelerator table. The accelerator table must have been loaded by a call to the LoadAccelerators function or created by a call to the CreateAcceleratorTable function.

lpmsg

Points to an MSG structure that contains message information retrieved from the calling thread's message queue by using the GetMessage or PeekMessage function. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To differentiate the message from messages sent by menus or controls, the high-order word of the lParam parameter of the WM_COMMAND or WM_SYSCOMMAND message contains the value 1.

Accelerator key combinations used to select items from the System menu are translated into WM_SYSCOMMAND messages; all other accelerator key combinations are translated into WM_COMMAND messages.

When TranslateAccelerator returns a nonzero value and the message is translated, the application should not use the TranslateMessage function to process the message again.

An accelerator need not correspond to a menu command.

If the accelerator command corresponds to a menu item, the application is sent WM_INITMENU and WM_INITMENUPOPUP messages, as if the user were trying to display the menu. However, these messages are not sent if any of the following conditions are present:

•	The window is disabled.

•	The menu item is disabled.

•	The accelerator key combination does not correspond to an item on the System menu and the window is minimized.

•	A mouse capture is in effect. For information about mouse capture, see the description of the »SetCapture« function.

If the specified window is the active window and no window has the keyboard focus (which is generally the case if the window is minimized), TranslateAccelerator translates WM_SYSKEYUP and WM_SYSKEYDOWN messages instead of WM_KEYUP and WM_KEYDOWN messages.

If an accelerator keystroke occurs that corresponds to a menu item when the window that owns the menu is minimized, TranslateAccelerator does not send a WM_COMMAND message. However, if an accelerator keystroke occurs that does not match any of the items in the window's menu or in the System menu, the function sends a WM_COMMAND message, even if the window is minimized.

See Also

»CreateAcceleratorTable«, »GetMessage«, »LoadAccelerators«, »PeekMessage«, »SetCapture«


  TranslateMDISysAccel

BOOL TranslateMDISysAccel(hwndClient, lpmsg)
HWND  hwndClient;   /* handle of MDI client window */
LPMSG  lpmsg;   /* address of structure with message data */

The TranslateMDISysAccel function processes accelerator keystrokes for System menu commands of the multiple document interface (MDI) child windows associated with the given MDI client window. The function translates WM_KEYUP and WM_KEYDOWN messages to WM_SYSCOMMAND messages and sends them to the appropriate MDI child windows.

Parameters

hwndClient

Identifies the MDI client window.

lpmsg

Points to a message retrieved by using the GetMessage or PeekMessage function. The message must be an MSG structure and contain message information from the application's message queue. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function translates a message into a system command, the return value is TRUE; otherwise, it is FALSE.

See Also

»GetMessage«, »PeekMessage«, »TranslateAccelerator«


  TranslateMessage

BOOL TranslateMessage(lpmsg)
CONST MSG  *lpmsg;   /* address of structure with message */

The TranslateMessage function translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function.

Parameters

lpmsg

Points to an MSG structure that contains message information retrieved from the calling thread's message queue by using the GetMessage or PeekMessage function. The MSG structure has the following form:

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the message is translated (that is, a character message is posted to the thread's message queue), the return value is TRUE; otherwise, it is FALSE.

Comments

The TranslateMessage function does not modify the message pointed to by the lpmsg parameter.

WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message.

TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver.

If applications process virtual-key messages for some other purpose, they should not call TranslateMessage. For instance, an application should not call TranslateMessage if the TranslateAccelerator function returns FALSE.

See Also

»GetMessage«, »PeekMessage«, »TranslateAccelerator«


  TransmitCommChar

BOOL TransmitCommChar(hCommDev, chTransmit)
HANDLE  hCommDev;   /* handle of the communications device  */
char  chTransmit;   /* character to transmit */

The TransmitCommChar function transmits a specified character ahead of any pending data in the output buffer of the specified communications device.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

chTransmit

Specifies the character to transmit.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The TransmitCommChar function is useful for sending an interrupt character (such as a CTRL+C) to a host system.

If the device is not transmitting, TransmitCommChar cannot be called repeatedly. Once TransmitCommChar places a character in the output buffer, the character must be transmitted before the function can be called again. If the previous character has not yet been sent, TransmitCommChar returns an error.

Character transmission is subject to normal flow control and handshaking. This function can only be called synchronously.

See Also

»WaitCommEvent«


  UndeleteFile

DWORD APIENTRY UndeleteFile(hwndOwner, lpszDir)
HWND  hwndOwner;   /* handle of File Manager window */
LPSTR  lpszDir;   /* address of name of initial directory */

The UndeleteFile function is an application-defined callback function that File Manager calls when the user chooses the Undelete command from the File Manager File menu.

Parameters

hwndOwner

Identifies the File Manager window. An "undelete" dynamic-link library (DLL) should use this handle to specify the owner window for any dialog box or message box the DLL may display.

lpszDir

Points to a null-terminated string that contains the name of the initial directory.

Return Value

If the function succeeds, the return value is one of the following:

Value	Meaning
−l	An error occurred.
IDOK	A file was undeleted. File Manager repaints its windows.
IDCANCEL	No file was undeleted.


  UnhandledExceptionFilter

LONG UnhandledExceptionFilter(lpexpExceptionInfo)
LPEXCEPTION_POINTERS  lpexpExceptionInfo;   /* address of exception info */

The UnhandledExceptionFilter function passes unhandled exceptions to the debugger, if the process is being debugged. Otherwise, it optionally displays an Application Error message box and causes the exception handler to be executed. This function can be called only from within the filter expression of a try-except exception handler.

Parameters

lpexpExceptionInfo

Points to an EXCEPTION_POINTERS structure containing a description of the exception and the processor context at the time of the exception. This pointer is the return value of a call to the GetExceptionInformation function.

The EXCEPTION_POINTERS structure has the following form:

typedef struct _EXCEPTION_POINTERS { /* exp */

    PEXCEPTION_RECORD ExceptionRecord;

    PCONTEXT ContextRecord;

} EXCEPTION_POINTERS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

The function returns one of the following values:

Value	Meaning
EXCEPTION_CONTINUE_SEARCH	The process is being debugged, so the exception should be passed (as second chance) to the application's debugger.
EXCEPTION_EXECUTE_HANDLER	If the SEM_NOGPFAULTERRORBOX flag was specified in a previous call to SetErrorMode, no Application Error message box is displayed. The function returns control to the exception handler which is free to take any appropriate action.
Comments

If the process is not being debugged, the function displays an Application Error message box depending on the current error mode. The default behavior is to display the dialog box, but this can be disabled by specifying SEM_NOGPFAULTERRORBOX in a call to the SetErrorMode function.

The system uses UnhandledExceptionFilter internally to handle exceptions that occur during process and thread creation.

See Also

»GetExceptionInformation«, »SetErrorMode«,


  UnhookWindowsHook

BOOL UnhookWindowsHook(nCode, hkprc)
int  nCode;   /* type of hook to remove procedure from  */
HOOKPROC  hkprc;   /* address of hook procedure */

The UnhookWindowsHook function is obsolete. For Win32 applications, use the UnhookWindowsHookEx function.


  UnhookWindowsHookEx

BOOL UnhookWindowsHookEx(hhook)
HHOOK  hhook;   /* handle of hook procedure to remove */

The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.

Parameters

hhook

Identifies the hook to be removed. This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The hook procedure can be in the state of being called by another thread even after UnhookWindowsHookEx returns. If the hook procedure is not being called concurrently, the hook procedure is removed immediately before UnhookWindowsHookEx returns.

See Also

»SetWindowsHookEx«, »UnhookWindowsHook«


  UnionRect

BOOL UnionRect(lprcDst, lprcSrc1, lprcSrc2)
LPRECT  lprcDst;   /* address of structure for union */
CONST RECT  *lprcSrc1;   /* address of structure with first rectangle */
CONST RECT  *lprcSrc2;   /* address of structure with second rectangle */

The UnionRect function creates the union of two rectangles. The union is the smallest rectangle that contains both source rectangles.

Parameters

lprcDst

Points to the RECT structure that will receive a rectangle containing the rectangles pointed to by the lprcSrc1 and lprcSrc2 parameters. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lprcSrc1

Points to the RECT structure that contains the first source rectangle.

lprcSrc2

Points to the RECT structure that contains the second source rectangle.

Return Value

If the specified structure contains a nonempty rectangle, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Windows ignores the dimensions of an empty rectangle — that is, a rectangle in which all coordinates are set to zero, so that it has no height or no width.

See Also

»InflateRect«, »IntersectRect«, »OffsetRect«


  UnloadKeyboardLayout

BOOL UnloadKeyboardLayout(hkl)
HKL  hkl;   /* handle of keyboard layout */

The UnloadKeyboardLayout function removes a keyboard layout.

Parameters

hkl

Identifies the keyboard layout to unload.

Return Value

If the function succeeds, the return value is the handle of the keyboard layout; otherwise, it is NULL. To get extended error information, use the GetLastError function.

See Also

»LoadKeyboardLayout«


  UnlockFile

BOOL UnlockFile(hFile, dwFileOffsetLow, dwFileOffsetHigh, cbUnlockLow, cbUnlockHigh)
HANDLE  hFile;   /* handle of file to unlock */
DWORD  dwFileOffsetLow;   /* low-order word of lock region offset */
DWORD  dwFileOffsetHigh;   /* high-order word of lock region offset */
DWORD  cbUnlockLow;   /* low-order word of length to unlock */
DWORD  cbUnlockHigh;   /* high-order word of length to unlock */

The UnlockFile function unlocks a region in an open file. Unlocking a region enables other processes to access the region.

Parameters

hFile

Identifies a file that contains a region locked with LockFile. The file handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.

dwFileOffsetLow

Specifies the low-order word of the starting byte offset in the file where the locked region begins.

dwFileOffsetHigh

Specifies the high-order word of the starting byte offset in the file where the locked region begins.

cbUnlockLow

Specifies the low-order word of the length of the byte range to be unlocked.

cbUnlockHigh

Specifies the high-order word of the length of the byte range to be unlocked.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Unlocking a region of a file releases a lock on the file. The region to unlock must correspond exactly to an existing locked region. For example, two adjacent regions of a file cannot be locked separately and then unlocked as a single region that spans both locked regions.

Do not terminate a process with a portion of a file locked or close a file that has locked regions.

This function works on a file allocation table (FAT)-based file system only if the operating system is running SHARE.EXE.

See Also

»CreateFile«, »LockFile«


  UnlockFileEx

BOOL UnlockFileEx(hFile, dwReserved, nNumberOfBytesToUnlockLow,
nNumberOfBytesToUnlockHigh, lpOverlapped)
HANDLE  hFile;   /* handle of file to lock */
DWORD  dwReserved;   /* reserved; must be set to zero */
DWORD  nNumberOfBytesToUnlockLow;   /* low order 32-bits of length to unlock */
DWORD  nNumberOfBytesToUnlockHigh;   /* high order 32-bits of length to unlock */
LPOVERLAPPED  lpOverlapped;   /* pointer to struct with unlock region start offset */

The UnlockFileEx function unlocks a previously locked byte range in an open file.

Parameters

hFile

Supplies an open handle to a file that is to have an existing locked region unlocked. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.

dwReserved

Reserved parameter that must be zero.

nNumberOfBytesToUnlockLow

Supplies the low order 32-bits of the length of the byte range to unlock.

nNumberOfBytesToUnlockHigh

Supplies the high order 32-bits of the length of the byte range to unlock.

lpOverlapped

Required pointer to an OVERLAPPED data structure that the function uses with the unlocking request. This structure contains the file offset of the beginning of the unlock range. The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE/NULL. Use the GetLastError function to obtain extended error information.

Comments

Unlocking a region of a file is releases a previously acquired lock on a file. The region to unlock must correspond exactly to an existing locked region. Two adjacent regions of a file can not be locked seperately and then unlocked using a single region that spans both locked regions.

If a process terminates with a portion of a file locked, or closes a file that has outstanding locks, the behavior is not specified.

See Also

»CreateFile«, »LockFile«, »LockFileEx«, »UnlockFile«


  UnlockResource

The UnlockResource function is obsolete. It is not necessary for Win32 applications to unlock resources.

See Also

»LoadResource«, »LockResource«


  UnlockSegment

The UnlockSegment function is obsolete.


  UnlockServiceDatabase

BOOL UnlockServiceDatabase(sclLock)
SC_LOCK  sclLock;   /* service control manager database lock to be released */

The UnlockServiceDatabase function unlocks a service control manager database by releasing the specified lock.

Parameters

sclLock

Specifies a lock obtained from a previous call to the LockServiceDatabase function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value	Meaning
ERROR_INVALID_SERVICE_LOCK	The specified lock is invalid.
See Also

»LockServiceDatabase«, »QueryServiceLockStatus«


  UnmapViewOfFile

BOOL UnmapViewOfFile(lpBaseAddress)
LPVOID  lpBaseAddress;   /* address where mapped view begins */

The UnmapViewOfFile function unmaps a mapped view of a file from the calling process's address space.

Parameters

lpBaseAddress

Points to the base address of the mapped view of a file that is to be unmapped. This value must be identical to the value returned by a previous call to the MapViewOfFile or MapViewOfFileEx function.

Return Value

If the function succeeds, the return value is TRUE and all dirty pages within the specified range are stored in the on-disk representation of the mapped file. Otherwise, the return value is FALSE. To get extended error information, use the GetLastError function.

See Also

»MapViewOfFile«, »MapViewOfFileEx«


  UnpackDDElParam

BOOL UnpackDDElParam(uMsg, lParam, puLow, puHigh)
UINT  uMsg;   /* posted DDE message */
LONG  lParam;   /* lParam of posted DDE message */
PUINT  puLow;   /* address of low-order word of lParam */
PUINT  puHigh;   /* address of high-order word of lParam */

The UnpackDDElParam function unpacks a dynamic data exchange (DDE) lParam value received from a posted DDE message.

Parameters

uMsg

Specifies the posted DDE message.

lParam

Specifies the lParam parameter of the posted DDE message that was received. The application must free the memory object specified by the lParam parameter by calling the FreeDDElParam function.

puLow

Points to a value the function will set to the low-order word of lParam.

puHigh

Points to a value the function will set to the high-order word of lParam.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The PackDDElParam function eases the porting of 16-bit DDE applications to 32-bit DDE applications.

See Also

»FreeDDElParam«, »PackDDElParam«, »ReuseDDElParam«


  UnrealizeObject

The UnrealizeObject function has been deleted.

For compatibility with Win16 applications, the function is still exported in WinGDI.h. That allows older applications to compile and link successfully. However, the only action the function now takes is to return a result of 0. New applications should not call the function. Older applications should remove their calls to it as soon as is practical.


  UnregisterClass

BOOL UnregisterClass(lpszClass, hinst)
LPCTSTR  lpszClass;   /* address of class name string  */
HINSTANCE  hinst;   /* handle of application instance */

The UnregisterClass function removes a window class, freeing the memory required for the class.

Parameters

lpszClass

Points to a null-terminated string or is an integer atom. If this parameter is an integer atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value less than 0xC000, must be in the low-order word of lpszClass; the high-order word must be zero.

The lpszClass string specifies the window class name. This class name must have been registered by a previous call to the RegisterClass function. System global classes, such as dialog box controls, cannot be unregistered.

hinst

Identifies the instance of the module that created the class.

Return Value

If the function succeeds, the return value is TRUE. If the class could not be found or if a window still exists that was created with the class, the return value is FALSE. To get extended error information, use the GetLastError function.

Comments

Before calling this function, an application must destroy all windows created with the specified class.

All window classes registered by an application are unregistered when it terminates.

See Also

»GlobalAddAtom«, »RegisterClass«


  UnregisterHotKey

BOOL UnregisterHotKey(hwnd, idHotKey)
HWND  hwnd;   /* window associated with hot key  */
int  idHotKey;   /* identifier of hot key */

The UnregisterHotKey function frees a hot key previously registered by the calling thread.

Parameters

hwnd

Identifies the window associated with the hot key to be freed. This parameter should be NULL if the hot key is not associated with a window.

idHotKey

Specifies the identifier of the hot key to be freed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»RegisterHotKey«, »WM_HOTKEY«


  UpdateColors

BOOL UpdateColors(hdc)
HDC  hdc;   /* handle of device context */

The UpdateColors function updates the client area of the given device context by remapping the current colors in the client area to the currently realized logical palette.

Parameters

hdc

Identifies the device context.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can determine whether a device supports palette operations by calling the GetDeviceCaps function and specifying the RASTERCAPS constant.

An inactive window with a realized logical palette may call UpdateColors as an alternative to redrawing its client area when the system palette changes.

The UpdateColors function typically updates a client area faster than redrawing the area. However, because UpdateColors performs the color translation based on the color of each pixel before the system palette changed, each call to this function results in the loss of some color accuracy.

This function must be called soon after a WM_SYSPALETTECHANGE message is received.

See Also

»GetDeviceCaps«, »RealizePalette«


  UpdateResource

BOOL UpdateResource(hUpdateFile, lpszType, lpszName, IDLanguage, lpvData, cbData)
HANDLE  hUpdateFile;   /* update-file handle */
LPTSTR  lpszType;   /* address of resource type to update */
LPTSTR  lpszName;   /* address of resource name to update */
WORD  IDLanguage;   /* language identifier of resource */
LPVOID  lpvData;   /* address of resource data */
DWORD  cbData;   /* length of resource data, in bytes */

The UpdateResource function adds, deletes, or replaces a resource in an executable file.

Parameters

hUpdateFile

Specifies an update-file handle. This handle is returned by the BeginUpdateResource function.

lpszType

Points to a null-terminated string specifying the resource type to be updated. This parameter can also be an integer value passed to the MAKEINTRESOURCE macro, or it can be one of the following predefined resource types:

Value	Meaning
RT_ACCELERATOR	Accelerator table
RT_BITMAP	Bitmap resource
RT_DIALOG	Dialog box
RT_FONT	Font resource
RT_FONTDIR	Font directory resource
RT_MENU	Menu resource
RT_RCDATA	Application-defined resource (raw data)
RT_STRING	String-table entry
RT_MESSAGETABLE	Message-table entry
RT_CURSOR	Hardware-dependent cursor resource
RT_GROUP_CURSOR	Hardware-independent cursor resource
RT_ICON	Hardware-dependent icon resource
RT_GROUP_ICON	Hardware-independent icon resource
RT_VERSION	Version resource
lpszName

Points to a null-terminated string specifying the name of the resource to be updated. This parameter can also be an integer value passed to the MAKEINTRESOURCE macro. For more information about the MAKEINTRESOURCE macro, see the Microsoft Win32 Programmer's Reference, Volume 5.

IDLanguage

Specifies the language identifier of the resource to be updated. For a list of the primary language identifiers and sublanguage identifiers that make up a language identifier, see the MAKELANGID macro in the Microsoft Win32 Programmer's Reference, Volume 5.

lpvData

Points to the resource data to be inserted into the executable file. If the resource is one of the predefined types, the data must be valid and properly aligned. Note that this is the raw binary data stored in the executable file, not the data provided by LoadIcon, LoadString, or other resource-specific load functions. All data containing strings or text must be in Unicode format; lpvData must not point to ANSI data.

If lpvData is NULL, the specified resource is deleted from the executable file.

cbData

Specifies the size of the resource data at lpvData, in bytes.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

An application can use UpdateResource repeatedly to make changes to the resource data. Each call to UpdateResource contributes to an internal list of additions, deletions, and replacements but does not actually write the data to the executable file. The application must use the EndUpdateResource function to write the accumulated changes to the executable file.

See Also

»BeginUpdateResource«, »EndUpdateResource«, »LockResource«, »SizeofResource«


  UpdateWindow

BOOL UpdateWindow(hwnd)
HWND  hwnd;   /* handle of window */

The UpdateWindow function updates the client area of the given window by sending a WM_PAINT message to the window if the window's update region is not empty. The function sends a WM_PAINT message directly to the window procedure of the given window, bypassing the application queue. If the update region is empty, no message is sent.

Parameters

hwnd

Identifies the window to be updated.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»ExcludeUpdateRgn«, »GetUpdateRect«, »GetUpdateRgn«, »InvalidateRgn«, »InvalidateRect«


  ValidateRect

BOOL ValidateRect(hwnd, lprc)
HWND  hwnd;   /* handle of window */
CONST RECT  *lprc;   /* address of structure with validation rectangle */

The ValidateRect function validates the client area within the given rectangle by removing the rectangle from the update region of the given window.

Parameters

hwnd

Identifies the window whose update region is to be modified. If this parameter is NULL, Windows invalidates and redraws all windows and sends the WM_ERASEBKGND and WM_NCPAINT messages to the window procedure before the function returns.

lprc

Points to a RECT structure that contains the client coordinates of the rectangle to be removed from the update region. If this parameter is NULL, the entire client area is removed. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The BeginPaint function automatically validates the entire client area. Neither the ValidateRect nor ValidateRgn function should be called if a portion of the update region must be validated before the next WM_PAINT message is generated.

Windows continues to generate WM_PAINT messages until the current update region is validated.

See Also

»BeginPaint«, »InvalidateRect«, »InvalidateRgn«, »ValidateRgn«


  ValidateRgn

BOOL ValidateRgn(hwnd, hrgn)
HWND  hwnd;   /* handle of window */
HRGN  hrgn;   /* handle of valid region */

The ValidateRgn function validates the client area within the given region by removing the region from the current update region of the given window.

Parameters

hwnd

Identifies the window whose update region is to be modified.

hrgn

Identifies a region that defines the area to be removed from the update region. If this parameter is NULL, the entire client area is removed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE.

Comments

The given region must have been created by a region function. The region coordinates are assumed to be client coordinates.

The BeginPaint function automatically validates the entire client area. Neither the ValidateRect nor ValidateRgn function should be called if a portion of the update region must be validated before the next WM_PAINT message is generated.

See Also

»BeginPaint«, »ExcludeUpdateRgn«, »InvalidateRgn«, »InvalidateRect«, »ValidateRect«


  VerFindFile

DWORD VerFindFile(dwFlags, szFileName, szWinDir, szAppDir, szCurDir,
lpdwCurDirLen, szDestDir, lpdwDestDirLen)
DWORD  dwFlags;   /* is this a shared file? */
LPTSTR  szFileName;   /* file to install */
LPTSTR  szWinDir;   /* Windows directory */
LPTSTR  szAppDir;   /* directory for file being installed */
LPTSTR  szCurDir;   /* current working directory */
LPDWORD  lpdwCurDirLen;   /* size of string in szCurDir */
LPTSTR  szDestDir;   /* recommended destination directory */
LPDWORD  lpdwDestDirLen;   /* size of string in szDestDir */

The VerFindFile function determines where to install a file based on whether it locates another version of the file in the system. The values VerFindFile returns in the specified buffers are used in a subsequent call to VerInstallFile.

As with the other file installation functions, VerFindFile will only work with Win32 file images. Sixteen-bit Windows file images are not supported.

Parameters

dwFlags

Contains a bitmask of flags. This parameter can be the following value:

Flag	Description
VFFF_ISSHAREDFILE	The source file can be shared by multiple applications. An application can use this information to determine where the file should be copied.
All other values are reserved for future use by Microsoft.

szFileName

Points to the name of the file to be installed. The filename can include only the filename and extension, not a path.

szWinDir

Points to the directory in which Windows is running or will be run. This string is returned by the GetWindowsDirectory function.

szAppDir

Points to the directory where the installation program is installing a set of related files. If the installation program is installing an application, this is the directory where the application will reside. This parameter also points to the application's current directory unless otherwise specified.

szCurDir

Points to a buffer that receives the path to a current version of the file being installed. The path is a zero-terminated string. If a current version is not installed, the buffer will contain a zero-length string. The buffer should be at least _MAX_PATH characters long, although this is not required.

lpdwCurDirLen

Points to a variable that contains the length of the szCurDir buffer. This pointer must not be NULL.

When the function returns, lpdwCurDirLen contains the size, in characters, of the data returned in szCurDir, including the terminating null character. If the buffer is too small to contain all the data, lpdwCurDirLen will be the size of the buffer required to hold the path.

szDestDir

Points to a buffer that receives the path to the installation location recommended by VerFindFile. The path is a zero-terminated string. The buffer should be at least _MAX_PATH characters long, although this is not required.

lpdwDestDirLen

Points to a variable that contains the length of the szDestDir buffer. This pointer must not be NULL.

When the function returns, lpdwDestDirLen contains the size, in characters, of the data returned in szDestDir, including the terminating null character. If the buffer is too small to contain all the data, lpdwDestDirLen will be the size of the buffer needed to hold the path.

Return Value

The return value is a bitmask that indicates the status of the file. It can be one or more of the following values:

Value	Meaning
VFF_CURNEDEST	The currently installed version of the file is not in the recommended destination.
VFF_FILEINUSE	Windows is using the currently installed version of the file; therefore, the file cannot be overwritten or deleted.
VFF_BUFFTOOSMALL	At least one of the buffers was too small to contain the corresponding string. An application should check the output buffers to determine which buffer was too small.
All other values are reserved for future use by Microsoft.

Comments

VerFindFile searches for a copy of the specified file by using the OpenFile function. However, it determines the system directory from the specified Windows directory, or searches the path.

If the dwFlags parameter indicates that the file is private to this application (not VFFF_ISSHAREDFILE), VerFindFile recommends installing the file in the application's directory. Otherwise, if the system is running a shared copy of Windows, the function recommends installing the file in the Windows directory. If the system is running a private copy of Windows, the function recommends installing the file in the system directory.

See Also

»VerInstallFile«


  VerInstallFile

DWORD VerInstallFile(dwFlags, szSrcFileName, szDestFileName, szSrcDir, szDestDir,
szCurDir, szTmpFile, lpdwTmpFileLen)
DWORD  dwFlags;   /* installation type */
LPTSTR  szSrcFileName;   /* file to install */
LPTSTR  szDestFileName;   /* new name of file to install */
LPTSTR  szSrcDir;   /* directory for file being installed */
LPTSTR  szDestDir;   /* directory in which to install file */
LPTSTR  szCurDir;   /* current working directory */
LPTSTR  szTmpFile;   /* temp. file used during install */
LPDWORD  lpdwTmpFileLen;   /* size of string in szTmpFile */

The VerInstallFile function attempts to install the specified file based on information returned from the VerFindFile function. VerInstallFile decompresses the file, if necessary, assigns a unique filename, and checks for errors, such as outdated files.

As with the other file installation functions, VerInstallFile will only work with Win32T file images. Sixteen-bit Windows file images are not supported.

Parameters

dwFlags

Contains a bitmask of flags. This parameter can be one of the following values:

Flag	Description
VIFF_FORCEINSTALL	Installs the file regardless of mismatched version numbers. The function checks only for physical errors during installation.
VIFF_DONTDELETEOLD	Installs the file without deleting the previously installed file, if the previously installed file is not in the destination directory.
All other values are reserved for future use by Microsoft.

szSrcFileName

Points to the name of the file to be installed. This is the filename in the directory pointed to by the szSrcDir parameter; the filename can include only the filename and extension, not a path.

szDestFileName

Points to the name VerInstallFile will give the new file upon installation. This filename may be different from the filename in the szSrcFileName directory. The new name should include only the filename and extension, not a path.

szSrcDir

Points to a buffer that contains the name of the directory where the new file is found.

szDestDir

Points to a buffer that contains the name of the directory where the new file should be installed. VerFindFile returns this value in its szDestDir parameter.

szCurDir

Points to a buffer that contains the name of the directory where the preexisting version of this file is found. VerFindFile returns this value in its szCurDir parameter.

szTmpFile

Points to a buffer that should be empty upon the initial call to VerInstallFile. The function fills the buffer with the name of a temporary copy of the source file. The buffer should be at least _MAX_PATH characters long, although this is not required.

lpdwTmpFileLen

Points to a variable that contains the length of the szTmpFile buffer. This pointer must not be NULL.

When the function returns, lpdwTmpFileLen contains the size, in characters, of the data returned in szTmpFile, including the terminating null character. If the buffer is too small to contain all the data, lpdwTmpFileLen will be the size of the buffer required to hold the data.

Return Value

The return value is a bitmask that indicates exceptions. It can be one or more of the following values:

Value	Meaning
VIF_TEMPFILE	The temporary copy of the new file is in the destination directory. The cause of failure is reflected in other flags.
VIF_MISMATCH	The new and preexisting files differ in one or more attributes. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_SRCOLD	The file to install is older than the preexisting file. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_DIFFLANG	The new and preexisting files have different language or code-page values. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_DIFFCODEPG	The new file requires a code page that cannot be displayed by the version of Windows currently running. This error can be overridden by calling VerInstallFile with the VIFF_FORCEINSTALL flag set.
VIF_DIFFTYPE	The new file has a different type, subtype, or operating system from the preexisting file. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_WRITEPROT	The preexisting file is write protected. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_FILEINUSE	The preexisting file is in use by Windows and cannot be deleted.
VIF_OUTOFSPACE	The function cannot create the temporary file due to insufficient disk space on the destination drive.
VIF_ACCESSVIOLATION	A read, create, delete, or rename operation failed due to an access violation.
VIF_SHARINGVIOLATION	A read, create, delete, or rename operation failed due to a sharing violation.
VIF_CANNOTCREATE	The function cannot create the temporary file. The specific error may be described by another flag.
VIF_CANNOTDELETE	The function cannot delete the destination file, or cannot delete the existing version of the file located in another directory. If the VIF_TEMPFILE bit is set, the installation failed, and the destination file probably cannot be deleted.
VIF_CANNOTDELETECUR	The existing version of the file could not be deleted and VIFF_DONTDELETEOLD was not specified.
VIF_CANNOTRENAME	The function cannot rename the temporary file, but already deleted the destination file.
VIF_OUTOFMEMORY	The function cannot complete the requested operation due to insufficient memory. Generally, this means the application ran out of memory attempting to expand a compressed file.
VIF_CANNOTREADSRC	The function cannot read the source file. This could mean that the path was not specified properly.
VIF_CANNOTREADDST	The function cannot read the destination (existing) files. This prevents the function from examining the file's attributes.
VIF_BUFFTOOSMALL	The szTmpFile buffer was too small to contain the name of the temporary source file. When the function returns, lpdwTmpFileLen contains the size of the buffer required to hold the filename.
All other values are reserved for future use by Microsoft.

Comments

VerInstallFile copies the file from the source directory to the destination directory. If szCurDir indicates that a previous version of the file exists on the system, VerInstallFile compares the files' version stamp information. If the previously installed version of the file is more recent than the new version, or if the files' attributes are significantly different, for example, if they are in different languages, then VerInstallFile returns with one or more recoverable error codes.

VerInstallFile leaves the temporary file in the destination directory. The application can either override the error or delete the temporary file. If the application overrides the error, VerInstallFile deletes the previously installed version and renames the temporary file with the original filename.

See Also

»VerFindFile«


  VerLanguageName

DWORD VerLanguageName(idLang, lpszLang, cbLang)
DWORD  idLang;   /* Microsoft language identifier */
LPTSTR  lpszLang;   /* address of buffer for language string  */
DWORD  cbLang;   /* size of buffer */

The VerLanguageName function converts the specified binary Microsoft language identifier into a text representation of the language.

Parameters

idLang

Specifies the binary Microsoft language identifier. For example, VerLanguageName translates 0x040A into Castilian Spanish. If VerLanguageName does not recognize the identifier, the lpszLang parameter points to a default string ("Language-Neutral"). For a complete list of the language identifiers supported by the Win32 API, see the following Comments section.

lpszLang

Points to the buffer to receive the null-terminated string representing the language specified by the idLang parameter.

cbLang

Indicates the size of the buffer, in characters, pointed to by lpszLang.

Return Value

If the return value is less than or equal to the buffer size, the return value is the size, in characters, of the string returned in the buffer. This value does not include the terminating null character.

If the return value is greater than the buffer size, the return value is the size of the buffer required to hold the entire string. The string is truncated to the length of the existing buffer.

If an error occurs, the return value is zero. Unknown language identifiers do not produce errors.

Comments

Typically, an installation program uses this function to translate a language identifier returned by the VerQueryValue function. The text string may be used in a dialog box that asks the user how to proceed in the event of a language conflict.

Following are the possible language identifiers and their corresponding languages:

Identifier	Language
0x0000	Language-Neutral
0x0400	Process Default Language
0x0401	Arabic
0x0402	Bulgarian
0x0403	Catalan
0x0404	Traditional Chinese
0x0804	Simplified Chinese
0x0405	Czech
0x0406	Danish
0x0407	German
0x0807	Swiss German
0x0408	Greek
0x0409	U.S. English
0x0809	U.K. English
0x0C09	Australian English
0x1009	Canadian English
0x040A	Castilian Spanish
0x080A	Mexican Spanish
0x0C0A	Modern Spanish
0x040B	Finnish
0x040C	French
0x080C	Belgian French
0x0C0C	Canadian French
0x100C	Swiss French
0x040D	Hebrew
0x040E	Hungarian
0x040F	Icelandic
0x0410	Italian
0x0810	Swiss Italian
0x0411	Japanese
0x0412	Korean
0x0413	Dutch
0x0813	Belgian Dutch
0x0414	Norwegian — Bokmål
0x0814	Norwegian — Nynorsk
0x0415	Polish
0x0416	Brazilian Portuguese
0x0816	Portuguese
0x0417	Rhaeto-Romanic
0x0418	Romanian
0x0419	Russian
0x041A	Croato-Serbian (Latin)
0x081A	Serbo-Croatian (Cyrillic)
0x041B	Slovak
0x041C	Albanian
0x041D	Swedish
0x041E	Thai
0x041F	Turkish
0x0420	Urdu
0x0421	Bahasa


  VerQueryValue

BOOL VerQueryValue(lpvBlock, lpszSubBlock, lplpBuffer, lpcc)
const LPVOID  lpvBlock;   /* address of buffer for version resource */
LPTSTR  lpszSubBlock;   /* address of value to retrieve */
LPVOID  *lplpBuffer;   /* address of buffer for version pointer */
LPDWORD  lpcc;   /* address of version-value length buffer */

The VerQueryValue function returns selected version information from the specified version-information resource. To retrieve the appropriate resource, the GetFileVersionInfo function must be called before VerQueryValue.

As with the other file installation functions, VerQueryValue will only work with Win32 file images. Sixteen-bit Windows file images are not supported.

Parameters

lpvBlock

Points to the buffer containing the version-information resource returned by GetFileVersionInfo.

lpszSubBlock

Points to a zero-terminated string specifying which version-information value to retrieve. The string consists of names separated by backslashes (\) and can have one of the following forms:

Form	Description
\	Specifies the root block. The function retrieves a pointer to the VS_FIXEDFILEINFO structure for the version-information resource.
\VarFileInfo\Translation	Specifies the translation table in the variable information structure. The function retrieves a pointer to an array of language and character-set identifiers. An application uses these identifiers to create the name of a language-specific structure in the version-information resource.
\StringFileInfo\lang-charset\string-name	Specifies a value in a language-specific structure. The lang-charset name is a concatenation of a language and character-set identifier pair found in the translation table for the resource. The lang-charset name must be specified as a hexadecimal string. The string-name name is one of the predefined strings described in the following Comments section.
lplpBuffer

Points to a buffer that receives a pointer to the version-information value.

lpcc

Points to a buffer that receives the length, in characters, of the version-information value.

Return Value

If the specified structure exists and version information is available, the return value is nonzero. If the address of the length buffer is zero, no value is available for the specified version-information name. If the specified name does not exist or the specified resource is not valid, the return value is zero.

Comments

Windows NT contains the following predefined version information strings:

CompanyName FileDescription FileVersion InternalName LegalCopyright OriginalFilename ProductName ProductVersion

The following example shows how to retrieve the FileDescription string-value from a block of version information:

VerQueryValue(lpvBlock,

              TEXT("\\StringFileInfo\\040904E4\\FileDescription"),

              &lpBuffer,

              &dwBytes);

Call the GetFileVersionInfoSize and GetFileVersionInfo functions to properly initialize the lpvBlock buffer before calling the VerQueryValue function.

See Also

»GetFileVersionInfo«, »GetFileVersionInfoSize«, »VS_VERSION_INFO«


  VirtualAlloc

LPVOID VirtualAlloc(lpvAddress, cbSize, fdwAllocationType, fdwProtect)
LPVOID  lpvAddress;   /* address of region to reserve or commit */
DWORD  cbSize;   /* size of the region */
DWORD  fdwAllocationType;   /* type of allocation */
DWORD  fdwProtect;   /* type of access protection */

The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero.

Parameters

lpvAddress

Specifies the desired starting address of the region. If the memory is being reserved, the specified address is rounded down to the next 64K byte boundary. If the memory is already reserved and is being committed, the address is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function. If this parameter is NULL, the system determines where to allocate the region.

cbSize

Specifies the size, in bytes, of the region. If the lpvAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpvAddress to (lpvAddress+cbSize). This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.

fdwAllocationType

Specifies the type of allocation. One or both of the following flags is specified:

Value	Meaning
MEM_COMMIT	Allocates physical storage in memory or in the paging file on disk for the specified region of pages. The MEM_RESERVE flag must also be specified, or the specified range of pages must have been reserved by a previous call to the VirtualAlloc function.
	An attempt to commit an already-committed page will not cause the function to fail. This means that a range of committed/decommited pages can be commited without having to worry about a failure.
MEM_RESERVE	Reserves a range of the process's virtual address space without allocating any physical storage. The reserved range cannot be used by any other allocation operations (the malloc function, the LocalAlloc function, and so on) until it is released. Reserved pages can be committed in subsequent calls to the VirtualAlloc function.
fdwProtect

Specifies the type of access protection. If the pages are being reserved but not committed, this parameter must specify the PAGE_NOACCESS flag. If the pages are being committed, any one of the following flags can be specified:

Value	Meaning
PAGE_NOACCESS	Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_READONLY	Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execution access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE	Enables both read and write access to the committed region of pages.
Return Value

If the function succeeds, the return value is the base address of the allocated region of pages; otherwise, it is NULL. To get extended error information, use the GetLastError function.

Comments

The VirtualAlloc function can perform the following operations:

•	Commit a region of pages reserved by a previous call to the VirtualAlloc function.

•	Reserve a region of free pages.

•	Reserve and commit a region of free pages.

You can use VirtualAlloc to reserve a block of pages and then make additional calls to VirtualAlloc to commit individual pages from the reserved block. This enables a process to reserve a range of its virtual address space without consuming physical storage until it is needed.

Each page in the process's virtual address space is in one of three states:

State	Meaning
Free	The page is not committed or reserved and is not accessible to the process. VirtualAlloc can reserve, or simultaneously reserve and commit, a free page.
Reserved	The range of addresses cannot be used by other allocation functions, but the page is not accessible and has no physical storage associated with it. VirtualAlloc can commit a reserved page, but it cannot reserve it a second time. The VirtualFree function can release a reserved page, making it a free page.
Committed	Physical storage is allocated for the page, and access is controlled by a protection code. The system initializes and loads each committed page into physical memory only at the first attempt to read or write that page. When the process terminates, the system releases the storage for committed pages. VirtualAlloc can commit an already-committed page; this means that a range of committed/uncommitted pages can be committed without having to worry about a failure. The VirtualFree function can decommit a committed page, releasing the page's storage, or it can simultaneously decommit and release a committed page.
If the lpvAddress parameter is not NULL, the function uses the lpvAddress and cbSize parameters to compute the region of pages to be allocated. The current state of the entire range of pages must be compatible with the type of allocation specified by the fdwAllocationType parameter. Otherwise, the function fails and none of the pages are allocated. This compatibility requirement does not preclude committing an already-committed page; see the comments above in this regard.

See Also

»GlobalAlloc«, »VirtualFree«, »VirtualLock«, »VirtualProtect«, »VirtualQuery«


  VirtualFree

BOOL VirtualFree(lpvAddress, cbSize, fdwFreeType)
LPVOID  lpvAddress;   /* address of region of committed pages */
DWORD  cbSize;   /* size of the region */
DWORD  fdwFreeType;   /* type of free operation */

The VirtualFree function releases or decommits (or both) a region of pages within the virtual address space of the calling process.

Parameters

lpvAddress

Points to the base address of the region of pages to be freed. If the fdwFreeType parameter includes the MEM_RELEASE flag, this parameter must be the base address returned by the VirtualAlloc function when the region of pages was reserved.

cbSize

Specifies the size, in bytes, of the region to be freed. If the fdwFreeType parameter includes the MEM_RELEASE flag, this parameter must be zero. Otherwise, the region of affected pages includes all pages containing one or more bytes in the range from the lpvAddress parameter to (lpvAddress+cbSize). This means that a 2-byte range straddling a page boundary causes both pages to be freed.

fdwFreeType

Specifies the type of free operation. You may use one, but NOT both, of the following flags:

Flag	Meaning
MEM_DECOMMIT	Decommits the specified region of committed pages.
	An attempt to decommit an uncommitted page will not cause the function to fail. This means that a range of committed/uncommited pages can be decommited without having to worry about a failure.
MEM_RELEASE	Releases the specified region of reserved pages. If this flag is specified, the cbSize parameter must be zero, or the function fails.
Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The VirtualFree function can perform one of the following operations:

•	Decommit a region of committed/uncommitted pages.

•	Release a region of reserved pages.

•	Decommit and release a region of committed/uncommitted pages.

To release a region of pages, the entire range of pages must be in the same state (all reserved or all committed) and the entire region originally reserved by the VirtualAlloc function must be released at the same time. If only part of the pages in the original reserved region are committed, you must first call VirtualFree to decommit the committed pages and then call VirtualFree again to release the entire block.

Pages that have been released are free pages available for subsequent allocation operations. Attempting to read from or write to a free page results in an access violation exception.

VirtualFree can decommit an uncommitted page; this means that a range of committed/uncommitted pages can be decommitted without having to worry about a failure. Decommitting a page releases its physical storage, either in memory or in the paging file on disk. If a page is decommitted but not released, its state changes to reserved, and it can be committed again by a subsequent call to VirtualAlloc. Attempting to read from or write to a reserved page results in an access violation exception.

The current state of the entire range of pages must be compatible with the type of free operation specified by the fdwFreeType parameter. Otherwise, the function fails and no pages are released or decommitted.

See Also

»GlobalAlloc«, »GlobalFree«, »VirtualAlloc«


  VirtualLock

BOOL VirtualLock(lpvAddress, cbSize)
LPVOID  lpvAddress;   /* address of first byte of range to lock  */
DWORD  cbSize;   /* number of bytes in range to lock */

The VirtualLock function locks the specified region of the process's virtual address space into memory, ensuring that subsequent access to the region will not incur a page fault.

Parameters

lpvAddress

Points to the base address of the region of pages to be locked.

cbSize

Specifies the size, in bytes, of the region to be locked. The region of affected pages includes all pages that contain one or more bytes in the range from the lpvAddress parameter to (lpvAddress+cbSize). This means that a 2-byte range straddling a page boundary causes both pages to be locked.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

All pages in the specified region must be committed. Memory protected with the PAGE_NOACCESS flag cannot be locked.

Locking pages into memory may degrade the performance of the system by reducing the available RAM and forcing the system to swap out other critical pages to the paging file. There is a limit on the number of pages that can be locked: 30 pages. The limit is intentionally small to avoid severe performance degradation.

To unlock a region of locked pages, use the VirtualUnlock function. Locked pages are automatically unlocked when the process terminates.

This function is not like the GlobalLock or LocalLock function in that it does not increment a lock count and translate a handle into a pointer. There is no lock count for virtual pages, so multiple calls to the VirtualUnlock function are never required to unlock a region of pages.

See Also

»GlobalLock«, »LocalLock«, »VirtualUnlock«


  VirtualProtect

BOOL VirtualProtect(lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect)
LPVOID  lpvAddress;   /* address of region of committed pages */
DWORD  cbSize;   /* size of the region */
DWORD  fdwNewProtect;   /* desired access protection */
PDWORD  pfdwOldProtect;   /* address of variable to get old protection */

The VirtualProtect function changes the access protection on a region of committed pages in the virtual address space of the calling process.

Parameters

lpvAddress

Points to the base address of the region of pages whose access protection attributes are changed.

cbSize

Specifies the size, in bytes, of the region whose access protection attributes are changed. The region of affected pages includes all pages containing one or more bytes in the range from the lpvAddress parameter to (lpvAddress+cbSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.

fdwNewProtect

Specifies the new access protection. One of the following flags is specified:

Value	Meaning
PAGE_NOACCESS	Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_READONLY	Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execution access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE	Enables both read and write access to the committed region of pages.
pfdwOldProtect

Points to a variable to receive the previous access protection of the first page within the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The access protection value can only be set on committed pages. If the state of any page in the specified region is not committed, the function fails and returns without modifying the access protection of any pages in the specified region.

This function changes the access protection of memory in the calling process, and the VirtualProtectEx function changes the access protection of memory in a specified process.

See Also

»VirtualAlloc«, »VirtualProtectEx«


  VirtualProtectEx

BOOL VirtualProtectEx(hProcess, lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect)
HANDLE  hProcess;   /* handle of the process */
LPVOID  lpvAddress;   /* address of region of committed pages */
DWORD  cbSize;   /* size of the region */
DWORD  fdwNewProtect;   /* desired access protection */
PDWORD  pfdwOldProtect;   /* address of variable to get old protection */

The VirtualProtectEx function changes the access protection on a region of committed pages in the virtual address space of the specified process.

Parameters

hProcess

Identifies the process whose memory protection is changed. The handle must have PROCESS_VM_OPERATION access.

lpvAddress

Points to the base address of the region of pages whose access protection attributes are changed.

cbSize

Specifies the size, in bytes, of the region whose access protection attributes are changed. The region of affected pages includes all pages containing one or more bytes in the range from the lpvAddress parameter to (lpvAddress+cbSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.

fdwNewProtect

Specifies the new access protection. One of the following flags is specified:

Value	Meaning
PAGE_NOACCESS	Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_READONLY	Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execution access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE	Enables both read and write access to the committed region of pages.
pfdwOldProtect

Points to a variable to receive the previous access protection of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The access protection value can only be set on committed pages. If the state of any page in the specified region is not committed, the function fails and returns without modifying the access protection of any pages in the specified region.

This function is identical to the VirtualProtect function except that it enables changing the access protection of memory in a specified process.

See Also

»VirtualAlloc«, »VirtualProtect«, »VirtualQueryEx«


  VirtualQuery

DWORD VirtualQuery(lpvAddress, pmbiBuffer, cbLength)
LPVOID  lpvAddress;   /* address of region */
PMEMORY_BASIC_INFORMATION  pmbiBuffer;   /* address of information buffer */
DWORD  cbLength;   /* size of buffer */

The VirtualQuery function provides information about a range of pages in the virtual address space of the calling process.

Parameters

lpvAddress

Points to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.

pmbiBuffer

Points to a MEMORY_BASIC_INFORMATION structure in which information about the specified page range is returned. The MEMORY_BASIC_INFORMATION structure has the following form:

typedef struct _MEMORY_BASIC_INFORMATION { /* mbi */

    PVOID BaseAddress;            /* base address of region    */

    PVOID AllocationBase;         /* allocation base address   */

    DWORD AllocationProtect;      /* initial access protection */

    DWORD RegionSize;             /* size, in bytes, of region */

    DWORD State;                  /* committed, reserved, free */

    DWORD Protect;                /* current access protection */

    DWORD Type;                   /* type of pages             */

} MEMORY_BASIC_INFORMATION;

typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbLength

Specifies the size, in bytes, of the buffer pointed to by the pmbiBuffer parameter.

Return Value

The return value is the actual number of bytes returned in the information buffer.

Comments

The VirtualQuery function provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

•	The state of all pages is the same with the MEM_COMMIT, MEM_RESERVE, or MEM_FREE flag.

•	If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAlloc function.

•	The access protection of all pages is the same with the PAGE_READONLY, PAGE_READWRITE, or PAGE_NOACCESS flag.

The function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages, or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size, in bytes, of the region of pages with matching attributes.

This function reports on a region of pages in the memory of the calling process, and the VirtualQueryEx function reports on a region of pages in the memory of a specified process.

See Also

»VirtualQueryEx«


  VirtualQueryEx

DWORD VirtualQueryEx(hProcess, lpvAddress, pmbiBuffer, cbLength)
HANDLE  hProcess;   /* handle of the process */
LPVOID  lpvAddress;   /* address of region */
PMEMORY_BASIC_INFORMATION  pmbiBuffer;   /* address of information buffer */
DWORD  cbLength;   /* size of buffer */

The VirtualQueryEx function provides information about a range of pages within the virtual address space of the specified process.

Parameters

hProcess

Identifies the process whose memory information is queried. The handle must have PROCESS_QUERY_INFORMATION access.

lpvAddress

Points to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.

pmbiBuffer

Points to a MEMORY_BASIC_INFORMATION structure in which information about the specified page range is returned. The MEMORY_BASIC_INFORMATION structure has the following form:

typedef struct _MEMORY_BASIC_INFORMATION { /* mbi */

    PVOID BaseAddress;            /* base address of region    */

    PVOID AllocationBase;         /* allocation base address   */

    DWORD AllocationProtect;      /* initial access protection */

    DWORD RegionSize;             /* size, in bytes, of region */

    DWORD State;                  /* committed, reserved, free */

    DWORD Protect;                /* current access protection */

    DWORD Type;                   /* type of pages             */

} MEMORY_BASIC_INFORMATION;

typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbLength

Specifies the size, in bytes, of the buffer pointed to by the pmbiBuffer parameter.

Return Value

The return value is the actual number of bytes returned in the information buffer.

Comments

The VirtualQueryEx function provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

•	The state of all pages is the same with the MEM_COMMIT, MEM_RESERVE, or MEM_FREE parameter.

•	If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAlloc function.

•	The access protection of all pages is the same with the PAGE_READONLY, PAGE_READWRITE, or PAGE_NOACCESS flag.

The VirtualQueryEx function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages, or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size, in bytes, of the region of pages with matching attributes.

This function is identical to the VirtualQuery function, except that it enables access to information about memory in a specified process.

See Also

»VirtualProtectEx«, »VirtualQuery«


  VirtualUnlock

BOOL VirtualUnlock(lpvAddress, cbSize)
LPVOID  lpvAddress;   /* address of first byte of range  */
DWORD  cbSize;   /* number of bytes in range */

The VirtualUnlock function unlocks a specified range of pages in the process's virtual address space, enabling the system to swap the pages out to the paging file if necessary.

Parameters

lpvAddress

Points to the base address of the region of pages to be unlocked.

cbSize

Specifies the size, in bytes, of the region being unlocked. The region of affected pages includes all pages containing one or more bytes in the range from the lpvAddress parameter to (lpvAddress+cbSize). This means that a 2-byte range straddling a page boundary causes both pages to be unlocked.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

For the function to succeed, the range specified need not match a range passed to a previous VirtualLock call, but all pages in the range must be locked.

See Also

»VirtualLock«


  VkKeyScan

SHORT VkKeyScan(ch)
TCHAR  ch;   /* character to translate */

The VkKeyScan function translates a character to the corresponding virtual-key code and shift state for the current keyboard.

Parameters

ch

Specifies the character to be translated into a virtual-key code.

Return Value

If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains the shift state, which can be a combination of the following flag bits:

Bit	Meaning
1	Either SHIFT key is pressed.
2	Either CTRL key is pressed.
4	Either ALT key is pressed.
If the function finds no key that translates to the passed character code, both the low-order and high-order bytes contain −1.

Comments

For keyboard layouts that use the right-hand ALT key (AltGr) as a shift key (for example, the French keyboard layout), the shift state is represented by the value 6, because AltGr is converted internally into CTRL+ALT.

Translations for the numeric keypad (VK_NUMPAD0 through VK_DIVIDE) are ignored. This function is intended to translate characters into keystrokes from the main keyboard section only. For example, the character '7' is translated into VK_7, not VK_NUMPAD7.

VkKeyScan is used by applications that send characters by using the WM_KEYUP and WM_KEYDOWN messages.

See Also

»GetAsyncKeyState«, »GetKeyNameText«, »GetKeyboardState«, »GetKeyState«, »SetKeyboardState«


  WaitCommEvent

BOOL WaitCommEvent(hCommDev, lpfdwEvtMask, lpo)
HANDLE  hCommDev;   /* handle of the communications device */
LPDWORD  lpfdwEvtMask;   /* address of variable for event that occurred  */
LPOVERLAPPED  lpo;   /* address of overlapped structure */

The WaitCommEvent function waits for an event to occur for a specified communications device. The set of events that are monitored by this function is contained in the event mask associated with the device handle.

Parameters

hCommDev

Identifies the communications device. The CreateFile function returns this handle.

lpfdwEvtMask

Points to a 32-bit variable that receives a mask indicating the type of event that occurred. If an error occurs, the value is zero; otherwise, it is one of the following values:

Value	Meaning
EV_BREAK	A break was detected on input.
EV_CTS	The CTS (clear-to-send) signal changed state.
EV_DSR	The DSR (data-set-ready) signal changed state.
EV_ERR	A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING	A ring indicator was detected.
EV_RLSD	The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR	Any character was received and placed in the input buffer.
EV_RXFLAG	The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY	The last character in the output buffer was sent.
lpo

Points to an OVERLAPPED structure. This parameter is ignored if the hCommDev handle was opened without specifying the FILE_FLAG_OVERLAPPED flag. If overlapped operation is not desired, this parameter can be NULL. The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The WaitCommEvent function monitors a set of events for a specified communications resource. To set and query the current event mask of a communications resource, use the SetCommMask and GetCommMask functions.

If the lpo parameter is NULL or the hCommDev handle was opened without specifying the FILE_FLAG_OVERLAPPED flag, the WaitCommEvent function does not return until one of the specified events or an error occurs.

If lpo points to an OVERLAPPED structure and FILE_FLAG_OVERLAPPED was specified when the hCommDev handle was opened, WaitCommEvent is performed as an overlapped operation. In this case, the OVERLAPPED structure must contain a handle to a manual-reset event object (created by using the CreateEvent function).

If the overlapped operation cannot be completed immediately, the function returns FALSE and GetLastError returns ERROR_IO_PENDING, indicating that the operation is executing in the background. When this happens, the system sets the hEvent member of the OVERLAPPED stucture to the not-signaled state before WaitCommEvent returns, and then it sets it to the signaled state when one of the specified events or an error occurs. The calling process can use wait function to determine the event object's state, then use the GetOverlappedResult function to determine the results of the WaitCommEvent operation. GetOverlappedResult reports the success or failure of the operation, and the variable pointed to by the lpfdwEvtMask parameter is set to indicate the event that occurred.

If a process attempts to change the device handle's event mask by using the SetCommMask function while a WaitCommEvent operation is in progress, WaitCommEvent returns immediately. The variable pointed to by the lpfdwEvtMask parameter is set to zero.

See Also

»GetCommMask«, »SetCommMask«


  WaitForDebugEvent

BOOL WaitForDebugEvent(lpde, dwTimeout)
LPDEBUG_EVENT  lpde;   /* address of structure for event information  */
DWORD  dwTimeout;   /* number of milliseconds to wait for event */

The WaitForDebugEvent function waits for a debugging event to occur in a process being debugged.

Parameters

lpde

Points to a DEBUG_EVENT structure that is filled with information about the debugging event.

The DEBUG_EVENT structure has the following form:

typedef struct _DEBUG_EVENT { /* de */

    DWORD dwDebugEventCode;

    DWORD dwProcessId;

    DWORD dwThreadId;

    union {

        EXCEPTION_DEBUG_INFO Exception;

        CREATE_THREAD_DEBUG_INFO CreateThread;

        CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;

        EXIT_THREAD_DEBUG_INFO ExitThread;

        EXIT_PROCESS_DEBUG_INFO ExitProcess;

        LOAD_DLL_DEBUG_INFO LoadDll;

        UNLOAD_DLL_DEBUG_INFO UnloadDll;

        OUTPUT_DEBUG_STRING_INFO DebugString;

        RIP_INFO RipInfo;

    } u;

} DEBUG_EVENT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwTimeout

Specifies the number of milliseconds to wait for a debugging event. If dwTimeout is zero, the function tests for a debugging event and returns immediately. If dwTimeout is INFINITE, the function does not return until a debugging event has occurred.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Only the thread that created the process being debugged can call WaitForDebugEvent.

See Also

»ContinueDebugEvent«, »CreateProcess«, »DebugActiveProcess«, »DebugBreak«, »OutputDebugString«


  WaitForInputIdle

DWORD WaitForInputIdle(hProcess, dwTimeout)
HANDLE  hProcess;   /* handle to process */
DWORD  dwTimeout;   /* time-out interval in milliseconds */

The WaitForInputIdle function waits until the given process is waiting for user input with no input pending, or until the time-out interval has elapsed.

The WaitForInputIdle function only works with GUI applications. If a console application calls the function, it returns immediately, with no wait.

Parameters

hProcess

Identifies the process.

dwTimeout

Specifies the time-out interval, in milliseconds. If dwTimeout is INFINITE, the function does not return until the process is idle.

Return Value

The following table shows the possible return values:

Value	Meaning
0	The wait was satisfied successfully.
WAIT_TIMEOUT	The wait was terminated because the time-out interval elapsed.
0xFFFFFFFF	An error occurred. To get extended error information, use the GetLastError function.
Comments

The WaitForInputIdle function enables a thread to suspend its execution until a specified process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronizing a parent process and a newly created child process. When a parent process creates a child process, the CreateProcess function returns without waiting for the child process to finish its initialization. Before trying to communicate with the child process, the parent process can use WaitForInputIdle to determine when the child's initialization has been completed. For example, the parent process should use WaitForInputIdle before trying to find a window associated with the child process.

The WaitForInputIdle function can be used at any time, not just during application startup.

See Also

»CreateProcess«


  WaitForMultipleObjects

DWORD WaitForMultipleObjects(cObjects, lphObjects, fWaitAll, dwTimeout)
DWORD  cObjects;   /* number of handles in handle array */
LPHANDLE  lphObjects;   /* address of object-handle array */
BOOL  fWaitAll;   /* wait flag */
DWORD  dwTimeout;   /* time-out interval in milliseconds */

The WaitForMultipleObjects function returns either when any one or when all of the specified objects are in the signaled state, or when the time-out interval elapses.

Parameters

cObjects

Specifies the number of object handles in the array pointed to by lphObjects. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.

lphObjects

Points to an array of object handles. For a list of the object types whose handles can be specified, see the Comments section. The array can contain handles of objects of different types. The handles must have SYNCHRONIZE access.

fWaitAll

Specifies the wait type. If TRUE, the function returns when all objects in the lphObjects array are signaled at the same time. If FALSE, the function returns when any one of the objects is signaled. In the latter case, the return value indicates the object whose state caused the function to return.

dwTimeout

Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the conditions specified by the fWaitAll parameter are not satisfied. If dwTimeout is zero, the function tests the states of the specified objects and returns immediately. If dwTimeout is INFINITE, the function's time-out interval never elapses.

Return Value

If the function succeeds, the return value indicates the event that caused the function to return; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

The return value on success is one of the following values:

Value	Meaning
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + cObjects − 1)
	If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If fWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lphObjects array index of the object that satisfied the wait.
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + cObjects − 1)
	If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object. If fWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lphObjects array index of an abandoned mutex object that satisfied the wait.
WAIT_TIMEOUT
	The time-out interval elapsed and the conditions specified by the fWaitAll parameter are not satisfied.
Comments

The WaitForMultipleObjects function determines whether the conditions exist that satisfy the wait. If the wait is not satisfied, the calling thread enters an efficient wait state, consuming very little processor time while waiting for one of the conditions of the wait to be satisfied.

When fWaitAll is TRUE, the function's wait condition is satisfied only when the state of all objects is signaled at the same time. The function does not modify the state of the specified objects until all objects are simultaneously signaled. For example, a mutex can be signaled, but the thread does not get ownership until the other objects are also signaled. In the meantime, some other thread may get ownership of the mutex, thereby delaying satisfaction of the wait condition.

The system adjusts the state of some types of objects after the object's signaled state satisfies a wait condition. For example, the count of a semaphore object is decreased by one.

The WaitForMultipleObjects function can specify handles of any of the following object types in the lphObjects array:

Object	Description
change notification	The handle is returned by the FindFirstChangeNotification function. A change notification object's state is signaled when a specified type of change occurs within a specified directory or directory tree.
console input	The handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. The object's state is signaled when there is unread input in the console's input buffer, and it is nonsignaled when the input buffer is empty.
event	The handle is returned by the CreateEvent or OpenEvent function. An event object's state is set explicitly to signaled by the SetEvent or PulseEvent function. A manual-reset event object's state must be reset explicitly to nonsignaled by the ResetEvent function. For an auto-reset event object, the wait function resets the object's state to nonsignaled before returning. Event objects are also used in overlapped operations, in which the state is set by the system.
mutex	The handle is returned by the CreateMutex or OpenMutex function. A mutex object's state is signaled when it is not owned by any thread. The wait function requests ownership of the mutex for the calling thread, changing the mutex's state to nonsignaled when ownership is granted.
process	The handle is returned by the CreateProcess or OpenProcess function. A process object's state is signaled when the process terminates.
thread	The handle is returned by the CreateProcess, CreateThread, or CreateRemoteThread function. A thread object's state is signaled when the thread terminates.
semaphore	The handle is returned by the CreateSemaphore or OpenSemaphore function. A semaphore object maintains a count between zero and some maximum value. Its state is signaled when its count is greater than zero and nonsignaled when its count is zero. If the current state is signaled, the wait function decreases the count by one.
In some circumstances, a wait function can specify a handle of a file, named pipe, or communications device as an object to wait for. However, their use for this purpose is discouraged. For more information, see Chapter 44, "Synchronization."

See Also

»MsgWaitForMultipleObjects«, »Sleep«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«


  WaitForMultipleObjectsEx

DWORD WaitForMultipleObjectsEx(cObjects, lphObjects, fWaitAll, dwTimeout, fAlertable)
DWORD  cObjects;   /* number of handles in handle array */
LPHANDLE  lphObjects;   /* address of object-handle array */
BOOL  fWaitAll;   /* wait flag */
DWORD  dwTimeout;   /* time-out interval in milliseconds  */
BOOL  fAlertable;   /* alertable wait flag */

The WaitForMultipleObjectsEx function is an extended wait function that can be used to perform an alertable wait. This enables the function to return when the system queues an input and output (I/O) completion routine to be executed by the calling thread. The function also returns either when any one or when all of the specified objects are in the signaled state, or when the time-out interval elapses.

This function is available only in Microsoft® Windows NT™.

Parameters

cObjects

Specifies the number of object handles to wait for in the array pointed to by lphObjects. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.

lphObjects

Points to an array of object handles. For a list of the object types whose handles can be specified, see the Comments section. The array can contain handles of objects of different types. The handles must have SYNCHRONIZE access.

fWaitAll

Specifies the wait type. If TRUE, the function returns when all objects in the lphObjects array are signaled at the same time. If FALSE, the function returns when any one of the objects is signaled. In the latter case, the return value indicates the object whose state caused the function to return.

dwTimeout

Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the conditions specified by the fWaitAll parameter are not satisfied and no completion routines are queued. If dwTimeout is zero, the function tests the states of the specified objects and checks for queued completion routines and then returns immediately. If dwTimeout is INFINITE, the function's time-out interval never elapses.

fAlertable

Specifies whether the function returns when the system queues an I/O completion routine for execution by the calling thread. If TRUE, the function returns and the completion routine is executed. If FALSE, the function does not return and the completion routine is not executed.

A completion routine is queued for execution when the ReadFileEx or WriteFileEx function in which it was specified has been completed. The wait function returns and the completion routine is executed only if fAlertable is TRUE and the calling thread is the thread that initiated the read or write operation.

Return Value

If the function succeeds, the return value indicates the event that caused the function to return; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

The return value on success is one of the following values:

Value	Meaning
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + cObjects − 1)
	If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If fWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lphObjects array index of the object that satisfied the wait.
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + cObjects − 1)
	If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled, and at least one of the objects is an abandoned mutex object. If fWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lphObjects array index of an abandoned mutex object that satisfied the wait.
WAIT_IO_COMPLETION
	One or more I/O completion routines are queued for execution.
WAIT_TIMEOUT
	The time-out interval elapsed, the conditions specified by the fWaitAll parameter were not satisfied, and no completion routines are queued.
Comments

The WaitForMultipleObjectsEx function determines whether the conditions exist that satisfy the wait. If the wait is not satisfied, the calling thread enters an efficient wait state, consuming very little processor time while waiting for one of the conditions of the wait to be satisfied.

When fWaitAll is TRUE, the function's wait condition is satisfied only when the state of all objects is signaled at the same time. The function does not modify the state of the specified objects until all objects are simultaneously signaled. For example, a mutex can be signaled, but the thread does not get ownership until the other objects are also signaled. In the meantime, some other thread may get ownership of the mutex, thereby delaying satisfaction of the wait condition.

The system adjusts the state of some types of objects after the object's signaled state satisfies a wait condition. For example, the count of a semaphore object is decreased by one.

The WaitForMultipleObjectsEx function can specify handles of any of the following object types in the lphObjects array:

Object	Description
change notification	The handle is returned by the FindFirstChangeNotification function. A change notification object's state is signaled when a specified type of change occurs within a specified directory or directory tree.
console input	The handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. The object's state is signaled when there is unread input in the console's input buffer, and it is nonsignaled when the input buffer is empty.
event	The handle is returned by the CreateEvent or OpenEvent function. An event object's state is set explicitly to signaled by the SetEvent or PulseEvent function. A manual-reset event object's state must be reset explicitly to nonsignaled by the ResetEvent function. For an auto-reset event object, the wait function resets the object's state to nonsignaled before returning. Event objects are also used in overlapped operations, in which the state is set by the system.
mutex	The handle is returned by the CreateMutex or OpenMutex function. A mutex object's state is signaled when it is not owned by any thread. The wait function requests ownership of the mutex for the calling thread, changing the mutex's state to nonsignaled when ownership is granted.
process	The handle is returned by the CreateProcess or OpenProcess function. A process object's state is signaled when the process terminates.
thread	The handle is returned by the CreateProcess, CreateThread, or CreateRemoteThread function. A thread object's state is signaled when the thread terminates.
semaphore	The handle is returned by the CreateSemaphore or OpenSemaphore function. A semaphore object maintains a count between zero and some maximum value. Its state is signaled when its count is greater than zero and nonsignaled when its count is zero. If the current state is signaled, the wait function decreases the count by one.
In some circumstances, a wait function can specify a handle of a file, named pipe, or communications device as an object to wait for. However, their use for this purpose is discouraged. For more information, see Chapter 44, "Synchronization."

See Also

»MsgWaitForMultipleObjects«, »ReadFileEx«, »SleepEx«, »WaitForMultipleObjects«, »WaitForSingleObjectEx«, »WriteFileEx«


  WaitForSingleObject

DWORD WaitForSingleObject(hObject, dwTimeout)
HANDLE  hObject;   /* handle of object to wait for */
DWORD  dwTimeout;   /* time-out interval in milliseconds */

The WaitForSingleObject function returns when the specified object is in the signaled state or when the time-out interval elapses.

Parameters

hObject

Identifies the object. For a list of the object types whose handles can be specified, see the Comments section. The handle must have SYNCHRONIZE access.

dwTimeout

Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If dwTimeout is zero, the function tests the object's state and returns immediately. If dwTimeout is INFINITE, the function's time-out interval never elapses.

Return Value

If the function succeeds, the return value indicates the event that caused the function to return; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

The return value on success is one of the following values:

Value	Meaning
WAIT_OBJECT_0	The state of the specified object is signaled.
WAIT_ABANDONED	All of the following conditions are true: the specified object is a mutex object, the object's state is signaled, and the thread that owned the mutex object terminated without releasing its ownership.
WAIT_TIMEOUT	The time-out interval elapsed, and the object's state is nonsignaled.
Comments

The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters an efficient wait state. The thread consumes very little processor time while waiting for one of the conditions of the wait to be satisfied.

The system adjusts the state of some types of objects after the object's signaled state satisfies a wait condition. For example, the count of a semaphore object is decreased by one.

The WaitForSingleObject function can wait for the following objects:

Object	Description
change notification	The handle is returned by the FindFirstChangeNotification function. A change notification object's state is signaled when a specified type of change occurs within a specified directory or directory tree.
console input	The handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. The object's state is signaled when there is unread input in the console's input buffer, and it is nonsignaled when the input buffer is empty.
event	The handle is returned by the CreateEvent or OpenEvent function. An event object's state is set explicitly to signaled by the SetEvent or PulseEvent function. A manual-reset event object's state must be reset explicitly to nonsignaled by the ResetEvent function. For an auto-reset event object, the wait function resets the object's state to nonsignaled before returning. Event objects are also used in overlapped operations, in which the state is set by the system.
mutex	The handle is returned by the CreateMutex or OpenMutex function. A mutex object's state is signaled when it is not owned by any thread. The wait function requests ownership of the mutex for the calling thread, changing the mutex's state to nonsignaled when ownership is granted.
process	The handle is returned by the CreateProcess or OpenProcess function. A process object's state is signaled when the process terminates.
thread	The handle is returned by the CreateProcess, CreateThread, or CreateRemoteThread function. A thread object's state is signaled when the thread terminates.
semaphore	The handle is returned by the CreateSemaphore or OpenSemaphore function. A semaphore object maintains a count between zero and some maximum value. Its state is signaled when its count is greater than zero and nonsignaled when its count is zero. If the current state is signaled, the wait function decreases the count by one.
In some circumstances, a wait function can specify a handle of a file, named pipe, or communications device as an object to wait for. However, their use for this purpose is discouraged. For more information, see Chapter 44, "Synchronization."

See Also

»Sleep«, »WaitForMultipleObjects«, »WaitForSingleObjectEx«


  WaitForSingleObjectEx

DWORD WaitForSingleObjectEx(hObject, dwTimeout, fAlertable)
HANDLE  hObject;   /* handle of object to wait for */
DWORD  dwTimeout;   /* time-out interval in milliseconds */
BOOL  fAlertable;   /* return to execute I/O completion routine if TRUE */

The WaitForSingleObjectEx function is an extended wait function that can be used to perform an alertable wait. This enables the function to return when the system queues an input and output (I/O) completion routine to be executed by the calling thread. The function also returns when the specified object is in the signaled state or when the time-out interval elapses.

This function is available only in Microsoft® Windows NT™.

Parameters

hObject

Identifies the object. For a list of the object types whose handles can be specified, see the Comments section. The handle must have SYNCHRONIZE access.

dwTimeout

Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled and no completion routines are queued. If dwTimeout is zero, the function tests the object's state and checks for queued completion routines and then returns immediately. If dwTimeout is INFINITE, the function's time-out interval never elapses.

fAlertable

Specifies whether the function returns when the system queues an I/O completion routine for execution by the calling thread. If TRUE, the function returns and the completion routine is executed. If FALSE, the function does not return, and the completion routine is not executed.

A completion routine is queued for execution when the ReadFileEx or WriteFileEx function in which it was specified has been completed. The wait function returns and the completion routine is executed only if fAlertable is TRUE and the calling thread is the thread that initiated the read or write operation.

Return Value

If the function succeeds, the return value indicates the event that caused the function to return; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

The successful return value is one of the following:

Value	Meaning
WAIT_OBJECT_0
	The state of the specified object is signaled.
WAIT_ABANDONED
	All of the following conditions are true: the specified object is a mutex object, the object's state is signaled, and the thread that owned the mutex object terminated without releasing its ownership.
WAIT_IO_COMPLETION
	One or more I/O completion routines are queued for execution.
WAIT_TIMEOUT
	The time-out interval elapsed, and the object's state is nonsignaled.
Comments

The WaitForSingleObjectEx function determines whether the conditions exist that satisfy the wait. If the wait is not satisfied, the calling thread enters an efficient wait state, consuming very little processor time while waiting for one of the conditions of the wait to be satisfied.

The system adjusts the state of some types of objects after the object's signaled state satisfies a wait condition. For example, the count of a semaphore object is decreased by one.

The WaitForSingleObjectEx function can wait for the following objects:

Object	Description
change notification	The handle is returned by the FindFirstChangeNotification function. A change notification object's state is signaled when a specified type of change occurs within a specified directory or directory tree.
console input	The handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. The object's state is signaled when there is unread input in the console's input buffer, and it is nonsignaled when the input buffer is empty.
event	The handle is returned by the CreateEvent or OpenEvent function. An event object's state is set explicitly to signaled by the SetEvent or PulseEvent function. A manual-reset event object's state must be reset explicitly to nonsignaled by the ResetEvent function. For an auto-reset event object, the wait function resets the object's state to nonsignaled before returning. Event objects are also used in overlapped operations, in which the state is set by the system.
mutex	The handle is returned by the CreateMutex or OpenMutex function. A mutex object's state is signaled when it is not owned by any thread. The wait function requests ownership of the mutex for the calling thread, changing the mutex's state to nonsignaled when ownership is granted.
process	The handle is returned by the CreateProcess or OpenProcess function. A process object's state is signaled when the process terminates.
thread	The handle is returned by the CreateProcess, CreateThread, or CreateRemoteThread function. A thread object's state is signaled when the thread terminates.
semaphore	The handle is returned by the CreateSemaphore or OpenSemaphore function. A semaphore object maintains a count between zero and some maximum value. Its state is signaled when its count is greater than zero and nonsignaled when its count is zero. If the current state is signaled, the wait function decreases the count by one.
In some circumstances, a wait function can specify a handle of a file, named pipe, or communications device as an object to wait for. However, their use for this purpose is discouraged. For more information, see Chapter 44, "Synchronization."

See Also

»ReadFileEx«, »SleepEx«, »WaitForMultipleObjectsEx«, »WaitForSingleObject«, »WriteFileEx«


  WaitMessage

BOOL WaitMessage(VOID)

The WaitMessage function yields control to other threads when a thread has no other messages in its message queue. The WaitMessage function suspends the thread and does not return until a new message is placed in the thread's message queue.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»GetMessage«, »PeekMessage«


  WaitNamedPipe

BOOL WaitNamedPipe(lpszPipeName, dwTimeout)
LPTSTR  lpszPipeName;   /* address of name of pipe to wait for  */
DWORD  dwTimeout;   /* time-out interval in milliseconds */

The WaitNamedPipe function waits until either a time-out interval elapses or an instance of the specified named pipe is available to be connected to (that is, the pipe's server process has a pending ConnectNamedPipe operation on the pipe).

Parameters

lpszPipeName

Points to a null-terminated string that specifies the name of the named pipe. The string must include the name of the computer on which the server process is executing. A period may be used for the servername if the pipe is local. Use the following pipe name format:

\\servername\pipe\pipename

dwTimeout

Specifies the number of milliseconds the function will wait for an instance of the named pipe to be available. Use one of the following constants instead of specifying a number of milliseconds:

Value	Meaning
NMPWAIT_USE_DEFAULT_WAIT
	The time-out interval is the default value specified by the server process in the CreateNamedPipe function.
NMPWAIT_WAIT_FOREVER
	The function does not return until an instance of the named pipe is available.
Return Value

If an instance of the pipe is available before the time-out interval elapses the return value is TRUE. Otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If no instances of the specified named pipe exist, the WaitNamedPipe function returns immediately, regardless of the time-out value.

If the function succeeds, the process should use CreateFile to open a handle to the named pipe. A return value of TRUE indicates that there is at least one instance of the pipe available. A subsequent CreateFile call to the pipe can fail, because the instance was closed by the server or opened by another client.

See Also

»CallNamedPipe«, »ConnectNamedPipe«, »CreateFile«, »CreateNamedPipe«


  WaitSoundState

The WaitSoundState function has been deleted.

See Also

»Beep«, »MessageBeep«, »PlaySound«


  waveInAddBuffer

MMRESULT waveInAddBuffer(hWaveIn, lpwh, cbwh)
HWAVEIN  hWaveIn;   /* handle of input the device to send to */
LPWAVEHDR  lpwh;   /* address of structure identifying buffer  */
UINT  cbwh;   /* size of structure, in bytes */

The waveInAddBuffer function sends an input buffer to a waveform input device. When the buffer is filled, it is sent back to the application.

Parameters

hWaveIn

Identifies a handle to the waveform input device.

lpwh

Points to a WAVEHDR structure that identifies the buffer. The WAVEHDR structure has the following format:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwh

Specifies the size, in bytes, of the WAVEHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
WAVERR_UNPREPARED	The lpwh buffer hasn't been prepared.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.
Comments

The data buffer must be prepared by using the waveInPrepareHeader function before it is passed to waveInAddBuffer. The WAVEHDR structure and the data buffer pointed to by its lpData member must be allocated by using the GlobalAlloc function using the GMEM_MOVEABLE flag, and must be locked by using the GlobalLock function.

See Also

»waveInPrepareHeader«


  waveInClose

MMRESULT waveInClose(hWaveIn)
HWAVEIN  hWaveIn;   /* handle of device to close */

The waveInClose function closes the specified waveform input device.

Parameters

hWaveIn

Identifies the waveform input device. If the function is successful, the handle is no longer valid after the function returns.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
WAVERR_STILLPLAYING	There are still buffers in the queue.
Comments

If there are input buffers that have been sent by using the waveInAddBuffer function, and that haven't been returned to the application, the close operation will fail. Call the waveInReset function to mark all pending buffers as done.

See Also

»waveInOpen«, »waveInReset«


  waveInGetDevCaps

MMRESULT waveInGetDevCaps(IDDevice, lpwic, cbwic)
UINT  IDDevice;   /* identifiee of the device to query */
LPWAVEINCAPS  lpwic;   /* address of structure for capabilities  */
UINT  cbwic;   /* size of structure, in bytes */

The waveInGetDevCaps function queries a specified waveform input device to determine its capabilities.

Parameters

IDDevice

Identifies the waveform input device.

lpwic

Points to a WAVEINCAPS structure that receives information about the capabilities of the device. The WAVEINCAPS structure has the following format:

typedef struct waveincaps_tag {

    WORD  wMid;

    WORD  wPid;

    VERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    DWORD  dwFormats;

    WORD  wChannels;

} WAVEINCAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwic

Specifies the size, in bytes, of the WAVEINCAPS structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Use the waveInGetNumDevs function to determine the number of waveform input devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. The WAVE_MAPPER constant may also be used as a device identifier. Only cbwic (or fewer) bytes of information are copied to the location pointed to by lpwic. If cbwic is zero, nothing is copied, and the function returns zero.

See Also

»waveInGetNumDevs«


  waveInGetErrorText

MMRESULT waveInGetErrorText(mmrError, lpszDesc, cchDesc)
MMRESULT  mmrError;   /* error code */
LPTSTR  lpszDesc;   /* address of buffer for text description  */
UINT  cchDesc;   /* size of buffer, in characters */

The waveInGetErrorText function retrieves a text description of the error identified by the specified error number.

Parameters

mmrError

Specifies the error number.

lpszDesc

Points to a buffer that will receive a text description of the error.

cchDesc

Specifies the size, in characters, of the buffer pointed to by lpszDesc.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_BADERRNUM, indicating that the specified error number is out of range.

Comments

If the text error description is longer than the specified buffer, the description is truncated. The returned error string is always null-terminated. If cchDesc is zero, nothing is copied, and the function returns zero. All error descriptions are less than MAXERRORLENGTH characters long.


  waveInGetID

MMRESULT waveInGetID(hWaveIn, lpIDDevice)
HWAVEIN  hWaveIn;   /* handle of the device */
PUINT  lpIDDevice;   /* address of variable for device ID */

The waveInGetID function gets the device identifier for a waveform input device.

Parameters

hWaveIn

Identifies the waveform input device.

lpIDDevice

Points to a variable that receives the device identifier.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The hWaveIn parameter specifies an invalid handle.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.


  waveInGetNumDevs

UINT waveInGetNumDevs(VOID)

The waveInGetNumDevs function returns the number of waveform input devices.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of waveform input devices present in the system.

See Also

»waveInGetDevCaps«


  waveInGetPosition

MMRESULT waveInGetPosition(hWaveIn, lpmmt, cbmmt)
HWAVEIN  hWaveIn;   /* handle of device to query */
LPMMTIME  lpmmt;   /* address of structure for current position  */
UINT  cbmmt;   /* size of structure, in bytes */

The waveInGetPosition function retrieves the current input position of the specified waveform input device.

Parameters

hWaveIn

Identifies the waveform input device.

lpmmt

Points to an MMTIME structure that specifies the current input position. The MMTIME structure has the following format:

typedef struct mmtime_tag {

    WORD  wType;

    union {

        DWORD  ms;

        DWORD  sample;

        DWORD  cb;

        struct {

            BYTE  hour;

            BYTE  min;

            BYTE  sec;

            BYTE  frame;

            BYTE  fps;

            BYTE  dummy;

        } smpte;

        struct {

            DWORD  songptrpos;

        } midi;

    } u;

} MMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmmt

Specifies the size of the MMTIME structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_INVALHANDLE, indicating that the specified device handle is invalid.

Comments

Before calling waveInGetPosition, set the wType member of the MMTIME structure to indicate the time format. After calling waveInGetPosition, be sure to check the wType member to determine if the requested time format is supported. If the requested format is not supported, wType will specify an alternative format.

The position is set to zero when the device is opened or reset.


  waveInMessage

MMRESULT waveInMessage(hWaveIn, uMsg, dwParameter1, dwParameter2)
HWAVEIN  hWaveIn;   /* handle of device to send message to */
UINT  uMsg;   /* specifies message */
DWORD  dwParameter1;   /* application-defined parameter */
DWORD  dwParameter2;   /* application-defined parameter */

The waveInMessage function sends a message to a waveform input device driver.

Parameters

hWaveIn

Identifies the waveform input device to send a message to.

uMsg

Specifies the message to send.

dwParameter1

Application-defined parameter.

dwParameter2

Application-defined parameter.

Return Value

If the function succeeds, the return value is the value returned from the device driver.


  waveInOpen

MMRESULT waveInOpen(lphWaveIn, IDDevice, lpwf, dwCallback, dwCallbackInstance,
fdwOpen)
LPHWAVEIN  lphWaveIn;   /* variable to receive a handle to the input device */
UINT  IDDevice;   /* identifier of the device */
LPWAVEFORMAT  lpwf;   /* address of structure with device format */
DWORD  dwCallback;   /* address of callback or window handle */
DWORD  dwCallbackInstance;   /* instance data  */
DWORD  fdwOpen;   /* open option */

The waveInOpen function opens a specified waveform input device for recording.

Parameters

lphWaveIn

Points to a variable that will receive a handle that identifies the opened waveform input device. Use this handle to identify the device when calling other waveform input functions. This parameter may be NULL if the WAVE_FORMAT_QUERY flag is specified for fdwOpen.

IDDevice

Identifies the waveform input device to open. Use a valid device identifier or the WAVE_MAPPER flag.

If WAVE_MAPPER is specified, the function selects a waveform input device capable of recording in the given format.

lpwf

Points to a WAVEFORMAT structure that identifies the requested format for recording waveform data. The WAVEFORMAT structure has the following format:

typedef struct waveformat_tag {

    WORD  wFormatTag;

    WORD  nChannels;

    DWORD  nSamplesPerSec;

    DWORD  nAvgBytesPerSec;

    WORD  nBlockAlign;

} WAVEFORMAT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwCallback

Specifies the address of a callback function or a handle of a window to be called during waveform recording to process messages related to the progress of recording. For a description of the callback function, see the description of the »WaveProc« callback function. Specify NULL for this parameter if no callback mechanism is to be used.

dwCallbackInstance

Specifies user instance data passed to the callback function. This parameter is not used with window callbacks.

fdwOpen

Specifies flags for opening the device.

Value	Meaning
WAVE_FORMAT_QUERY	If this flag is specified, the device will be queried to determine if it supports the given format but will not actually be opened.
WAVE_ALLOWSYNC	If this flag is not specified, the device will fail to open if it is a synchronous device.
CALLBACK_WINDOW	If this flag is specified, dwCallback is assumed to be a window handle.
CALLBACK_FUNCTION	If this flag is specified, dwCallback is assumed to be a callback procedure address.
Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_ALLOCATED	The specified resource is already allocated.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
WAVERR_BADFORMAT	The system attempted to open the device with an unsupported wave format.
Comments

Use the waveInGetNumDevs function to determine the number of waveform input devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. The WAVE_MAPPER constant may also be used as a device identifier.

The WAVEFORMAT structure pointed to by lpwf may be extended to include type-specific information for certain data formats. For example, for pulse code modulated (PCM) data, an extra word is added to specify the number of bits per sample. Use the PCMWAVEFORMAT structure in this case.

If a window is chosen to receive callback information, the following messages are sent to the window-procedure function to indicate the progress of waveform input: MM_WIM_OPEN, MM_WIM_CLOSE, and MM_WIM_DATA.

If a function is chosen to receive callback information, the following messages are sent to the function to indicate the progress of waveform input: WIM_OPEN, WIM_CLOSE, WIM_DATA. The callback function must reside in a dynamic-link library (DLL).

See Also

»waveInClose«


  waveInPrepareHeader

MMRESULT waveInPrepareHeader(hWaveIn, lpwh, cbwh)
HWAVEIN  hWaveIn;   /* handle of waveform device */
LPWAVEHDR  lpwh;   /* address of structure with device information  */
UINT  cbwh;   /* size of structure, in bytes */

The waveInPrepareHeader function prepares a buffer for waveform input.

Parameters

hWaveIn

Identifies the waveform input device.

lpwh

Points to a WAVEHDR structure that identifies the buffer to be prepared. The WAVEHDR structure has the following format:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwh

Specifies the size, in bytes, of the WAVEHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.
Comments

The WAVEHDR structure and the data block pointed to by its lpData member must be allocated by using the GlobalAlloc function and the GMEM_MOVEABLE flag, and must be locked by using the GlobalLock function. Preparing a header that has already been prepared will have no effect, and the function will return zero.

See Also

»waveInUnprepareHeader«


  waveInReset

MMRESULT waveInReset(hWaveIn)
HWAVEIN  hWaveIn;   /* handle of device to reset */

The waveInReset function stops input on a given waveform input device and resets the current position to zero. All pending buffers are marked as done and returned to the application.

Parameters

hWaveIn

Identifiers the waveform input device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.
See Also

»waveInAddBuffer«, »waveInClose«, »waveInStart«, »waveInStop«


  waveInStart

MMRESULT waveInStart(hWaveIn)
HWAVEIN  hWaveIn;   /* handle of device to start */

The waveInStart function starts input on the specified waveform input device.

Parameters

hWaveIn

Identifies the waveform input device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.
Comments

Buffers are returned to the client when full or when the waveInReset function is called. (The dwBytesRecorded member in the header will contain the actual length of data.) If there are no buffers in the queue, the data is thrown away without notification to the client, and input continues.

Calling this function when input is already started has no effect, and the function returns zero.

See Also

»waveInReset«, »waveInStop«


  waveInStop

MMRESULT waveInStop(hWaveIn)
HWAVEIN  hWaveIn;   /* handle of device to stop */

The waveInStop function stops waveform input.

Parameters

hWaveIn

Identifies the waveform input device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.
Comments

If there are any buffers in the queue, the current buffer will be marked as done. (The dwBytesRecorded member in the header will contain the actual length of data.). Any empty buffers in the queue will remain there. Calling this function when input is not started has no effect, and the function returns zero.

See Also

»waveInReset«, »waveInStart«


  waveInUnprepareHeader

MMRESULT waveInUnprepareHeader(hWaveIn, lpwh, wh)
HWAVEIN  hWaveIn;   /* handle of input device */
LPWAVEHDR  lpwh;   /* address of structure identifying buffer  */
UINT  wh;   /* size of structure, in bytes */

The waveInUnprepareHeader function cleans up the preparation performed by the waveInPrepareHeader function. This function must be called after the device driver fills a data buffer and returns it to the application. You must call this function before freeing the data buffer.

Parameters

hWaveIn

Identifies the waveform input device.

lpwh

Points to a WAVEHDR structure that identifies the data buffer to be cleaned up. The WAVEHDR structure has the following format:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

wh

Specifies the size, in bytes, of the WAVEHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
WAVERR_STILLPLAYING	The lpwh buffer is still in the queue.
MMSYSERR_HANDLEBUSY	The handle hWaveIn is in use on another thread.
Comments

This function complements the waveInPrepareHeader function. You must call this function before freeing the data buffer by using the GlobalFree function. After passing a buffer to the device driver by using the waveInAddBuffer function, you must wait until the driver is finished with the buffer before calling waveInUnprepareHeader. Unpreparing a buffer that has not been prepared has no effect, and the function returns zero.

See Also

»waveInPrepareHeader«


  waveOutBreakLoop

MMRESULT waveOutBreakLoop(hWaveOut)
HWAVEOUT  hWaveOut;   /* handle of output device */

The waveOutBreakLoop function breaks a loop on a given waveform output device and allows playback to continue with the next block in the driver list.

Parameters

hWaveOut

Identifies the waveform output device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Waveform looping is controlled by the dwLoops and dwFlags members in the WAVEHDR structures passed to the device by using the waveOutWrite function. Use the WHDR_BEGINLOOP and WHDR_ENDLOOP flags in the dwFlags member to specify the beginning and ending data blocks for looping.

To loop on a single block, specify both flags for the same block. To specify the number of loops, use the dwLoops member in the WAVEHDR structure for the first block in the loop.

The blocks making up the loop are played to the end before the loop is stopped.

Calling this function when the nothing is playing or looping has no effect, and the function returns zero.

See Also

»waveOutPause«, »waveOutRestart«, »waveOutWrite«


  waveOutClose

MMRESULT waveOutClose(hWaveOut)
HWAVEOUT  hWaveOut;   /* handle of device to close */

The waveOutClose function closes the specified waveform output device.

Parameters

hWaveOut

Identifies the waveform output device. If the function succeeds, the handle is no longer valid after the function returns.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
WAVERR_STILLPLAYING	There are still buffers in the queue.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

If the device is still playing a waveform, the close operation will fail. Use the waveOutReset function to terminate waveform playback before calling waveOutClose.

See Also

»waveOutOpen«, »waveOutReset«


  waveOutGetDevCaps

MMRESULT waveOutGetDevCaps(IDDevice, lpwoc, cbwoc)
UINT  IDDevice;   /* identifier of output device */
LPWAVEOUTCAPS  lpwoc;   /* address of structure for device capabilities  */
UINT  cbwoc;   /* size of structure, in bytes */

The waveOutGetDevCaps function queries a specified waveform device to determine its capabilities.

Parameters

IDDevice

Identifies the waveform output device.

lpwoc

Points to a WAVEOUTCAPS structure that receives information about the capabilities of the device. The WAVEOUTCAPS structure has the following format:

typedef struct waveoutcaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    DWORD  dwFormats;

    WORD  wChannels;

    DWORD  dwSupport;

} WAVEOUTCAPS;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwoc

Specifies the size, in bytes, of the WAVEOUTCAPS structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device identifier is out of range.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Use the waveOutGetNumDevs function to determine the number of waveform output devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. The WAVE_MAPPER constant may also be used as a device identifier. Only cbwoc (or fewer) bytes of information are copied to the location pointed to by lpwoc. If cbwoc is zero, nothing is copied, and the function returns zero.

See Also

»waveOutGetNumDevs«


  waveOutGetErrorText

MMRESULT waveOutGetErrorText(mmrError, lpszDesc, cchDesc)
MMRESULT  mmrError;   /* error code */
LPTSTR  lpszDesc;   /* address of buffer for text description  */
UINT  cchDesc;   /* size of buffer, in characters */

The waveOutGetErrorText function retrieves a text description of the error identified by the specified error number.

Parameters

mmrError

Specifies the error number.

lpszDesc

Points to a buffer that will receive a text description of the error.

cchDesc

Specifies the size, in characters, of the buffer at lpszDesc.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be MMSYSERR_BADERRNUM, indicating that the specified error number is out of range.

Comments

If the text error description is longer than the specified buffer, the description is truncated. The returned error string is always null-terminated. If cchDesc is zero, nothing is copied and the function returns zero. All error descriptions are less than MAXERRORLENGTH characters long.


  waveOutGetID

MMRESULT waveOutGetID(hWaveOut, lpIDDevice)
HWAVEOUT  hWaveOut;   /* handle of the device */
PUINT  lpIDDevice;   /* address of buffer for device ID */

The waveOutGetID function gets the device identifier for a waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

lpIDDevice

Points to a variable that will receive the device identifier.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The hWaveOut parameter specifies an invalid handle.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.


  waveOutGetNumDevs

UINT waveOutGetNumDevs(VOID)

The waveOutGetNumDevs function retrieves the number of waveform output devices present in the system.

Parameters

This function has no parameters.

Return Value

If the function succeeds, the return value is the number of waveform output devices present in the system.

See Also

»waveOutGetDevCaps«


  waveOutGetPitch

MMRESULT waveOutGetPitch(hWaveOut, lpdwPitch)
HWAVEOUT  hWaveOut;   /* handle of output device */
LPDWORD  lpdwPitch;   /* address of buffer for pitch */

The waveOutGetPitch function queries the the current pitch setting of a waveform output device.

Parameters

hWaveOut

Identifies waveform output device.

lpdwPitch

Points to a variable that will receive the current pitch-multiplier setting. The pitch multiplier indicates the current change in pitch from the original authored setting. The pitch multiplier must be a positive value.

The pitch multiplier is specified as a fixed-point value. The high-order word of the doubleword location contains the signed integer part of the number, and the low-order word contains the fractional part. The fraction is expressed as a word in which a value of 0x8000 represents one half, and 0x4000 represents one-quarter. For example, the value 0x00010000 specifies a multiplier of 1.0 (no pitch change), and a value of 0x000F8000 specifies a multiplier of 15.5.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Changing the pitch does not change the playback rate, sample rate, or playback time. Not all devices support pitch changes. To determine whether the device supports pitch control,use the WAVECAPS_PITCH flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

See Also

»waveOutGetPlaybackRate«, »waveOutSetPitch«, »waveOutSetPlaybackRate«


  waveOutGetPlaybackRate

MMRESULT waveOutGetPlaybackRate(hWaveOut, lpdwRate)
HWAVEOUT  hWaveOut;   /* handle of output device */
LPDWORD  lpdwRate;   /* address of buffer for playback rate */

The waveOutGetPlaybackRate function queries the current playback rate setting of a waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

lpdwRate

Points to a variable that will receive the current playback rate. The playback-rate setting is a multiplier indicating the current change in playback rate from the original authored setting. The playback-rate multiplier must be a positive value.

The rate is specified as a fixed-point value. The high-order word of the doubleword location contains the signed integer part of the number, and the low-order word contains the fractional part. The fraction is expressed as a word in which a value of 0x8000 represents one-half, and 0x4000 represents one-quarter. For example, the value 0x00010000 specifies a multiplier of 1.0 (no playback rate change), and a value of 0x000F8000 specifies a multiplier of 15.5.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Changing the playback rate does not change the sample rate but does change the playback time.

Not all devices support playback-rate changes. To determine whether a device supports playback-rate changes, use the WAVECAPS_PLAYBACKRATE flag to test the dwSupport of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

See Also

»waveOutGetPitch«, »waveOutSetPitch«, »waveOutSetPlaybackRate«,


  waveOutGetPosition

MMRESULT waveOutGetPosition(hWaveOut, lpmmt, cbmmt)
HWAVEOUT  hWaveOut;   /* handle of output device */
LPMMTIME  lpmmt;   /* address of structure for current position  */
UINT  cbmmt;   /* size of structure, in bytes */

The waveOutGetPosition function retrieves the current playback position of the specified waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

lpmmt

Points to an MMTIME structure that receives the current playback position. The MMTIME structure has the following format:

typedef struct mmtime_tag {

    WORD  wType;

    union {

        DWORD  ms;

        DWORD  sample;

        DWORD  cb;

        struct {

            BYTE  hour;

            BYTE  min;

            BYTE  sec;

            BYTE  frame;

            BYTE  fps;

            BYTE  dummy;

        } smpte;

        struct {

            DWORD  songptrpos;

        } midi;

    } u;

} MMTIME;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbmmt

Specifies the size, in bytes, of the MMTIME structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Before calling waveOutGetPosition, set the wType member of the MMTIME structure to indicate the time format. After calling waveOutGetPosition, check the wType field to determine if the requested time format is supported. If the requested format is not supported, wType will specify an alternative format.

The position is set to zero when the device is opened or reset.


  waveOutGetVolume

MMRESULT waveOutGetVolume(IDDevice, lpdwVolume)
UINT  IDDevice;   /* identifier of output device */
LPDWORD  lpdwVolume;   /* address of buffer for volume */

The waveOutGetVolume function queries the current volume setting of a waveform output device.

Parameters

IDDevice

Identifies the waveform output device.

lpdwVolume

Points to a buffer that will receive the current volume setting. The low-order word of this location contains the left channel volume setting, and the high-order word contains the right channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.

If a device does not support both left and right volume control, the low-order word of the specified location contains the mono volume level.

The full 16-bit setting set with waveOutSetVolume is returned, regardless of whether the device supports the full 16 bits of volume-level control.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Not all devices support volume changes. To determine whether the device supports volume control, use the WAVECAPS_VOLUME flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

To determine whether the device supports volume control on both the left and right channels, use the WAVECAPS_LRVOLUME flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

See Also

»waveOutSetVolume«


  waveOutMessage

MMRESULT waveOutMessage(hWaveOut, uMsg, dwParameter1, dwParameter2)
HWAVEOUT  hWaveOut;   /* handle of output device */
UINT  uMsg;   /* message */
DWORD  dwParameter1;   /* application-defined parameter */
DWORD  dwParameter2;   /* application-defined parameter */

The waveOutMessage function sends a message to a waveform output device driver.

Parameters

hWaveOut

Identifies the audio device.

uMsg

Specifies the message to send.

dwParameter1

Application-defined parameter.

dwParameter2

Application-defined parameter.

Return Value

If the function succeeds, the return value is the value returned from the driver.


  waveOutOpen

MMRESULT waveOutOpen(lphWaveOut, IDDevice, lpwf, dwCallback,
dwCallbackInstance, fdwOpen)
LPHWAVEOUT  lphWaveOut;   /* variable to receive a handle of output device */
UINT  IDDevice;   /* identifier of device */
LPWAVEFORMAT  lpwf;   /* address of structure with device format */
DWORD  dwCallback;   /* address of callback or window handle */
DWORD  dwCallbackInstance;   /* instance data  */
DWORD  fdwOpen;   /* open option */

The waveOutOpen function opens a specified waveform output device for playback.

Parameters

lphWaveOut

Points to a variable that will receive a handle that identifies the opened waveform output device. Use this handle of identify the device when calling other waveform output functions. This parameter may be NULL if the WAVE_FORMAT_QUERY flag is specified for fdwOpen.

IDDevice

Identifies the waveform output device to open. Use a valid device identifier or the WAVE_MAPPER flag.

If WAVE_MAPPER is specified, the function selects a waveform output device capable of playing the given format.

lpwf

Points to a WAVEFORMAT structure that identifies the desired format for recording waveform data. The WAVEFORMAT structure has the following format:

typedef struct waveformat_tag {

    WORD  wFormatTag;

    WORD  nChannels;

    DWORD  nSamplesPerSec;

    DWORD  nAvgBytesPerSec;

    WORD  nBlockAlign;

} WAVEFORMAT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

dwCallback

Specifies the address of a callback function or a handle of a window called during waveform playback to process messages related to the progress of playback. For more information about the callback function, see the description of the »WaveProc« function. Specify NULL for this parameter if no callback mechanism is to be used.

dwCallbackInstance

Specifies user instance data passed to the callback function. This parameter is not used with window callbacks.

fdwOpen

Specifies flags for opening the device, as follows.

Value	Meaning
WAVE_FORMAT_QUERY	If this flag is specified, the device is queried to determine if it supports the given format but is not actually opened.
WAVE_ALLOWSYNC	If this flag is not specified, the device will fail to open if it is a synchronous device.
CALLBACK_WINDOW	If this flag is specified, dwCallback is assumed to be a window handle.
CALLBACK_FUNCTION	If this flag is specified, dwCallback is assumed to be a callback procedure address.
Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_BADDEVICEID	The specified device ID is out of range.
MMSYSERR_ALLOCATED	The specified resource is already allocated.
MMSYSERR_NOMEM	The system is unable to allocate or lock memory.
WAVERR_BADFORMAT	The system attempted to open with an unsupported wave format.
Comments

Use waveOutGetNumDevs to determine the number of waveform output devices present in the system. The device identifier specified by IDDevice varies from zero to one less than the number of devices present. The WAVE_MAPPER constant may also be used as a device identifier.

The WAVEFORMAT structure pointed to by lpwf may be extended to include type-specific information for certain data formats. For example, for pulse code modulated (PCM) data, an extra word is added to specify the number of bits per sample. Use the PCMWAVEFORMAT structure in this case.

If a window is chosen to receive callback information, the following messages are sent to the window procedure function to indicate the progress of waveform output: MM_WOM_OPEN, MM_WOM_CLOSE, and MM_WOM_DONE.

If a function is chosen to receive callback information, the following messages are sent to the function to indicate the progress of waveform output: WOM_OPEN, WOM_CLOSE, and WOM_DONE. The callback function must reside in a dynamic-link library (DLL).

See Also

»waveOutClose«


  waveOutPause

MMRESULT waveOutPause(hWaveOut)
HWAVEOUT  hWaveOut;   /* handle of output device */

The waveOutPause function pauses playback on a specified waveform output device. The current playback position is saved. Use the waveOutRestart function to resume playback from the current playback position.

Parameters

hWaveOut

Identifies the waveform output device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Calling this function when the output is already paused has no effect, and the function returns zero.

See Also

»waveOutRestart«, »waveOutBreakLoop«


  waveOutPrepareHeader

MMRESULT waveOutPrepareHeader(hWaveOut, lpwh, cbwh)
HWAVEOUT  hWaveOut;   /* handle of output device */
LPWAVEHDR  lpwh;   /* address of structure with buffer information  */
UINT  cbwh;   /* size of structure, in bytes */

The waveOutPrepareHeader function prepares a waveform data block for playback.

Parameters

hWaveOut

Identifies the waveform output device.

lpwh

Points to a WAVEHDR structure that identifies the data block to be prepared. The WAVEHDR structure has the following format:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwh

Specifies the size of the WAVEHDR structure in bytes.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOMEM	Unable to allocate or lock memory.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

The WAVEHDR structure and the data block pointed to by its lpData member must be allocated by using the GlobalAlloc function and the GMEM_MOVEABLE flag, and must be locked by using the GlobalLock function. Preparing a header that has already been prepared has no effect, and the function returns zero.

See Also

»waveOutUnprepareHeader«


  waveOutReset

MMRESULT waveOutReset(hWaveOut)
HWAVEOUT  hWaveOut;   /* handle of device to reset */

The waveOutReset function stops playback on a given waveform output device and resets the current position to zero. All pending playback buffers are marked as done and returned to the application.

Parameters

hWaveOut

Identifies the waveform output device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
See Also

»waveOutClose«, »waveOutWrite«


  waveOutRestart

MMRESULT waveOutRestart(hWaveOut)
HWAVEOUT  hWaveOut;   /* handle of device to restart */

The waveOutRestart function restarts a paused waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Calling this function when the output is not paused has no effect, and the function returns zero.

See Also

»waveOutBreakLoop«, »waveOutPause«


  waveOutSetPitch

MMRESULT waveOutSetPitch(hWaveOut, dwPitch)
HWAVEOUT  hWaveOut;   /* handle of device to set pitch for  */
DWORD  dwPitch;   /* new pitch */

The waveOutSetPitch function sets the pitch of a waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

dwPitch

Specifies the new pitch-multiplier setting. The pitch-multiplier setting indicates the current change in pitch from the original authored setting. The pitch multiplier must be a positive value.

The pitch multiplier is specified as a fixed-point value. The high-order word of the location contains the signed integer part of the number, and the low-order word contains the fractional part. The fraction is expressed as a word in which a value of 0x8000 represents one-half, and 0x4000 represents one-quarter. For example, the value 0x00010000 specifies a multiplier of 1.0 (no pitch change), and a value of 0x000F8000 specifies a multiplier of 15.5.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Changing the pitch does not change the playback rate or the sample rate. The playback time is also unchanged. Not all devices support pitch changes. To determine whether the device supports pitch control, use the WAVECAPS_PITCH flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

See Also

»waveOutGetPitch«, »waveOutSetPlaybackRate«, »waveOutGetPlaybackRate«


  waveOutSetPlaybackRate

MMRESULT waveOutSetPlaybackRate(hWaveOut, dwRate)
HWAVEOUT  hWaveOut;   /* handle of device to set rate for  */
DWORD  dwRate;   /* specifies the new rate */

The waveOutSetPlaybackRate function sets the playback rate of a waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

dwRate

Specifies the new playback-rate setting. The playback-rate setting is a multiplier indicating the current change in playback rate from the original authored setting. The playback rate multiplier must be a positive value.

The rate is specified as a fixed-point value. The high-order word contains the signed integer part of the number, and the low-order word contains the fractional part. The fraction is expressed as a word in which a value of 0x8000 represents one-half, and 0x4000 represents one-quarter. For example, the value 0x00010000 specifies a multiplier of 1.0 (no playback-rate change), and a value of 0x000F8000 specifies a multiplier of 15.5.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

Changing the playback rate does not change the sample rate but does change the playback time.

Not all devices support playback-rate changes. To determine whether a device supports playback-rate changes, use the WAVECAPS_PLAYBACKRATE flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

See Also

»waveOutGetPitch«, »waveOutGetPlaybackRate«, »waveOutSetPitch«


  waveOutSetVolume

MMRESULT waveOutSetVolume(IDDevice, dwVolume)
UINT  IDDevice;   /* handle of device to set volume for  */
DWORD  dwVolume;   /* new volume */

The waveOutSetVolume function sets the volume of a waveform output device.

Parameters

IDDevice

Identifies the waveform output device.

dwVolume

Specifies the new volume setting. The low-order word contains the left channel volume setting, and the high-order word contains the right channel setting. A value of 0xFFFF represents full volume, and a value of 0x0000 is silence.

If a device does not support both left and right volume control, the low-order word of dwVolume specifies the volume level, and the high-order word is ignored.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
MMSYSERR_NOTSUPPORTED	The function isn't supported.
MMSYSERR_NODRIVER	The driver was not installed.
Comments

Not all devices support volume changes. To determine whether the device supports volume control, use the WAVECAPS_VOLUME flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by the waveOutGetDevCaps function).

To determine whether the device supports volume control on both the left and right channels, use the WAVECAPS_LRVOLUME flag to test the dwSupport member of the WAVEOUTCAPS structure (filled by waveOutGetDevCaps).

Most devices don't support the full 16 bits of volume level control and will not use the high-order bits of the requested volume setting. For example, for a device that supports 4 bits of volume control, requested volume level values of 0x4000, 0x4fff, and 0x43be all produce the same physical volume setting, 0x4000. The waveOutGetVolume function returns the full 16-bit setting set by using waveOutSetVolume.

Volume settings are interpreted logarithmically. This means the perceived increase in volume is the same from 0x5000 to 0x6000 as it is from 0x4000 to 0x5000.

See Also

»waveOutGetVolume«


  waveOutUnprepareHeader

MMRESULT waveOutUnprepareHeader(hWaveOut, lpwh, cbwh)
HWAVEOUT  hWaveOut;   /* handle of wave device */
LPWAVEHDR  lpwh;   /* address of structure with buffer information  */
UINT  cbwh;   /* size of structure, in bytes */

The waveOutUnprepareHeader function cleans up the preparation performed by the waveOutPrepareHeader function. This function must be called after the device driver is finished with a data block. You must call this function before freeing the data buffer.

Parameters

hWaveOut

Identifies the waveform output device.

lpwh

Points to a WAVEHDR structure identifying the data block to be cleaned up. The WAVEHDR structure has the following format:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwh

Specifies the size, in bytes, of the WAVEHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
WAVERR_STILLPLAYING	The lpwh buffer is still in the queue.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

This function complements the waveOutPrepareHeader function. You must call this function before freeing the data buffer using the GlobalFree function. After passing a buffer to the device driver by using the waveOutWrite function, you must wait until the driver is finished with the buffer before calling waveOutUnprepareHeader.

Unpreparing a buffer that has not been prepared has no effect, and the function returns zero.

See Also

»waveOutPrepareHeader«


  waveOutWrite

MMRESULT waveOutWrite(hWaveOut, lpwh, cbwh)
HWAVEOUT  hWaveOut;   /* handle of device to write to */
LPWAVEHDR  lpwh;   /* address of structure with buffer information  */
UINT  cbwh;   /* size of structure, in bytes */

The waveOutWrite function sends a data block to the specified waveform output device.

Parameters

hWaveOut

Identifies the waveform output device.

lpwh

Points to a WAVEHDR structure containing information about the data block. The WAVEHDR structure has the following format:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cbwh

Specifies the size, in bytes, of the WAVEHDR structure.

Return Value

If the function succeeds, the return value is zero; otherwise, it is an error code, which can be one of the following:

Value	Meaning
MMSYSERR_INVALHANDLE	The specified device handle is invalid.
WAVERR_UNPREPARED	The lpwh buffer hasn't been prepared.
MMSYSERR_HANDLEBUSY	The handle hWaveOut is in use on another thread.
Comments

The data buffer must be prepared by using the waveOutPrepareHeader function before it is passed to waveOutWrite. The WAVEHDR structure and the data buffer pointed to by its lpData member must be allocated by using the GlobalAlloc function and the GMEM_MOVEABLE flag, and must be locked using the GlobalLock function. Unless the device is paused by calling the waveOutPause function, playback begins when the first data block is sent to the device.

See Also

»waveOutPause«, »waveOutPrepareHeader«, »waveOutReset«, »waveOutRestart«


  WaveProc

void CALLBACK WaveProc(hWave, uMsg, dwInstance, dwParam1, dwParam2)
HWAVE  hWave;   /* handle of waveform device */
UINT  uMsg;   /* sent message */
DWORD  dwInstance;   /* instance data */
DWORD  dwParam1;   /* application-defined parameter */
DWORD  dwParam2;   /* application-defined parameter */

The WaveProc function is an application-defined callback function that processes messages sent to a waveform device. The address of the WaveProc function can be specified as the callback-address parameter for the waveInOpen or waveOutOpen function.

Parameters

hWave

Identifies the waveform device associated with the callback.

uMsg

Specifies the message.

dwInstance

Specifies the user instance data specified with waveInOpen or waveOutOpen.

dwParam1

Specifies an application-defined parameter for the message.

dwParam2

Specifies an application-defined parameter for the message.

Return Value

This function does not return a value.

Comments

WaveProc is a placeholder for the application-defined function name.

There are several differences between WaveProc functions under Windows NT and under Windows 3.1 :

•	Under Windows 3.1, a WaveProc function is called at interrupt time. The call to a WaveProc function occurs on a separate thread under Windows NT.

•	Under Windows 3.1, a WaveProc function has to be in a dynamic link library. Under Windows NT, there is no such restriction.

•	Under Windows 3.1, a WaveProc function must be exported in a .DEF file. Under Windows NT, that is not necessary.

If source code must be compatible with Windows 3.1, it should follow the Windows 3.1 rules as noted briefly above and specified more fully in the Windows 3.1 documentation.

One other item should be noted carefully. There is a limited set of APIs that a Windows 3.1 WaveProc function may call. In Win32, that strict limitation has been removed. However, it is strongly recommended that a Windows NT WaveProc function restrain its calls to APIs in the same set, with the addition of the API SetEvent. Here is the Windows NT recommended list:

EnterCriticalSection	PostThreadMessage
LeaveCriticalSection	SetEvent
midiOutLongMsg	timeGetSystemTime
midiOutShortMsg	timeGetTime
OutputDebugStr	timeKillEvent
PostMessage	timeSetEvent
If an application's WaveProc function does stray from this list, it should be careful not to call APIs that take a long time to complete.

A WaveProc function should not call other Wave* APIs; if it does, it will probably deadlock.

If a Win32 WaveProc shares data with other code, a Critical Section or similar mutual exclusion mechanism should be used to protect the integrity of the data.


  WideCharToMultiByte

int WideCharToMultiByte(uCodePage, dwFlags, lpWideCharStr, cchWideChar,
lpMultiByteStr, cchMultiByte, lpDefaultChar, lpfUsedDefaultChar)
UINT  uCodePage;   /* code page */
DWORD  dwFlags;   /* performance and mapping flags */
LPCWSTR  lpWideCharStr;   /* address of wide-character string */
int  cchWideChar;   /* number of characters in string */
LPSTR  lpMultiByteStr;   /* address of buffer for new string */
int  cchMultiByte;   /* size of buffer */
LPSTR  lpDefaultChar;   /* address of default for unmappable characters */
LPBOOL  lpfUsedDefaultChar;   /* address of flag set when default char. used */

The WideCharToMultiByte function maps a wide-character string to a new character string. The new character string is not necessarily from a multibyte character set.

Parameters

uCodePage

Specifies the code page to be used to perform the conversion. This parameter can be given the value of any codepage that is installed or available in the system. The following two values have special meanings:

Value	Meaning
CP_ACP	ANSI code page
CP_OEMCP	OEM code page
dwFlags

Specifies a flag affecting the handling of unmapped characters. The function performs more quickly when this flag is not set.

This parameter can be WC_COMPOSITECHECK. When WC_COMPOSITECHECK is specified, the function converts composite characters to precomposed characters. In composite characters, the base character and the corresponding nonspacing character have different character values. In precomposed characters, the base character and the corresponding nonspacing character have a single character value. (A base character is a character followed by a nonspacing character. For example, in the character è, the e is the base character and the accent mark is the nonspacing character.)

When an application specifies WC_COMPOSITECHECK, it can use the following flags to customize the conversion to precomposed characters. These flags determine the function's behavior when there is no precomposed mapping for a base−nonspace character combination in the wide-character string.

Value	Meaning
WC_DISCARDNS	Discard nonspacing characters.
WC_SEPCHARS	Generate separate characters. This is the default behavior.
WC_DEFAULTCHAR	Replace exceptions with the default character.
lpWideCharStr

Points to the wide-character string to be converted.

cchWideChar

Specifies the number of characters in the string pointed to by the lpWideCharStr parameter. If this value is −1, the string is assumed to be null terminated and the length is calculated automatically.

lpMultiByteStr

Points to the buffer to receive the translated string.

cchMultiByte

Specifies the size in bytes of the buffer pointed to by the lpMultiByteStr parameter. If this value is zero, the function returns the number of bytes required for the buffer. (In this case, the lpMultiByteStr buffer is not used.)

lpDefaultChar

Points to the character used if a wide character cannot be represented in the specified code page. If this parameter is NULL, a system default value is used. The function is faster when both lpDefaultChar and lpfUsedDefaultChar are NULL.

lpfUsedDefaultChar

Points to a flag that indicates whether a default character was used. This flag is set to TRUE if one or more wide characters in the source string cannot be represented in the specified code page. Otherwise, it is set to FALSE. This parameter may be NULL. The function is faster when both lpDefaultChar and lpfUsedDefaultChar are NULL.

Return Value

If the function succeeds, and cchMultiByte is non-zero, the return value is the number of bytes written to the buffer pointed to by lpMultiByteStr.

If the function succeeds, and cchMultiByte is zero, the return value is the required size, in bytes, for a buffer that can receive the translated string.

If the function fails, the return value is FALSE. Call GetLastError for extended error information.

Comments

The lpMultiByteStr and lpWideCharStr pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

An application can use the lpDefaultChar parameter to change the default character used for the conversion.

The function is faster when both lpDefaultChar and lpfUsedDefaultChar are NULL.

See Also

»MultiByteToWideChar«


  WidenPath

BOOL WidenPath(hdc)
HDC  hdc;   /* handle of device context */

The WidenPath function redefines the current path as the area that would be painted if the path were stroked using the pen currently selected into the given device context.

Parameters

hdc

Identifies a device context that contains a closed path.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. Use the GetLastError function to get extended error information, which can be one of the following:

ERROR_CAN_NOT_COMPLETE
ERROR_INVALID_PARAMETER
ERROR_NOT_ENOUGH_MEMORY

Comments

This function is successful only if the current pen is a geometric pen created by the ExtCreatePen function, or if the pen is created with the CreatePen function and has a width, in device units, of more than one.

The device context identified by the hdc parameter must contain a closed path.

Any Bézier curves in the path are converted to sequences of straight lines approximating the widened curves. As such, no Bézier curves remain in the path after WidenPath is called.

See Also

»BeginPath«, »EndPath«, »SetMiterLimit«


  WindowFromDC

HWND WindowFromDC(hdc)
HDC  hdc;   /* handle of window */

The WindowFromDC function returns the handle of the window associated with the given display device context (DC). Output functions that use the given DC draw into this window.

Parameters

hdc

Identifies the DC from which a handle for the associated window is to be retrieved.

Return Value

If the function succeeds, the return value is the handle of the window associated with the given display DC; otherwise, the return value is NULL.

See Also

»GetDC«, »GetDCEx«, »GetWindowDC«


  WindowFromPoint

HWND WindowFromPoint(pt)
POINT  pt;   /* structure with point */

The WindowFromPoint function retrieves the handle of the window that contains the specified point.

Parameters

pt

Specifies a POINT structure that defines the point to be checked. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is the handle of the window that contains the point. If no window exists at the given point, the return value is NULL.

Comments

The WindowFromPoint function does not retrieve the handle of a hidden or disabled window, even if the point is within the window. An application should use the ChildWindowFromPoint function for a nonrestrictive search.

See Also

»ChildWindowFromPoint«


  WindowProc

LRESULT CALLBACK WindowProc(hwnd, uMsg, wParam, lParam)
HWND  hwnd;   /* handle of window */
UINT  uMsg;   /* message identifier */
WPARAM  wParam;   /* first message parameter */
LPARAM  lParam;   /* second message parameter */

The WindowProc function is an application-defined callback function that processes messages sent to a window.

Parameters

hwnd

Identifies the window.

uMsg

Specifies the message.

wParam

Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.

lParam

Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.

Return Value

The function should return the result of the message processing. The actual return value depends on the message sent.

Comments

WindowProc is a placeholder for the application-defined function name.

See Also

»CallWindowProc«, »DefWindowProc«, »RegisterClass«


  WinExec

UINT WinExec(lpszCmdLine, fuCmdShow)
LPCSTR  lpszCmdLine;   /* address of command line  */
UINT  fuCmdShow;   /* window style for new app */

The WinExec function runs the specified application.

This function is provided for compatibility with earlier versions of Windows, For Win32 applications, use the CreateProcess function.

Parameters

lpszCmdLine

Points to a null-terminated character string that contains the command line (filename plus optional parameters) for the application to be executed. If the name of the executable file in the lpszCmdLine string does not contain a directory path, Windows searches for the executable file in this sequence:

1.	The directory from which the application loaded.

2.	The current directory.

3.	The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.

4.	The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.

5.	The directories listed in the PATH environment variable.

fuCmdShow

Specifies how a Windows-based application window is to be shown and is used to supply the wShowWindow member of the STARTUPINFO parameter to CreateProcess. See the description of the nCmdShow parameter of the »ShowWindow« function for a list of the acceptable values. For a non-Windows-based application, the PIF file, if any, for the application determines the window state.

Return Value

If the function succeeds, the return value is greater than 31; otherwise, it is one of the following error values:

Value	Meaning
0	The system is out of memory or resources.
ERROR_FILE_NOT_FOUND	The specified file was not found.
ERROR_PATH_NOT_FOUND	The specified path was not found.
ERROR_BAD_FORMAT	The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
Comments

Win32 applications should use the CreateProcess function rather than this function. The WinExec function exists in Win32 to provide compatibility with earlier versions of Windows.

The WinExec function is implemented in the Win32 API by a call to the CreateProcess function. The following list shows how the appropriate CreateProcess parameters are formed:

CreateProcess parameter	Value
lpszImageName	NULL
lpszCommandLine	WinExec lpszCmdLine parameter
lpsaProc	NULL
lpsaThread	NULL
fInheritHandles	FALSE
fdwCreate	0
lpvEnvironment	NULL
lpszCurDir	NULL
lpsi	The structure is initialized to zero. The cb member is set to the size of the structure, and the wShowWindow member is set to the value of the WinExec fuCmdShow parameter.
lppi->hProcess	The handle is immediately closed.
lppi->hThread	The handle is immediately closed.
In Win32, the WinExec function returns when the launched process calls the GetMessage function or a timeout limit is reached. To avoid waiting on the timeout delay, call the GetMessage function as soon as possible in any process launched by a call to WinExec.

See Also

»CreateProcess«, »GetSystemDirectory«, »GetWindowsDirectory«, »ShowWindow«


  WinHelp

BOOL WinHelp(hwnd, lpszHelpFile, fuCommand, dwData)
HWND  hwnd;   /* handle of window requesting Help */
LPCTSTR  lpszHelpFile;   /* address of directory-path string */
UINT  fuCommand;   /* type of Help */
DWORD  dwData;   /* additional data */

The WinHelp function starts the Windows Help application (WINHLP32.EXE) and passes additional data indicating the nature of the help requested by the application. The application specifies the name and, where required, the directory path of the Help file to display.

Parameters

hwnd

Identifies the window requesting Help. The WinHelp function uses this handle to keep track of which applications have requested Help.

lpszHelpFile

Points to a null-terminated string containing the path, if necessary, and the name of the Help file that the Help application is to display.

The filename may be followed by an angle bracket (>) and the name of a secondary window if the topic is to be displayed in a secondary window rather than in the primary window. The name of the secondary window must have been defined in the [WINDOWS] section of the Help project (.HPJ) file.

fuCommand

Specifies the type of help requested. For a list of possible values and how they affect the value to place in the dwData parameter, see the following Comments section.

dwData

Specifies additional data. The value used depends on the value of the fuCommand parameter. For a list of possible values, see the following Comments section.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Before closing the window that requested Help, the application must call WinHelp with the fuCommand parameter set to HELP_QUIT. Until all applications have done this, Windows Help does not terminate.

The following table shows the possible values for the fuCommand parameter and the corresponding formats of the dwData parameter:

fuCommand	dwData	Action
HELP_COMMAND	Long pointer to a string containing the name of a Help macro to be executed.	Executes a Help macro.
HELP_CONTENTS	Ignored; applications should set to 0L.	Displays the Help contents topic as defined by the Contents option in the [OPTIONS] section of the .HPJ file.
HELP_CONTEXT	Unsigned long integer containing the context number for the topic.	Displays Help for a particular topic identified by a context number that has been defined in the [MAP] section of the .HPJ file.
HELP_CONTEXTPOPUP	Unsigned long integer containing the context number for a topic.	Displays in a pop-up window Help for a particular topic identified by a context number that has been defined in the [MAP] section of the .HPJ file.
HELP_FORCEFILE	Ignored; applications should set to 0L.	Ensures that WinHelp is displaying the correct Help file. If the correct Help file is currently displayed, there is no action. If the incorrect Help file is displayed, WinHelp opens the correct file.
HELP_HELPONHELP	Ignored; applications should set to 0L.	Displays the Contents topic of the designated Using Help file.
HELP_INDEX	Ignored; applications should set to 0L.	Displays the Help Contents topic as defined by the Index option in the [OPTIONS] section of the .HPJ file.
HELP_KEY	Long pointer to a string containing a keyword for the desired topic.	Displays the topic found in the keyword list that matches the keyword passed in the dwData parameter, if there is one exact match. If there is more than one match, displays the Search dialog box with the topics listed in the Go To list box.
HELP_MULTIKEY	Long pointer to the MULTIKEYHELP structure, as defined in WINDOWS.H.This structure specifies the table footnote character and the keyword.	Displays the Help topic identified by a keyword in an alternative keyword table.
HELP_PARTIALKEY	Long pointer to a string containing a keyword for the desired topic.	Displays the topic found in the keyword list that matches the keyword passed in the dwData parameter, if there is one exact match. If there is more than one match, displays the Search dialog box with the topics listed in the Go To list box. If there is no match, displays the Search dialog box. To bring up the Search dialog box without passing a keyword (the third result), you should use a long pointer to an empty string.
HELP_QUIT	Ignored; applications should set to 0L.	Informs the Help application that Help is no longer needed. If no other applications have asked for Help, Windows closes the Help application.
HELP_SETCONTENTS	Unsigned long integer containing the context number for the topic to be designated as the Contents topic.	Determines the Contents topic Help is to display when a user presses the F1 key.
HELP_SETINDEX	Unsigned long integer containing the context number for the topic to be designated as the Index topic.	Determines the topic WinHelp is to display when a user selects Index.
HELP_SETWINPOS	Long pointer to the HELPWININFO structure, as defined in WINDOWS.H.This structure specifies the size and position of either a primary or secondary Help window.	Displays the Help window, if it is minimized or in memory, and positions it according to the data passed.


  WinMain

int WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HINSTANCE  hInstance;   /* handle of current instance */
HINSTANCE  hPrevInstance;   /* handle of previous instance */
LPSTR  lpszCmdLine;   /* address of command line  */
int  nCmdShow;   /* show state of window */

The WinMain function is called by the system as the initial entry point for a Windows-based application.

Parameters

hInstance

Identifies the current instance of the application.

hPrevInstance

Identifies the previous instance of the application. For a Windows NT application, this parameter is always NULL.

lpszCmdLine

Points to a null-terminated string specifying the command line for the application.

nCmdShow

Specifies how the window is to be shown. This parameter can be one of the following values:

Value	Meaning
SW_HIDE	Hides the window and activates another window.
SW_MINIMIZE	Minimizes the specified window and activates the top-level window in the system's list.
SW_RESTORE	Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position (same as SW_SHOWNORMAL).
SW_SHOW	Activates a window and displays it in its current size and position.
SW_SHOWMAXIMIZED	Activates a window and displays it as a maximized window.
SW_SHOWMINIMIZED	Activates a window and displays it as an icon.
SW_SHOWMINNOACTIVE	Displays a window as an icon. The active window remains active.
SW_SHOWNA	Displays a window in its current state. The active window remains active.
SW_SHOWNOACTIVATE	Displays a window in its most recent size and position. The active window remains active.
SW_SHOWNORMAL	Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position (same as SW_RESTORE).
Return Value

If the function succeeds, the return value is the return value of the PostQuitMessage function. If the function terminates before entering the message loop, the return value is NULL.

Comments

The WinMain function initializes the application and then performs a message retrieval-and-dispatch loop that is the top-level control structure for the remainder of the application's execution. The loop terminates when a WM_QUIT message is received. Then WinMain exits the application, returning the value passed by the PostQuitMessage function.

See Also

»DispatchMessage«, »GetMessage«, »PostQuitMessage«, »TranslateMessage«


  WNetAddConnection

DWORD WNetAddConnection(lpszRemoteName, lpszPassword, lpszLocalName)
LPTSTR  lpszRemoteName;   /* address of network device name */
LPTSTR  lpszPassword;   /* address of password */
LPTSTR  lpszLocalName;   /* address of local device name */

The WNetAddConnection function enables the calling application to connect a local device to a network resource. A successful connection is persistent, meaning that Windows automatically restores the connection during subsequent logon operations.

This function is provided for compatibility with earlier versions of Microsoft Windows. For new applications, use the WNetAddConnection2 function.

Parameters

lpszRemoteName

Points to a null-terminated string that specifies the network resource to connect to.

lpszPassword

Points to a null-terminated string that specifies the password to be used to make a connection. This is usually the password associated with the current user.

If lpszPassword is NULL, the default password is used. If the string is empty, no password is used.

lpszLocalName

Points to a null-terminated string that specifies the name of a local device to be redirected, such as F: or LPT1. The case of the characters in the string is not important. If the string is NULL, a connection to the network resource is made without redirecting the local device.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, it is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_ACCESS_DENIED	Access is denied.
ERROR_ALREADY_ASSIGNED	The device specified in the lpszLocalName parameter is already connected.
ERROR_BAD_DEV_TYPE	The device type and the resource type do not match.
ERROR_BAD_DEVICE	The value specified in lpszLocalName is invalid.
ERROR_BAD_NET_NAME	The value specified in lpszRemoteName is not valid or cannot be located.
ERROR_BAD_PROFILE	The user profile is in an incorrect format.
ERROR_CANNOT_OPEN_PROFILE	The system is unable to open the user profile to process persistent connections.
ERROR_DEVICE_ALREADY_REMEMBERED	An entry for the device specified in lpszLocalName is already in the user profile.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_INVALID_PASSWORD	The specified password is invalid.
ERROR_NO_NET_OR_BAD_PATH	The operation cannot be performed, because either a network component is not started or the specified name cannot be used.
ERROR_NO_NETWORK	The network is not present.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

See Also

»WNetAddConnection2«, »WNetCancelConnection«, »WNetCancelConnection2«, »WNetGetConnection«


  WNetAddConnection2

DWORD WNetAddConnection2(lpNetResource, lpszPassword, lpszUserName, fdwConnection)
LPNETRESOURCE  lpNetResource;   /* address of net resource */
LPTSTR  lpszPassword;   /* address of password */
LPTSTR  lpszUserName;   /* address of user name  */
DWORD  fdwConnection;   /* connection-type flags */

The WNetAddConnection2 function enables the caller to connect a local device to a network resource. This function supersedes the WNetAddConnection function.

Parameters

lpNetResource

Points to an NETRESOURCE structure that specifies the network resource to connect to. This structure has the following format:

typedef struct _NETRESOURCE {  /* nr */

    DWORD  dwScope;

    DWORD  dwType;

    DWORD  dwDisplayType;

    DWORD  dwUsage;

    LPTSTR lpLocalName;

    LPTSTR lpRemoteName;

    LPTSTR lpComment;

    LPTSTR lpProvider;

} NETRESOURCE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

The following members must be set in the NETRESOURCE structure:

Member	Description
lpRemoteName	Points to a null-terminated string that specifies the network resource to connect to.
lpLocalName	Points to a null-terminated string that specifies the name of a local device to be redirected, such as F: or LPT1. The case of the characters in the string is not important. If the string is NULL, a connection to the network resource is made without redirecting the local device.
lpProvider	Points to a null-terminated string that specifies the network provider to connect to. If lpProvider is NULL or points to an empty string, Windows attempts to determine the correct provider.
	An application should set lpProvider only when it must specify a network provider. Otherwise, the application should allow Windows to determine which provider the network name maps to.
	If lpProvider is not NULL, Windows attempts to make a connection only to the named provider.
dwType	Specifies the type of resource with which to connect. It can be RESOURCETYPE_DISK, RESOURCETYPE_PRINT, or RESOURCETYPE_ANY. The value RESOURCETYPE_ANY is used when the resource type is unimportant or unknown.
The other members of the NETRESOURCE structure are ignored.

lpszPassword

Points to a null-terminated string that specifies the password to be used to make the connection. This is usually the password associated with the current user.

If lpszPassword is NULL, the default password is used. If the string is empty, no password is used.

lpszUserName

Points to a null-terminated string that specifies the user name used to make the connection. If lpszUserName is NULL, the default user security context for the process is applied. Specify NULL when the user wants to connect to a resource, but has a different user name or account assigned for that resource. This name represents a security context and is provider-specific.

fdwConnection

Specifies a bitmask for the connection type. The following values are defined:

Value	Meaning
0	No information about the connection is stored.
CONNECT_UPDATE_PROFILE	Information about the connection is stored in the user profile. If the connection is successful, Windows automatically restores this connection during subsequent logon operations.
Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, the return value is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_ACCESS_DENIED	Access is denied.
ERROR_ALREADY_ASSIGNED	The device specified in the lpszLocalName parameter is already connected.
ERROR_BAD_DEV_TYPE	The device type and the resource type do not match.
ERROR_BAD_DEVICE	The value specified in lpszLocalName is invalid.
ERROR_BAD_NET_NAME	The value specified in lpszRemoteName is not valid or cannot be located.
ERROR_BAD_PROFILE	The user profile is in an incorrect format.
ERROR_CANNOT_OPEN_PROFILE	The system is unable to open the user profile to process persistent connections.
ERROR_DEVICE_ALREADY_REMEMBERED	An entry for the device specified in lpszLocalName is already in the user profile.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_INVALID_PASSWORD	The specified password is invalid.
ERROR_NO_NET_OR_BAD_PATH	The operation cannot be performed, because either a network component is not started or the specified name cannot be used.
ERROR_NO_NETWORK	The network is not present.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

See Also

»WNetAddConnection«, »WNetAddConnection2«, »WNetCancelConnection2«, »WNetGetConnection«


  WNetCancelConnection

DWORD WNetCancelConnection(lpszName, fForce)
LPTSTR  lpszName;   /* address of resource name to disconnect  */
BOOL  fForce;   /* flag for unconditional disconnect */

The WNetCancelConnection function breaks an existing network connection.

This function is provided for compatibility with earlier versions of Microsoft Windows. For new applications, use the WNetCancelConnection2 function.

Parameters

lpszName

Points to a null-terminated string that specifies the name of either the redirected local device or the remote network resource to disconnect from. When lpszName specifies a redirected local device, only the specified redirection is broken, and Windows will not restore the connection during subsequent logon operations. When lpszName specifies a remote network resource, the connection to that remote network resource is broken.

fForce

Specifies whether the disconnection is to occur even if there are open files or jobs on the connection. If fForce is FALSE, the function fails if there are open files or jobs.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, the return value is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_BAD_PROFILE	The user profile is in an incorrect format.
ERROR_CANNOT_OPEN_PROFILE	The system is unable to open the user profile to process persistent connections.
ERROR_DEVICE_IN_USE	The device is in use by an active process and cannot be disconnected.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_NOT_CONNECTED	The name specified by the lpszName parameter is not a redirected device, or the system is not currently connected to the device specified by the lpszName parameter.
ERROR_OPEN_FILES	There are open files and the fForce parameter is FALSE.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

See Also

»WNetAddConnection«, »WNetAddConnection2«, »WNetCancelConnection2«, »WNetGetConnection«


  WNetCancelConnection2

DWORD WNetCancelConnection2(lpszName, fdwConnection, fForce)
LPTSTR  lpszName;   /* address of resource name to disconnect */
DWORD  fdwConnection;   /* connection-type flags */
BOOL  fForce;   /* flag for unconditional disconnect */

The WNetCancelConnection2 function breaks an existing network connection. It can also be used to remove remembered network connections that are not currently connected.

Parameters

lpszName

Points to a null-terminated string that specifies the name of either the redirected local device or the remote network resource to disconnect from. If lpszName specifies a redirected local resource, only the specified redirection is broken; otherwise, all connections to the remote network resource are broken.

fdwConnection

Specifies a bitmask for the connection type. The following values are defined:

Value	Meaning
0	No information about the connection is stored.
CONNECT_UPDATE_PROFILE	The user profile is updated with the information that this is no longer a persistent connection. Windows will not restore this connection during subsequent logon operations. Disconnecting resources using remote names has no effect on persistent connections.
fForce

Specifies whether the disconnection should occur even if there are open files or jobs on the connection. If fForce is FALSE, the function fails if there are open files or jobs.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, the return value is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_BAD_PROFILE	The user profile is in an incorrect format.
ERROR_CANNOT_OPEN_PROFILE	The system is unable to open the user profile to process persistent connections.
ERROR_DEVICE_IN_USE	The device is in use by an active process and cannot be disconnected.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_NOT_CONNECTED	The name specified by the lpszName parameter is not a redirected device, or the system is not currently connected to the device specified by the lpszName parameter.
ERROR_OPEN_FILES	There are open files and the fForce parameter is FALSE.
See Also

»WNetAddConnection«, »WNetAddConnection2«, »WNetCancelConnection«, »WNetGetConnection«


  WNetCloseEnum

DWORD WNetCloseEnum(hEnum)
HANDLE  hEnum;   /* handle of enumeration */

The WNetCloseEnum function ends a network-resource enumeration started by the WNetOpenEnum function.

Parameters

hEnum

Identifies an enumeration instance. This handle must have been returned by the WNetOpenEnum function.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, the return value is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_NO_NETWORK	Network is not present. This condition is tested before the handle specified in the hEnum parameter is tested for validity.
ERROR_INVALID_HANDLE	hEnum is not a valid handle.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

See Also

»WNetEnumResource«, »WNetOpenEnum«


  WNetConnectionDialog

DWORD WNetConnectionDialog(hwnd, fdwResourceType)
HWND  hwnd;   /* handle of window owning dialog box */
DWORD  fdwResourceType;   /* resource type to allow connections to */

The WNetConnectionDialog function starts a general browsing dialog box for connecting to network resources.

Parameters

hwnd

Identifies the owning window.

fdwResourceType

Specifies the resource type to allow connections to. This parameter can be one of the following values:

Value	Meaning
RESOURCETYPE_DISK	Connect to disk resources.
Return Value

If the function completes successfully, the return value is NO_ERROR.

If the user cancels out of the dialog, the return value is 0xFFFFFFFF.

In all other cases, the function returns an error code. The same error code can be obtained by calling GetLastError. Possible error codes for the function include :

Value	Meaning
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_INVALID_PASSWORD	The specified password is invalid.
ERROR_NO_NETWORK	No network is present.
ERROR_NOT_ENOUGH_MEMORY	There is insufficient memory to start the dialog box.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

Comments

If the user chooses OK in the dialog box, the requested network connections will have been performed when this function returns.

If the function attempts to make a connection and the provider returns ERROR_INVALID_PASSWORD, Windows prompts the user to enter a password and uses the new password in another attempt to make the connection.

See Also

»WNetAddConnection2«, »WNetCancelConnection2«, »WNetDisconnectDialog«


  WNetDisconnectDialog

DWORD WNetDisconnectDialog(hwnd, fdwResourceType)
HWND  hwnd;   /* handle of window owning dialog box */
DWORD  fdwResourceType;   /* resource type to disconnect from */

The WNetDisconnectDialog function starts a general browsing dialog box for disconnecting from network resources.

Parameters

hwnd

Specifies the handle of the owning window.

fdwResourceType

Specifies the resource type to disconnect from. This parameter may be may be one of the following values:

Value	Meaning
RESOURCETYPE_DISK	Disconnect from disk resources.
RESOURCETYPE_PRINT	Disconnect from print resources.
Return Value

If the function completes successfully, the return value is NO_ERROR.

If the user cancels out of the dialog, the return value is 0xFFFFFFFF.

In all other cases, the function returns an error code. The same error code can be obtained by calling GetLastError. Possible error codes for the function include :

Value	Meaning
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_NO_NETWORK	No network is present.
ERROR_NOT_ENOUGH_MEMORY	There is insufficient memory to start the dialog box.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

Comments

If the user chooses OK in the dialog box, the requested network disconnections will have been performed when this function returns.

See Also

»WNetAddConnection2«, »WNetCancelConnection2«, »WNetConnectionDialog«


  WNetEnumResource

DWORD WNetEnumResource(hEnum, lpcEntries, lpvBuffer, lpcbBuffer)
HANDLE  hEnum;   /* handle of enumeration */
LPDWORD  lpcEntries;   /* address of entries to list */
LPVOID  lpvBuffer;   /* address of buffer for results */
LPDWORD  lpcbBuffer;   /* address of buffer-size variable */

The WNetEnumResource function continues a network-resource enumeration started by the WNetOpenEnum function.

Parameters

hEnum

Identifies an enumeration instance. This handle must have been returned by the WNetOpenEnum function.

lpcEntries

Points to a variable specifying the number of entries requested. If the number requested is 0xFFFFFFFF, the function returns as many entries as possible.

When the function finishes successfully, the variable pointed to by the lpcEntries parameter contains the number of entries actually read.

lpvBuffer

Points to the buffer to receive the enumeration results, which are returned as an array of NETRESOURCE structures. The buffer is valid until the next call using the handle given by the hEnum parameter. The order of the NETRESOURCE structures in the array is not predictable.

lpcbBuffer

Points to a variable that specifies the size, in bytes, of the lpvBuffer parameter. If the buffer is too small to receive even one entry, this variable receives the required size of the buffer.

Return Value

If the function succeeds, the return value is one of the following values:

Value	Meaning
NO_ERROR	The enumeration succeeded, and the buffer contains the requested data. The calling application can continue to call the WNetEnumResource function to complete the enumeration.
ERROR_NO_MORE_ITEMS	There are no more entries. The buffer contents are undefined.
If the return value is not NO_ERROR or ERROR_NO_MORE_ITEMS, it is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_MORE_DATA	The buffer is too small for even one entry.
ERROR_INVALID_HANDLE	The handle given by the hEnum parameter is not valid.
ERROR_NO_NETWORK	No network is present. This condition is tested before hEnum is tested for validity.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

Comments

An application cannot set the lpvBuffer parameter to NULL and retrieve the required buffer size from the lpcbBuffer parameter. Instead, the application should allocate a buffer of a reasonable size (16K is typical) and use the value of lpcbBuffer for error-detection.

See Also

»WNetCloseEnum«, »WNetOpenEnum«


  WNetGetConnection

DWORD WNetGetConnection(lpszLocalName, lpszRemoteName, lpcchBuffer)
LPTSTR  lpszLocalName;   /* address of local name */
LPTSTR  lpszRemoteName;   /* address of buffer for remote name  */
LPDWORD  lpcchBuffer;   /* address of buffer size, in characters */

The WNetGetConnection function retrieves the name of the network resource associated with a local device.

Parameters

lpszLocalName

Points to a null-terminated string that specifies the name of the local device to get the network name for.

lpszRemoteName

Points to a buffer that will receive the null-terminated remote name used to make the connection.

lpcchBuffer

Points to a variable that specifies the size, in characters, of the buffer pointed to by the lpszRemoteName parameter. If the function fails because the buffer is not big enough, this variable returns the required buffer size.

Return Value

If the function succeeds,the return value is NO_ERROR. Otherwise, it is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_BAD_DEVICE	The string pointed to by lpszLocalName is invalid.
ERROR_NOT_CONNECTED	The device specified by lpszLocalName is not redirected.
ERROR_MORE_DATA	The buffer is too small. The lpcchBuffer parameter points to a variable that contains the required buffer size.
ERROR_CONNECTION_UNAVAIL	The device is not currently connected, but it is a remembered (persistent) connection.
ERROR_NO_NETWORK	No network is present.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_NO_NET_OR_BAD_PATH	None of the providers recognized this local name as having a connection. However, the network is not available for at least one provider to whom the connection may belong.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

See Also

»WNetGetLastError«, »WNetGetUser«


  WNetGetLastError

DWORD WNetGetLastError(lpdwErrorCode, lpszDescription, cchDescription, lpszName,
cchName)
LPDWORD  lpdwErrorCode;   /* address of error code */
LPTSTR  lpszDescription;   /* address of string describing error */
DWORD  cchDescription;   /* size of the description buffer, in characters */
LPTSTR  lpszName;   /* address of buffer for provider name  */
DWORD  cchName;   /* size of the provider-name buffer */

The WNetGetLastError function retrieves the most recent extended error code set by a Windows network function.

Parameters

lpdwErrorCode

Points to the variable that will receive the error code reported by the network provider. This error code is network-provider specific.

lpszDescription

Points to the buffer that will receive the null-terminated string describing the error.

cchDescription

Specifies the size, in characters, of the buffer pointed to by the lpszDescription parameter. If the buffer is too small for the error string, the string is truncated, but still null-terminated. A buffer of at least 256 characters is recommended.

lpszName

Points to the buffer that will receive the null-terminated string identifying the network provider that raised the error.

cchName

Specifies the size, in characters, of the buffer pointed to by the lpszName parameter. If the buffer is too small for the error string, the string is truncated, but still null-terminated.

Return Value

If the function successfully obtains the last error reported by the provider, the return value is NO_ERROR.

If the caller supplies an invalid buffer, the return value is ERROR_INVALID_ADDRESS.

Comments

The WNetGetLastError function is used to retrieve errors that are specific to a network provider. It should be called when a Windows network function (or the GetLastError function) returns ERROR_EXTENDED_ERROR. Like the GetLastError function, this function returns extended error information, which is maintained on a per-thread basis. Unlike GetLastError, this function can also return a string for reporting errors that are not described by any existing error code.

See Also

»GetLastError«


  WNetGetUser

DWORD WNetGetUser(lpszLocalName, lpszUserName, lpcchBuffer)
LPTSTR  lpszLocalName;   /* address of local name to get user name for */
LPTSTR  lpszUserName;   /* address of buffer for user name  */
LPDWORD  lpcchBuffer;   /* address of buffer-size variable */

The WNetGetUser function retrieves the current default user name or the user name used to establish a network connection.

Parameters

lpszLocalName

Points to a null-terminated string that specifies either the name of the local device to return the user name for, or the name of a network that the user has made a connection to.

If lpszLocalName is NULL, Windows returns the name of the current user for the process.

If lpszLocalName is a network name and the user is connected to that resource using different names, the network provider may not be able to resolve which user name to return. In this case, the provider may make an arbitrary choice from the possible user names.

lpszUserName

Points to a buffer that will receive the null-terminated user name.

lpcchBuffer

Points to a variable that specifies the size, in characters, of the buffer pointed to by the lpszUserName parameter. If the call fails because the buffer is not big enough, this variable returns the required buffer size.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, the return value is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_NOT_CONNECTED	The device specified by lpszLocalName is not a redirected device or a connected network name.
ERROR_MORE_DATA	The buffer is too small.
ERROR_NO_NETWORK	No network is present.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
ERROR_NO_NET_OR_BAD_PATH	None of the providers recognized this local name as having a connection. However, the network is not available for at least one provider to whom the connection may belong.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

See Also

»WNetGetConnection«, »WNetGetLastError«


  WNetOpenEnum

DWORD WNetOpenEnum(fdwScope, fdwType, fdwUsage, lpNetResource, lphEnum)
DWORD  fdwScope;   /* scope of enumeration */
DWORD  fdwType;   /* resource types to list */
DWORD  fdwUsage;   /* resource usage to list */
LPNETRESOURCE  lpNetResource;   /* address of resource structure  */
LPHANDLE  lphEnum;   /* address of enumeration handle buffer */

The WNetOpenEnum function starts an enumeration of network resources or existing connections.

Parameters

fdwScope

Specifies the scope of the enumeration. This parameter can be one of the following values:

Value	Meaning
RESOURCE_CONNECTED	All currently connected resources (fdwUsage is ignored).
RESOURCE_GLOBALNET	All resources on the network.
RESOURCE_REMEMBERED	All remembered (persistent) connections (fdwUsage is ignored).
fdwType

Specifies the resource types to enumerate. This parameter can be a combination of the following values:

Value	Meaning
RESOURCETYPE_ANY	All resources. (This value cannot be combined with RESOURCETYPE_DISK or RESOURCETYPE_PRINT.)
RESOURCETYPE_DISK	All disk resources.
RESOURCETYPE_PRINT	All print resources.
If a network provider cannot distinguish between print and disk resources, it may enumerate all resources.

fdwUsage

Specifies the resource usage to be enumerated. This parameter can be a combination of the following values:

Value	Meaning
0	All resources.
RESOURCEUSAGE_CONNECTABLE	All connectable resources.
RESOURCEUSAGE_CONTAINER	All container resources.
The fdwUsage parameter is ignored if the fdwScope parameter is not RESOURCE_GLOBALNET.

lpNetResource

Points to a NETRESOURCE structure specifying the container to enumerate. The NETRESOURCE structure has the following form:

typedef struct _NETRESOURCE {  /* nr */

    DWORD  dwScope;

    DWORD  dwType;

    DWORD  dwDisplayType;

    DWORD  dwUsage;

    LPTSTR lpLocalName;

    LPTSTR lpRemoteName;

    LPTSTR lpComment;

    LPTSTR lpProvider;

} NETRESOURCE;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If lpNetResource is NULL, the root of the network is assumed. Windows organizes a network as a hierarchy; the root is the topmost container in the network. For more information about the Windows network functions, see Chapter 56, "Networks."

If lpNetResource is not NULL, it must point to a NETRESOURCE structure. This structure can be filled in by the application or returned by a call to the WNetEnumResource function. This NETRESOURCE structure must specify a container resource; that is, the RESOURCEUSAGE_CONTAINER bit must be set in the dwUsage member.

To enumerate all network resources, an application can begin the enumeration by calling WNetOpenEnum with lpNetResource set to NULL and then use the returned handle with the WNetEnumResource function to enumerate resources. If one of the resources in the NETRESOURCE array returned by the WNetEnumResource function is a container resource, the WNetOpenEnum function can be used to open the resource for further enumeration.

If the fdwScope parameter is not RESOURCE_GLOBALNET, lpNetResource must be NULL.

lphEnum

Points to variable filled in with an enumeration handle that can be used in a subsequent call to the WNetEnumResource function.

Return Value

If the function succeeds, the return value is NO_ERROR. Otherwise, the return value is an error code, which can be retrieved by calling the GetLastError function. Possible return values from GetLastError include the following:

Value	Meaning
ERROR_NOT_CONTAINER	The lpNetResource parameter does not point to a container.
ERROR_INVALID_PARAMETER	Either the fdwScope or the fdwType parameter is invalid, or there is a bad combination of parameters.
ERROR_NO_NETWORK	No network is present.
ERROR_EXTENDED_ERROR	A network-specific error occurred. Use the WNetGetLastError function to obtain a description of the error.
This function returns error codes for compatibility with Windows 3.1. For compatibility with Windows NT, the function also sets the error-code value returned by the GetLastError function.

Comments

The WNetOpenEnum function is used to begin enumeration of the resources in a single container. The following examples show the hierarchical structure of a Microsoft® Advanced Server™ network and a Novell® Netware® network:

AdServer (container, in this case the provider)

  ACCOUNTING (container, in this case the domain)

    \\ACCTSPAY (container, in this case the server)

      PAYFILES (disk)

      LASERJET (print)

Netware (container, in this case the provider)

  MARKETING (container, in this case the server)

    SYS (disk, first one on any Netware server)

    ANOTHERVOLUME (disk)

    LASERJET (print)

See Also

»WNetCloseEnum«, »WNetEnumResource«


  WordBreakProc

int CALLBACK WordBreakProc(lpszEditText, ichCurrentPos, cbEditText, action)
LPSTR  lpszEditText;   /* address of edit text */
int  ichCurrentPos;   /* index of starting point */
int  cbEditText;   /* length of edit text  */
int  action;   /* action to take */

The WordBreakProc function is an application-defined callback function that the operating system calls whenever a multiline edit control must break a line of text.

Parameters

lpszEditText

Points to the text of the edit control.

ichCurrentPos

Specifies an index to a character position in the buffer of text that identifies the point at which the function should begin checking for a word break.

cbEditText

Specifies the number of bytes in the text.

action

Specifies the action to be taken by the callback function. This parameter can be one of the following values:

Value	Action
WB_LEFT	Look for the beginning of a word to the left of the current position.
WB_RIGHT	Look for the beginning of a word to the right of the current position. (This is useful in right-aligned edit controls.)
WB_ISDELIMITER	Check whether the character at the current position is a delimiter.
Return Value

If the action parameter specifies WB_ISDELIMITER, the return value is nonzero (TRUE) if the character at the current position is a delimiter, or zero if it is not. Otherwise, the return value is an index to the beginning of a word in the buffer of text.

Comments

A carriage return followed by a linefeed must be treated as a single word by the callback function. Two carriage returns followed by a linefeed also must be treated as a single word.

An application must install the callback function by specifying the address of the callback function in an EM_SETWORDBREAKPROC message.

WordBreakProc is a placeholder for the library-defined function name.

See Also

»SendMessage«


  WriteConsole

BOOL WriteConsole(hConsoleOutput, lpvBuffer, cchToWrite, lpcchWritten, lpvReserved)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
CONST VOID  *lpvBuffer;   /* address of buffer to write from */
DWORD  cchToWrite;   /* number of characters to write */
LPDWORD  lpcchWritten;   /* address of number of characters written  */
LPVOID  lpvReserved;   /* reserved */

The WriteConsole function writes a character string to a console screen buffer beginning at the current cursor location.

Parameters

hConsoleOutput

Identifies the console screen buffer to write to. The handle must have GENERIC_WRITE access.

lpvBuffer

Points to a buffer that contains characters to be written to the screen buffer.

cchToWrite

Specifies the number of characters to write.

lpcchWritten

Points to a 32-bit variable that receives the number of characters actually written.

lpvReserved

Reserved; must be NULL.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

WriteConsole writes characters to a console screen buffer. It behaves like the WriteFile function except that it can write in either Unicode (wide-character) or ANSI mode. To create an application that maintains a single set of sources compatible with both modes, use WriteConsole rather than WriteFile. However, WriteConsole can only be used with a console screen buffer handle; WriteFile can also be used with other handles (such as files or pipes). This means that WriteConsole fails if used with a standard handle that has been redirected to be something other than a console handle.

Although an application can use WriteConsole in ANSI mode, to write ANSI characters, the function does not support ANSI escape sequences.

WriteConsole writes characters to the screen buffer at the current cursor position. The cursor position advances as characters are written. The SetConsoleCursorPosition function sets the current cursor position.

Characters are written using the foreground and background color attributes associated with this screen buffer. The SetConsoleTextAttribute function changes these colors. To determine the current color attributes and the current cursor position, use GetConsoleScreenBufferInfo.

All of the input modes that affect the behavior of WriteFile have the same effect on WriteConsole. To query and set the output modes of a console screen buffer, use the GetConsoleMode and SetConsoleMode functions.

See Also

»GetConsoleMode«, »GetConsoleScreenBufferInfo«, »ReadConsole«, »SetConsoleMode«, »SetConsoleTextAttribute«, »WriteFile«


  WriteConsoleInput

BOOL WriteConsoleInput(hConsoleInput, pirBuffer, cInRecords, lpcWritten)
HANDLE  hConsoleInput;   /* handle of a console input buffer */
PINPUT_RECORD  pirBuffer;   /* address of the buffer for write data */
DWORD  cInRecords;   /* number of records to write */
LPDWORD  lpcWritten;   /* address of number of records written */

The WriteConsoleInput function writes data directly to the console input buffer.

Parameters

hConsoleInput

Identifies the input buffer. The handle must have GENERIC_WRITE access.

pirBuffer

Points to an INPUT_RECORD buffer containing data to be written to the input buffer. The INPUT_RECORD structure has the following form:

typedef struct _INPUT_RECORD { /* ir */

    WORD EventType;

    union {

        KEY_EVENT_RECORD KeyEvent;

        MOUSE_EVENT_RECORD MouseEvent;

        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;

        MENU_EVENT_RECORD MenuEvent;

        FOCUS_EVENT_RECORD FocusEvent;

    } Event;

} INPUT_RECORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

cInRecords

Specifies the number of input records to write.

lpcWritten

Points to a 32-bit variable that receives the number of input records actually written.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

WriteConsoleInput places input records into the input buffer behind any pending events in the buffer. The input buffer grows dynamically, if necessary, to hold as many events as are written.

See Also

»PeekConsoleInput«, »ReadConsoleInput«


  WriteConsoleOutput

BOOL WriteConsoleOutput(hConsoleOutput, pchiSrcBuffer, coordSrcBufferSize,
coordSrcBufferCoord, psrctDestRect)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
PCHAR_INFO  pchiSrcBuffer;   /* address of buffer with data to write */
COORD  coordSrcBufferSize;   /* column-row size of source buffer */
COORD  coordSrcBufferCoord;   /* upper left cell to write from */
PSMALL_RECT  psrctDestRect;   /* address of rectangle to write to */

The WriteConsoleOutput function writes character and color attribute data to a specified rectangular block of character cells in a console screen buffer. The data to be written is taken from a correspondingly sized rectangular block at a given location in the source buffer.

Parameters

hConsoleOutput

Identifies the screen buffer. The handle must have GENERIC_WRITE access.

pchiSrcBuffer

Points to a source buffer that contains the data to be written to the screen buffer. This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures whose size is specified by the coordSrcBufferSize parameter. The CHAR_INFO structure has the following form:

typedef struct _CHAR_INFO { /* chi */

    union {                /* Unicode or ANSI character  */

        WCHAR UnicodeChar;

        CHAR AsciiChar;

    } Char;

    WORD Attributes;       /* text and background colors */

} CHAR_INFO, *PCHAR_INFO;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

coordSrcBufferSize

Specifies the size, in character cells, of the buffer pointed to by the pchiSrcBuffer parameter. The X member of the COORD structure is the number of columns; the Y member is the number of rows. The COORD structure has the following form:

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

coordSrcBufferCoord

Specifies the coordinates of the upper left cell in the buffer pointed to by the pchiSrcBuffer parameter to write data from. The X member of the COORD structure is the column, and the Y member is the row.

psrctDestRect

Points to a SMALL_RECT structure. On input, the structure members specify the upper left and lower right coordinates of the screen buffer rectangle to write to. On output, the structure members specify the actual rectangle that was written to. The SMALL_RECT structure has the following form:

typedef struct _SMALL_RECT { /* srct */

    SHORT Left;

    SHORT Top;

    SHORT Right;

    SHORT Bottom;

} SMALL_RECT;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

WriteConsoleOutput treats the source buffer and the destination screen buffer as two-dimensional arrays (columns and rows of character cells). The rectangle pointed to by the psrctDestRect parameter specifies the size and location of the block to write to in the screen buffer. A rectangle of the same size is located with its upper left cell at the coordinates of the coordSrcBufferCoord parameter in the pchiSrcBuffer array. Data from the cells that are in the intersection of this rectangle and the source buffer rectangle (whose dimensions are specified by the coordSrcBufferSize parameter) is written to the destination rectangle.

Cells in the destination rectangle whose corresponding source location are outside the boundaries of the source buffer rectangle are left unaffected by the write operation. In other words, these are the cells for which there is no data available to be written.

Before WriteConsoleOutput returns, it sets the members of psrctDestRect to the actual screen buffer rectangle affected by the write operation. This reflects the cells in the destination rectangle for which there existed a corresponding cell in the source buffer; and it clips the dimensions of the destination rectangle to the boundaries of the screen buffer.

If the rectangle specified by psrctDestRect lies completely outside the boundaries of the screen buffer, or if the corresponding rectangle is positioned completely outside the boundaries of the source buffer, no data is written. In this case, the function returns with the members of the structure pointed to by the psrctDestRect parameter set such that the Right member is less than the Left, or the Bottom member is less than the Top. To determine the size of the screen buffer, use the GetConsoleScreenBufferInfo function.

WriteConsoleOutput has no effect on the cursor position.

See Also

»ReadConsoleOutput«, »ReadConsoleOutputAttribute«, »ReadConsoleOutputCharacter«, »WriteConsoleOutputAttribute«, »WriteConsoleOutputCharacter«


  WriteConsoleOutputAttribute

BOOL WriteConsoleOutputAttribute(hConsoleOutput, lpwAttribute, cWriteCells,
coordWrite, lpcWritten)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
LPWORD  lpwAttribute;   /* address of buffer to write attributes from */
DWORD  cWriteCells;   /* number of character cells to write to */
COORD  coordWrite;   /* coordinates of first cell to write to */
LPDWORD  lpcWritten;   /* address of number of cells written to */

The WriteConsoleOutputAttribute function copies a specified number of foreground and background color attributes to consecutive cells of a console screen buffer, beginning at a given location.

Parameters

hConsoleOutput

Identifies the screen buffer. The handle must have GENERIC_WRITE access.

lpwAttribute

Points to a buffer that contains the attributes to write to the screen buffer.

cWriteCells

Specifies the number of screen buffer character cells to write to.

coordWrite

Specifies the column and row coordinates of the first cell in the screen buffer to write to.

lpcWritten

Points to a 32-bit variable that receives the number of attributes actually written to the screen buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of attributes to write to extends beyond the end of the specified row in the screen buffer, attributes are written to the next row. If the number of attributes to write to extends beyond the end of the screen buffer, the attributes are written up to the end of the screen buffer.

The character values at the positions written to are not changed.

Each attribute specifies the foreground (text) and background colors in which that character cell is drawn. The attribute values are some combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a white background.

FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE

See Also

»ReadConsoleOutput«, »ReadConsoleOutputAttribute«, »ReadConsoleOutputCharacter«, »WriteConsoleOutput«, »WriteConsoleOutputCharacter«


  WriteConsoleOutputCharacter

BOOL WriteConsoleOutputCharacter(hConsoleOutput, lpWriteBuffer, cchWrite,
coordWriteCoord, lpcWritten)
HANDLE  hConsoleOutput;   /* handle of a console screen buffer */
LPTSTR  lpWriteBuffer;   /* address of buffer to write characters from */
DWORD  cchWrite;   /* number of character cells to write to */
COORD  coordWriteCoord;   /* coordinates of first cell to write to */
LPDWORD  lpcWritten;   /* address of number of cells written to */

The WriteConsoleOutputCharacter function copies a specified number of characters to consecutive cells of a console screen buffer, beginning at a given location.

Parameters

hConsoleOutput

Identifies the screen buffer. The handle must have GENERIC_WRITE access.

lpWriteBuffer

Points to a buffer that contains the characters to write to the screen buffer.

cchWrite

Specifies the number of screen buffer character cells to write to.

coordWriteCoord

Specifies the column and row coordinates of the first cell in the screen buffer to write to.

lpcWritten

Points to a doubleword that the function sets on exit to the number of characters written to the screen buffer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If the number of characters to write to extends beyond the end of the specified row in the screen buffer, characters are written to the next row. If the number of characters to write to extends beyond the end of the screen buffer, characters are written up to the end of the screen buffer.

The attribute values at the positions written to are not changed.

See Also

»ReadConsoleOutput«, »ReadConsoleOutputAttribute«, »ReadConsoleOutputCharacter«, »WriteConsoleOutput«, »WriteConsoleOutputAttribute«


  WriteFile

BOOL WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten,
lpOverlapped)
HANDLE  hFile;   /* file to write to */
CONST VOID  *lpBuffer;   /* address of data to write to file */
DWORD  nNumberOfBytesToWrite;   /* number of bytes to write */
LPDWORD  lpNumberOfBytesWritten;   /* address of number of bytes written */
LPOVERLAPPED  lpOverlapped;   /* addr. of structure needed for overlapped I/O */

The WriteFile function writes data to a file. The function starts writing data to the file at the position indicated by the file pointer. After the write has been completed, the file pointer is adjusted by the number of bytes actually written except when the file is opened with FILE_FLAG_OVERLAPPED. If the file handle was created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the write is finished.

Parameters

hFile

Identifies the file to be written. The file handle must have been created with GENERIC_WRITE access to the file.

lpBuffer

Points to the buffer containing the data to be written to the file.

nNumberOfBytesToWrite

Specifies the number of bytes to write to the file. Unlike the MS-DOS operating system, Windows NT interprets a value of zero as specifying a null write operation. A null write operation does not write any bytes but does cause the time stamp to change.

lpNumberOfBytesWritten

Specifies the number of bytes written by this call. WriteFile sets this value to zero before doing any work or error checking.

lpOverlapped

Points to an OVERLAPPED structure that is required if hFile was opened with FILE_FLAG_OVERLAPPED.

The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the current position of the file pointer is unknown, WriteFile returns FALSE, and the GetLastError function returns ERROR_INVALID_PARAMETER.

If hFile was not created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the write operation starts at the current file position and WriteFile does not return until the operation has been completed.

If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile may return before the write operation has been completed. In this case, WriteFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue processing while the write operation is being completed. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation.

If hFile was not created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile does not return until the write operation has been completed.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If part of the file is locked by another process and the write overlaps the locked portion, this function fails.

Characters can be written to the screen buffer using WriteFile with a handle to console output. The exact behavior of the function is determined by the console mode. The data is written to the current cursor position. The cursor position is updated after the write.

Unlike the MS-DOS operating system, Windows NT interprets zero bytes to write as specifying a null write operation and WriteFile does not truncate or extend the file. Use the SetEndOfFile function to truncate or extend a file.

When writing to a nonblocking, byte-mode pipe handle with insufficient buffer space, WriteFile returns TRUE with *lpNumberOfBytesWritten < nNumberOfBytesToWrite.

When an application uses the WriteFile function to write to a pipe, the write operation may not finish if the pipe buffer is full. The write operation is completed when a read operation (using the ReadFile function) makes more buffer space available.

If the anonymous read pipe handle has been closed, and WriteFile attempts to write using the corresponding anonymous write pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.

The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.

See Also

»CreateFile«, »GetOverlappedResult«, »ReadFile«, »SetEndOfFile«, »WriteFileEx«


  WriteFileEx

BOOL WriteFileEx(hFile, lpBuffer, nNumberOfBytesToWrite, lpOverlapped, lpCompletionRoutine)
HANDLE  hFile;   /* file to write */
LPVOID  lpBuffer;   /* address of buffer */
DWORD  nNumberOfBytesToWrite;   /* no. of bytes to write */
LPOVERLAPPED  lpOverlapped;   /* address of offset */
LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine;       /* addr. of routine */

The WriteFileEx function writes data to a file and reports its completion status asynchronously. This function is an extension to the WriteFile function that enables an application to continue with other processing.

Parameters

hFile

Identifies the file to write to. The file handle must have been created with the FILE_FLAG_OVERLAPPED flag and must have GENERIC_WRITE access to the file.

lpBuffer

Points to the buffer that contains the data to write to the file. The application must not use this buffer until overlapped input and output (I/O) has been completed.

nNumberOfBytesToWrite

Specifies the number of bytes to write to the file. If nNumberOfBytesToWrite is zero, this function does nothing.

lpOverlapped

Points to an OVERLAPPED structure. This structure must be valid for the duration of the write operation. It should not be a local variable if the calling application can return while the write operation is pending.

The OVERLAPPED structure has the following form:

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

For a full description of this structure, see the Microsoft Win32 Programmer's Reference, Volume 5.

lpCompletionRoutine

Points to the completion routine called when the write operation has been completed. For more information about the completion routine, see the description of the »FileIOCompletionRoutine« function.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

If the write operation is not yet completed, the function returns TRUE. If the calling thread is in an alertable wait (using the SleepEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx function) when the write operation is completed, the completion routine is called and the wait is completed with a return value of WAIT_IO_COMPLETION.

If the calling thread is not in an alertable wait when the write operation finishes, Windows queues the completion routine call until the thread enters an alertable wait.

Comments

If part of the file is locked by another process and the read overlaps the locked portion, this function fails.

The WriteFileEx function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.

See Also

»CreateFile«, »ReadFileEx«, »SleepEx«, »WaitForMultipleObjectsEx«, »WaitForSingleObjectEx«, »WriteFile«


  WritePrinter

BOOL WritePrinter(hPrinter, pBuf, cbBuf, lpdwWritten)
HANDLE  hPrinter;   /* handle of printer object */
LPVOID  pBuf;   /* address of array that contains printer data */
DWORD  cbBuf;   /* size, in bytes, of array */
LPDWORD  lpdwWritten;   /* addr. of variable with count of bytes written */

The WritePrinter function informs the print spooler that the specified data should be written to the given printer.

Parameters

hPrinter

Identifies the printer.

pBuf

Points to an array of bytes that contains the data that should be written to the printer.

cbBuf

Specifies the size, in bytes, of the array.

lpdwWritten

Points to a value that specifies the number of bytes of data that were written to the printer.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

See Also

»OpenPrinter«


  WritePrivateProfileSection

BOOL WritePrivateProfileSection(lpszSection, lpszKeysAndValues, lpszFile)
LPCTSTR  lpszSection;   /* address of string with section name */
LPCTSTR  lpszKeysAndValues;   /* address of string with data  */
LPCTSTR  lpszFile;   /* address of string with filename */

The WritePrivateProfileSection function replaces the keys and values under the specified section in the given initialization file.

This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string containing the name of the section in which data is written. This section name is typically the name of the calling application.

lpszKeysAndValues

Points to a buffer containing the new key names and associated values that are written to the named section.

lpszFile

Points to a null-terminated string containing the name of the initialization file. If this parameter does not contain a full path for the file, the function searches the Windows directory for the file. If the file does not exist and lpszFile does not contain a full path, the function creates the file in the Windows directory. The function does not create a file if lpszFile contains the full path and filename of a file that does not exist.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

The data in the buffer pointed to by the lpszKeysAndValues parameter consists of one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The WritePrivateProfileSection function is not case-sensitive; the string pointed to by the lpszSection parameter can be a combination of uppercase and lowercase letters.

If no section name matches the string pointed to by the lpszSection parameter, WritePrivateProfileSection creates the section at the end of the specified initialization file and initializes the new section with the specified key name and value pairs.

WritePrivateProfileSection deletes the existing keys and values for the named section and inserts the key names and values in the buffer pointed to by the lpszKeysAndValues parameter. The function does not attempt to correlate old and new key names; if the new names appear in a different order from the old names, any comments associated with preexisting keys and values in the initialization file will probably be associated with incorrect keys and values.

This operation is atomic; no operations that read from or write to the specified initialization file are allowed while the information is being written.

Calls to PrivateProfile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In this case, the WritePrivateProfileSection function writes information to the registry, not to the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetPrivateProfileSection«, »RegCreateKeyEx«, »RegSetValueEx«, »WriteProfileSection«


  WritePrivateProfileString

BOOL WritePrivateProfileString(lpszSection, lpszKey, lpszString, lpszFile)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKey;   /* address of key name */
LPCTSTR  lpszString;   /* address of string to add */
LPCTSTR  lpszFile;   /* address of initialization filename */

The WritePrivateProfileString function copies a string into the specified section of the specified initialization file.

This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string containing the name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section is case-independent; the string can be any combination of uppercase and lowercase letters.

lpszKey

Points to the null-terminated string containing the name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this parameter is NULL, the entire section, including all entries within the section, is deleted.

lpszString

Points to a null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpszKey parameter is deleted.

lpszFile

Points to a null-terminated string that names the initialization file.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

To improve performance, Windows keeps a cached version of the most-recently accessed initialization file. If that filename is specified and the other three parameters are NULL, Windows flushes the cache. In that case, the function returns FALSE, even if the flush succeeds.

A section in the initialization file must have the following form:

[section]
key=string
      .
      .
      .

If the lpszFile parameter does not contain a full path and filename for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.

If lpszFile contains a full path and filename and the file does not exist, WriteProfileString creates the file. The specified directory must already exist.

An application can use the WritePrivateProfileString function to enter .INI file information into the registry. To do so, an application should follow these guidelines:

•	Ensure that no .INI file of the specified name exists on the system.

•	Ensure that there is a key entry in the registry that specifies the .INI file. This entry should be under the path HKEY_LOCAL_MACHINE\SOFTWARE\ Microsoft\Windows NT\CurrentVersion\IniFileMapping.

•	Enter a value for that .INI file key entry that specifies a section. That is to say, an application must specify a section name, as it would appear within an .INI file or registry entry. Here is an example: [My Section].

•	For system files, an application should specify SYS for an added value.

•	For application files, an application should specify USR within the added value. Here is an example: "My Section: USR: App NameSection". And, since USR indicates a mapping under HKEY_CURRENT_USER, the application should also create a key under HKEY_CURRENT_USER that specifies the application name listed in the added value. For the example just given, that would be "App Name".

The following sample code illustrates the foregoing guidelines. These assumptions are made :

•	There is an application named "Foo Bar"

•	That application uses an .INI file named "foobar.ini"

•	There is a section in the .INI file that we want to look like this:

[Section1]

  FirstKey = It all worked out okay.

  SecondKey = By golly, it works.

  ThirdKey = Another test.

Here is the sample code :

/* include files */

#include <stdio.h>

#include <windows.h>

/* a main function */

main()

{

  /* local variables */

  CHAR inBuf[80];

  HKEY  hKey1, hKey2;

  DWORD  dwDisposition;

  LONG   lRetCode;

  /* try to create the .INI file key */

  lRetCode = RegCreateKeyEx ( HKEY_LOCAL_MACHINE,

             "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\foobar.ini",

                              0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,

                              NULL, &hKey1,

                              &dwDisposition);

  /* if we failed, note it, and leave */

  if (lRetCode != ERROR_SUCCESS){

    printf ("Error in creating foobar.ini key\n");

    return (0) ;

    }

  /* try to set a section value */

  lRetCode = RegSetValueEx ( hKey1,

                             "Section1",

                             0,

                             REG_SZ,

                             "USR:Foo Bar\\Section1",

                             20);

  /* if we failed, note it, and leave */

  if (lRetCode != ERROR_SUCCESS) {

    printf ( "Error in setting Section1 value\n");

    return (0) ;

    }

  /* try to create a Foo Bar key */

  lRetCode = RegCreateKeyEx ( HKEY_CURRENT_USER,

                              "Foo Bar",

                              0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,

                              NULL, &hKey2,

                              &dwDisposition);

  /* if we failed, note it, and leave */

  if (lRetCode != ERROR_SUCCESS) {

    printf ("Error in creating Foo Bar key\n");

    return (0) ;

    }

  /* if we get this far, all has gone well */

  /* let's write some added values */

  WritePrivateProfileString ("Section1", "FirstKey",

                             "It all worked out okay.", "foobar.ini");

  WritePrivateProfileString ("Section1", "SecondKey",

                             "By golly, it works.", "foobar.ini");

  WritePrivateProfileSection ("Section1", "ThirdKey = Another Test.",

                              "foobar.ini");

  /* let's test our work */

  GetPrivateProfileString ("Section1", "FirstKey",

                           "Bogus Value: Get didn't work", inBuf, 80,

                           "foobar.ini");

  printf ("%s", inBuf);

  /* okay, we are outta here */

  return(0);

}

See Also

»GetPrivateProfileString«, »WriteProfileString«


  WriteProcessMemory

BOOL WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, cbWrite,
lpNumberOfBytesWritten)
HANDLE  hProcess;   /* handle of process whose memory is written to */
LPVOID  lpBaseAddress;   /* address to start writing to */
LPVOID  lpBuffer;   /* address of buffer to write data to */
DWORD  cbWrite;   /* number of bytes to write */
LPDWORD  lpNumberOfBytesWritten;   /* actual number of bytes written */

The WriteProcessMemory function writes memory in a specified process. The entire area to be written to must be accessible, or the operation fails.

Parameters

hProcess

Identifies an open handle of a process whose memory is to be written to. The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.

lpBaseAddress

Points to the base address in the specified process to be written to. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for write access. If this is the case, the function proceeds; otherwise, the function fails.

lpBuffer

Points to the buffer that supplies data to be written into the specified process address space.

cbWrite

Specifies the requested number of bytes to write into the specified process.

lpNumberOfBytesWritten

Specifies an optional parameter that, if supplied, receives the actual number of bytes transferred into the specified process. If lpNumberOfBytesWritten is NULL, the parameter is ignored.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function. The function will fail if the requested write operation crosses into an area of the process that is inaccessible.

Comments

This function copies the data from the specified buffer in the current process to the address range of the specified process. Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call WriteProcessMemory. The process whose address space is being written to is typically, but not necessarily, being debugged.

The entire area to be written to must be accessible. If it is not, the function fails, as noted above.

See Also

»ReadProcessMemory«


  WriteProfileSection

BOOL WriteProfileSection(lpszSection, lpszKeysAndValues)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKeysAndValues;   /* address of buffer with data */

The WriteProfileSection function replaces the contents of the specified section in the WIN.INI file with the specified keys and values.

This function is provided for compatibility with 16-bit Windows applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string containing the name of the section in which data is written. This section name is typically the name of the calling application.

lpszKeysAndValues

Points to a buffer containing the new key names and associated values that are written to the named section.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

If there is no section in WIN.INI that matches the specified section name, WriteProfileSection creates the section at the end of the file and initializes the new section with the key name and value pairs specified in the lpszKeysAndValues parameter.

Keys and values in the lpszKeysAndValues buffer, consists of one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The WriteProfileSection function is not case-sensitive; the strings can be a combination of uppercase and lowercase letters.

WriteProfileSection deletes the existing keys and values for the named section and inserts the key names and values in the buffer pointed to by lpszKeysAndValues. The function does not attempt to correlate old and new key names; if the new names appear in a different order from the old names, any comments associated with preexisting keys and values in the initialization file will probably be associated with incorrect keys and values.

This operation is atomic; no other operations that read from or write to the initialization file are allowed while the information is being written.

Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the WriteProfileSection function writes information to the registry, not to the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetProfileSection«, »WritePrivateProfileSection«


  WriteProfileString

BOOL WriteProfileString(lpszSection, lpszKey, lpszString)
LPCTSTR  lpszSection;   /* address of section name */
LPCTSTR  lpszKey;   /* address of key name */
LPCTSTR  lpszString;   /* address of string to write */

The WriteProfileString function copies a string into the specified section of the WIN.INI file.

This function is provided for compatibility with 16-bit Windows-based applications. New applications should store initialization information in the registry.

Parameters

lpszSection

Points to a null-terminated string that specifies the section to which the string is to be copied. If the section does not exist, it is created. The name of the section is not case-sensitive; the string can be any combination of uppercase and lowercase letters.

lpszKey

Points to a null-terminated string containing the key to be associated with the string. If the key does not exist in the specified section, it is created. If this parameter is NULL, the entire section, including all entries in the section, is deleted.

lpszString

Points to a null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpszKey parameter is deleted.

Return Value

If the function succeeds, the return value is TRUE; otherwise, it is FALSE. To get extended error information, use the GetLastError function.

Comments

Windows keeps a cached version of WIN.INI to improve performance. If all three parameters are NULL, Windows flushes the cache.

A section in the WIN.INI file must have the following form:

[section]
key=string
    .
    .
    .

Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the WritePrivateProfileString function writes information to the registry, not to the initialization file; the change in the storage location has no effect on the function's behavior.

See Also

»GetProfileString«, »WritePrivateProfileString«


  WriteTapemark

DWORD WriteTapemark(hDevice, dwTapemarkType, dwTapemarkCount, bImmediate)
HANDLE  hDevice;   /* handle of open device */
DWORD  dwTapemarkType;   /* type of tapemarks to write */
DWORD  dwTapemarkCount;   /* number of tapemarks to write  */
BOOL  bImmediate;   /* return after write begins */

Parameters

hDevice

Identifies the device on which to write tapemarks. This handle is created by using the CreateFile function.

dwTapemarkType

Specifies the type of tapemarks to write. This parameter can be one of the following values:

Value	Description
TAPE_FILEMARKS	Writes the number of filemarks specified by the dwTapemarkCount parameter.
TAPE_LONG_FILEMARKS	Writes the number of long filemarks specified by dwTapemarkCount.
TAPE_SETMARKS	Writes the number of setmarks specified by dwTapemarkCount.
TAPE_SHORT_FILEMARKS	Writes the number of short filemarks specified by dwTapemarkCount.
dwTapemarkCount

Specifies the number of tapemarks to write.

bImmediate

Specifies whether to return as soon as the operation begins. If this parameter is TRUE, the function returns immediately; if it is FALSE, the function does not return until the operation has been completed.

Return Value

If the function succeeds, the return value is NO_ERROR; otherwise, it can be one of the following error codes:

Error	Description
ERROR_BEGINNING_OF_MEDIA	An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET	A reset condition was detected on the bus.
ERROR_END_OF_MEDIA	The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED	A filemark was reached during an operation.
ERROR_SETMARK_DETECTED	A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED	The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE	The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH	The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED	The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED	The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE	There is no media in the drive.
ERROR_NOT_SUPPORTED	The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA	An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA	An attempt to unload the tape failed.
ERROR_WRITE_PROTECT	The media is write protected.
Comments

Filemarks, setmarks, short filemarks, and long filemarks are special recorded elements that denote the linear organization of the tape. None of these marks contain user data. Filemarks are the most general marks; setmarks provide a hierarchy not available with filemarks.

A short filemark contains a short erase gap that cannot be overwritten unless the write operation is performed from the beginning of the partition or from an earlier long filemark.

A long filemark contains a long erase gap that allows an application to position the tape at the beginning of the filemark and to overwrite the filemark and the erase gap.


  wsprintf

int cdecl wsprintf(lpOut, lpFmt [[, argument]. . .)
LPTSTR  lpOut;   /* address of buffer for output */
LPCTSTR  lpFmt;   /* address of format-control string */

The wsprintf function formats and stores a series of characters and values in a buffer. Any arguments are converted and copied to the output buffer according to the corresponding format specification in the format string. The function appends a terminating null character to the characters it writes, but the return value does not include the terminating null character in its character count.

Parameters

lpOut

Points to a buffer to receive the formatted output.

lpFmt

Points to a null-terminated string that contains the format-control specifications. In addition to ordinary ASCII characters, a format specification for each argument appears in this string. For more information about the format specification, see the Comments section.

argument

Specifies one or more optional arguments. The number and type of argument parameters depend on the corresponding format-control specifications in the lpFmt parameter.

Return Value

If the function succeeds, the return value is the number of characters stored in the output buffer, not counting the terminating null character. Otherwise, the return value is less than the length of the format-control string. To get extended error information, use the GetLastError function.

Comments

The format-control string contains format specifications that determine the output format for the arguments following the lpFmt parameter. Format specifications, discussed below, always begin with a percent sign (%). If a percent sign is followed by a character that has no meaning as a format field, the character is not formatted (for example, %% produces a single percent-sign character).

The format-control string is read from left to right. When the first format specification (if any) is encountered, it causes the value of the first argument after the format-control string to be converted and copied to the output buffer according to the format specification. The second format specification causes the second argument to be converted and copied, and so on. If there are more arguments than format specifications, the extra arguments are ignored. If there are not enough arguments for all of the format specifications, the results are undefined.

A format specification has the following form:

%[-][#][0][width][.precision]type

Each field is a single character or a number signifying a particular format option. The type characters that appear after the last optional format field determine whether the associated argument is interpreted as a character, a string, or a number. The simplest format specification contains only the percent sign and a type character (for example, %s). The optional fields control other aspects of the formatting. Following are the optional and required fields and their meanings:

Field	Meaning
−	Pad the output with blanks or zeros to the right to fill the field width, justifying output to the left. If this field is omitted, the output is padded to the left, justifying it to the right.
#	Prefix hexadecimal values with 0x (lowercase) or 0X (uppercase).
0	Pad the output value with zeros to fill the field width. If this field is omitted, the output value is padded with blank spaces.
width	Copy the specified minimum number of characters to the output buffer. The width field is a nonnegative integer. The width specification never causes a value to be truncated; if the number of characters in the output value is greater than the specified width, or if the width field is not present, all characters of the value are printed, subject to the precision specification.
.precision	For numbers, copy the specified minimum number of digits to the output buffer. If the number of digits in the argument is less than the specified precision, the output value is padded on the left with zeros. The value is not truncated when the number of digits exceeds the specified precision. If the specified precision is 0 or omitted entirely, or if the period (.) appears without a number following it, the precision is set to 1.
	For strings, copy the specified maximum number of characters to the output buffer.
type	Output the corresponding argument as a character, a string, or a number. This field can be any of the following character sequences:
Sequence	Insert
c	A single character. The wsprintf function ignores character arguments with a numeric value of zero. This sequence is interpreted as type WCHAR when the calling application uses the #define UNICODE compile flag and as type CHAR otherwise.
C	A single character. This sequence is interpreted as type CHAR when the calling application uses the #define UNICODE compile flag and as type WCHAR otherwise.
d	A signed decimal integer argument. This sequence is equivalent to the i sequence.
hc, hC	A single character. The wsprintf function ignores character arguments with a numeric value of zero. This sequence is always interpreted as type CHAR, even when the calling application uses the #define UNICODE compile flag.
hs, hS	A string. This sequence is always interpreted as type LPSTR, even when the calling application uses the #define UNICODE compile flag.
i	A signed decimal integer. This sequence is equivalent to the d sequence.
lc, lC	A single character. The wsprintf function ignores character arguments with a numeric value of zero. This sequence is always interpreted as type WCHAR, even when the calling application does not use the #define UNICODE compile flag.
ld	A long signed decimal integer. This sequence is equivalent to the li sequence.
li	A long signed decimal integer. This sequence is equivalent to the ld sequence.
ls, lS	A string. This sequence is always interpreted as type LPWSTR, even when the calling application does not use the #define UNICODE compile flag. This sequence is equivalent to the ws sequence.
lu	A long unsigned integer.
lx, lX	A long unsigned hexadecimal integer in lowercase or uppercase.
s	A string. This sequence is interpreted as type LPWSTR when the calling application uses the #define UNICODE compile flag and as type LPSTR otherwise.
S	A string. This sequence is interpreted as type LPSTR when the calling application uses the #define UNICODE compile flag and as type LPWSTR otherwise.
u	An unsigned integer argument.
x, X	An unsigned hexadecimal integer in lowercase or uppercase.
Note  Unlike other Windows functions, wsprintf uses the C calling convention (_cdecl), rather than the Pascal calling convention. As a result, it is the calling process's responsibility to pop arguments off the stack, and arguments are pushed on the stack from right to left. In C-language modules, the C compiler performs this task.

See Also

»wvsprintf«


  wvsprintf

int wvsprintf(lpOut, lpFmt, lpvaArgs)
LPTSTR  lpOut;   /* address of buffer for output */
LPCTSTR  lpFmt;   /* address of format-control string */
const VOID FAR*  lpvaArgs;   /* address of array of format-control arguments */

The wvsprintf function formats and stores a series of characters and values in a buffer. The items pointed to by the argument list are converted and copied to an output buffer according to the corresponding format specification in the format-control string. The function appends a terminating null character to the characters it writes, but the return value does not include the terminating null character in its character count.

Parameters

lpOut

Points to a buffer to receive the formatted output.

lpFmt

Points to a null-terminated string that contains the format-control specifications. In addition to ordinary ASCII characters, a format specification for each argument appears in this string. For more information about the format specification, see the description of the »wsprintf« function.

lpvaArgs

Points to an array of variables, each of which specifies an argument for the format-control string. The number, type, and interpretation of the arguments depend on the corresponding format-control specifications in the lpFmt parameter.

Return Value

If the function succeeds, the return value is the number of characters stored in the buffer, not counting the terminating null character. Otherwise, the return value is less than the length of the format-control string. To get extended error information, use the GetLastError function.

See Also

»wsprintf«


  Yield

void Yield(void)

The Yield function is obsolete. In the Win32 API, this function does nothing.

Threads that contain windows should use the DispatchMessage, PeekMessage, or TranslateMessage functions. The message-loop functions handle message synchronization properly and yield at the appropriate times.

Threads that do not contain windows should use the Sleep function with a sleep time of zero milliseconds to give up the remainder of their current timeslice.

See Also

»DispatchMessage«, »PeekMessage«, »Sleep«, »TranslateMessage«


  ZeroMemory

VOID ZeroMemory (Destination, Length)
PVOID  Destination;   /* address of block to fill with zeroes */
DWORD  Length;   /* size in bytes of block to fill with zeroes */

The ZeroMemory function fills a block of memory with zeroes.

Parameters

Destination

Points to the starting address of the block of memory to fill with zeroes.

Length

Specifies the size in bytes of the block of memory to fill with zeroes.

Return Value

This function has no return value.

See Also

»CopyMemory«, »FillMemory«, »MoveMemory«


Introduction
Programmer's Reference, Volume 5: Messages, Structures, and Macros

Introduction

The Microsoft® Win32™ application programming interface (API) allows applications to exploit the power of 32-bits on the Microsoft® Windows™ family of operating systems. Applications written to the Win32 API are scalable on single and multiprocessor systems, and portable to RISC architectures. These manuals document the complete Win32 API including window management, graphics, file I/O, threading, memory management, security and networking.


Organization of This Manual

Following are brief descriptions of the chapters and appendixes in this manual.

•	Chapter 1, "Data Types," describes the keywords that define the size and meaning of parameter and return values associated with the Win32 API.

•	Chapter 2, "Messages," describes formatted window messages, through which Windows communicates with applications, and notification messages, which notify a control's parent window of actions that occur within the control.

•	Chapter 3, "Structures," defines the structures associated with the functions that are part of the Win32 API.

•	Chapter 4, "Macros," describes the purpose and defines the parameters of macros used to help manipulate data in Windows-based applications.

•	Chapter 5, "Dynamic Data Exchange Transactions," describes the transactions sent by the Dynamic Data Exchange Management Library (DDEML) to an application's dynamic data exchange (DDE) callback function. The transactions notify the application of DDE activity that affects the application.


Document Conventions

The following conventions are used throughout this manual to define syntax.

Convention	Meaning
Bold text	Denotes a term or character to be typed literally, such as a predefined data type or function name (HWND or CreateWindowEx), a command, or a command-line option (/x). You must type these terms exactly as shown.
Italic text	Denotes a placeholder or variable: You must provide the actual value. For example, the statement SetCursorPos(X,Y) requires you to substitute values for the X and Y parameters.
[ ]	Enclose optional parameters.
|	Separates an either/or choice.
...	Specifies that the preceding item may be repeated.
.	Represents an omitted portion of a sample application.
.
.
In addition, certain text conventions are used to help you understand this material.

Convention	Meaning
SMALL CAPITALS	Indicate the names of keys, key sequences, and key combinations — for example, ALT+SPACEBAR.
FULL CAPITALS	Indicate filenames and paths, most type and structure names (which are also bold), and constants.
monospace	Sets off code examples and shows syntax spacing.


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Programmer's Reference, Volume 5:
Messages, Structures, and Macros


Data Types
  Chapter 1  Data Types


  1.1  Data Types

Data types are keywords that define the size and meaning of parameters, return values, and members associated with the functions, messages, and structures of Microsoft Windows. The following table contains character, integer, and Boolean types; pointer types; and handles. The character, integer, and Boolean types are common to most C compilers. Most of the pointer-type names begin with a prefix of P or LP. A Windows-based application uses a handle to refer to a resource that has been loaded into memory. Windows provides access to these resources through internally maintained tables that contain individual entries for each handle. Each entry in the handle table contains the address of the resource and a means of identifying the resource type.

Type	Definition
ATOM	Atom (a reference to a character string in an atom table)
BOOL	Boolean variable (should be TRUE or FALSE)
BOOLEAN	Boolean variable (should be TRUE or FALSE)
BYTE	Byte (8 bits)
CCHAR	Windows character
CHAR	Windows character
COLORREF	Red, green, blue (RGB) color value (32 bits)
const	Variable whose value is to remain constant during execution
CRITICAL_SECTION	Critical-section object
CTRYID	Country identifier
DLGPROC	Pointer to a dialog box procedure
DWORD	Doubleword (32 bits)
ENHMFENUMPROC	Pointer to an application-defined callback function that enumerates enhanced-metafile records
ENUMRESLANGPROC	Pointer to an application-defined callback function that enumerates resource languages
ENUMRESNAMEPROC	Pointer to an application-defined callback function that enumerates resource names
ENUMRESTYPEPROC	Pointer to an application-defined callback function that enumerates resource types
FARPROC	Pointer to a callback function
FLOAT	Floating-point variable
FMORDER	Array of 32-bit font-mapper values
FONTENUMPROC	Pointer to an application-defined callback function that enumerates fonts
GOBJENUMPROC	Pointer to an application-defined callback function that enumerates graphics device interface (GDI) objects
GRAYSTRINGPROC	Pointer to an application-defined callback function that draws gray text
HACCEL	Handle of an accelerator table
HANDLE	Handle of an object
HBITMAP	Handle of a bitmap
HBRUSH	Handle of a brush
HCONV	Handle of a dynamic data exchange (DDE) conversation
HCONVLIST	Handle of a DDE conversation list
HCURSOR	Handle of a cursor
HDC	Handle of a device context (DC)
HDDEDATA	Handle of DDE data
HDLG	Handle of a dialog box
HDWP	Handle of a deferred window position structure
HENHMETAFILE	Handle of an enhanced metafile
HFILE	Handle of a file
HFONT	Handle of a font
HGDIOBJ	Handle of a GDI object
HGLOBAL	Handle of a global memory block
HHOOK	Handle of a hook
HICON	Handle of an icon
HINSTANCE	Handle of an instance
HKEY	Handle of a registry key
HLOCAL	Handle of a local memory block
HMENU	Handle of a menu
HMETAFILE	Handle of a metafile
HMIDIIN	Handle of a Musical Instrument Digital Interface (MIDI) input file
HMIDIOUT	Handle of a MIDI output file
HMMIO	Handle of a file
HOOKPROC	Pointer to an application-defined hook function
HPALETTE	Handle of a palette
HPEN	Handle of a pen
HRGN	Handle of a region
HRSRC	Handle of a resource
HSZ	Handle of a DDE string
HWAVEIN	Handle of a waveform input file
HWAVEOUT	Handle of a waveform output file
HWINSTA	Handle of a workstation
HWND	Handle of a window
INT	Signed integer
LANGID	Language identifier
LCID	Locale identifier
LCTYPE	Locale type
LINEDDAPROC	Pointer to a callback function that processes line coordinates
LONG	32-bit signed value
LP	Pointer to a null-terminated Unicode™ string
LPARAM	32-bit message parameter
LPBOOL	Pointer to a Boolean variable
LPBYTE	Pointer to a byte
LPCCH	Pointer to a constant Windows character
LPCCHOOKPROC	Pointer to an application-defined hook function
LPCFHOOKPROC	Pointer to an application-defined hook function
LPCH	Pointer to a Windows character
LPCOLORREF	Pointer to a COLORREF value
LPCRITICAL_SECTION	Pointer to a critical-section object
LPCSTR	Pointer to a constant null-terminated Windows character string
LPCTSTR	Pointer to a constant null-terminated Unicode or Windows character string
LPCWCH	Pointer to a constant null-terminated Unicode character
LPCWSTR	Pointer to a constant null-terminated Unicode character string
LPDWORD	Pointer to an unsigned doubleword (32 bits)
LPFRHOOKPROC	Pointer to an application-defined hook function
LPHANDLE	Pointer to a handle
LPHANDLER_FUNCTION	Pointer to a handler function
LPHWAVEIN	Pointer to a handle to a waveform input file
LPHWAVEOUT	Pointer to a handle to a waveform output file
LPINT	Pointer to a signed integer
LPLONG	Pointer to a signed long (32 bits)
LPOFNHOOKPROC	Pointer to an application-defined hook function
LPPRINTHOOKPROC	Pointer to an application-defined hook function
LPSETUPHOOKPROC	Pointer to an application-defined hook function
LPSTR	Pointer to a null-terminated Windows character string
LPTCH	Pointer to a Unicode character or a Windows character
LPTSTR	Pointer to a null-terminated Windows or Unicode character string
LRESULT	Signed result of message processing
LPVOID	Pointer to any type
LPWCH	Pointer to a Unicode character
LPWORD	Pointer to an unsigned word (16 bits)
LPWSTR	Pointer to a null-terminated Unicode character string
LUID	Locally unique identifier
MCIDEVICEID	Media control interface (MCI) device identifier
MFENUMPROC	Pointer to an application-defined callback function that enumerates metafile records
MMRESULT	Result of multimedia message processing
NPSTR	Pointer to a null-terminated Windows character string
NWPSTR	Pointer to a null-terminated Unicode string
PBOOL	Pointer to a Boolean variable
PBOOLEAN	Pointer to a Boolean variable
PBYTE	Pointer to a byte
PCCH	Pointer to a constant Windows character
PCH	Pointer to a Windows character
PCHAR	Pointer to a Windows character
PCRITICAL_SECTION	Pointer to a critical-section object
PCSTR	Pointer to a constant null-terminated Windows character string
PCWCH	Pointer to a constant Unicode character
PCWSTR	Pointer to a constant null-terminated Unicode character string
PDWORD	Pointer to an unsigned doubleword (32 bits)
PFLOAT	Pointer to a floating-point variable
PFNCALLBACK	Pointer to a callback function
PHANDLE	Pointer to a handle
PHANDLER_ROUTINE	Pointer to a handler routine
PHKEY	Pointer to a registry key
PINT	Pointer to a signed integer
PLONG	Pointer to a signed long (32 bits)
PLUID	Pointer to a locally unique identifier (LUID)
PROPENUMPROC	Pointer to an application-defined callback function that enumerates window properties
PSHORT	Pointer to a signed short (16 bits)
PSID	Pointer to a security identifier (SID)
PSTR	Pointer to a null-terminated Windows character string
PSZ	Pointer to a null-terminated Windows character string
PTCH	Pointer to a Windows or Unicode character
PTCHAR	Pointer to a Windows or Unicode character
PTSTR	Pointer to a null-terminated Windows or Unicode character string
PUCHAR	Pointer to an unsigned Windows character
PUINT	Pointer to an unsigned integer
PULONG	Pointer to an unsigned long (32 bits)
PUSHORT	Pointer to an unsigned short (16 bits)
PVOID	Pointer to any type
PWCH	Pointer to a Unicode character
PWCHAR	Pointer to a Unicode character
PWORD	Pointer to an unsigned word (16 bits)
PWSTR	Pointer to a null-terminated Unicode character string
REGSAM	Security access mask for registry key
SC_HANDLE	Handle of a service
SERVICE_STATUS_HANDLE	Handle of a service status value
SHORT	Short integer
SPHANDLE	Pointer to a handle
TCHAR	Unicode character or Windows character
TIMERPROC	Pointer to an application-defined timer callback function
UCHAR	Unsigned Windows character
UINT	Unsigned integer
ULONG	Unsigned long integer (32 bits)
USHORT	Unsigned short integer (16 bits)
VOID	Any type
WCHAR	Unicode character
WNDENUMPROC	Pointer to an application-defined callback function that enumerates windows
WNDPROC	Pointer to an application-defined window procedure
WORD	Unsigned word (16 bits)
WPARAM	32-bit message parameter
YIELDPROC	Pointer to a yield callback function


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Messages
  Chapter 2  Messages


  BM_GETCHECK

BM_GETCHECK

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a BM_GETCHECK message to retrieve the check state of a radio button or check box.

Parameters

This message has no parameters.

Return Value

The return value from a button created with the BS_AUTOCHECKBOX, BS_AUTORADIOBUTTON, BS_AUTO3STATE, BS_CHECKBOX, BS_RADIOBUTTON, or BS_3STATE style can be one of the following:

Value	Meaning
0	Button state is unchecked.
1	Button state is checked.
2	Button state is indeterminate (applies only if the button has the BS_3STATE or BS_AUTO3STATE style).
If the button has any other style, the return value is 0.

See Also

»BM_GETSTATE«, »BM_SETCHECK«


  BM_GETSTATE

BM_GETSTATE

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a BM_GETSTATE message to determine the state of a button or check box.

Parameters

This message has no parameters.

Return Value

The return value specifies the current state of the button. You can use the following bitmasks to extract information about the state:

Value	Meaning
0x0003	Specifies the check state (radio buttons and check boxes only). A value of 0 indicates the button is unchecked. A value of 1 indicates the button is checked. A radio button is checked when it contains a dot; a check box is checked when it contains an X. A value of 2 indicates the check state is indeterminate (three-state check boxes only). The state of a three-state check box is indeterminate when it is grayed.
0x0004	Specifies the highlight state. A nonzero value indicates that the button is highlighted. A button is highlighted when the user presses and holds the left mouse button. The highlighting is removed when the user releases the mouse button.
0x0008	Specifies the focus state. A nonzero value indicates that the button has the keyboard focus.
See Also

»BM_GETCHECK«, »BM_SETSTATE«


  BM_SETCHECK

BM_SETCHECK

wParam = (WPARAM) fCheck; /* check state            */

lParam = 0;               /* not used, must be zero */

An application sends a BM_SETCHECK message to set the check state of a radio button or check box.

Parameters

fCheck

Value of wParam. Specifies the check state. This parameter can be one of the following values:

Value	Meaning
0	Set the button state to unchecked.
1	Set the button state to checked.
2	Set the button state to grayed. This value can be used only if the button has the BS_3STATE or BS_AUTO3STATE style.
Return Value

This message always returns zero.

Comments

The BM_SETCHECK message has no effect on push buttons.

See Also

»BM_GETCHECK«, »BM_GETSTATE«, »BM_SETSTATE«


  BM_SETSTATE

BM_SETSTATE

wParam = (WPARAM) fState;   /* highlight state        */

lParam = 0;                 /* not used, must be zero */

An application sends a BM_SETSTATE message to change the highlight state of a button.

Parameters

fState

Value of wParam. Specifies whether the button is to be highlighted. A value of TRUE highlights the button. A value of FALSE removes any highlighting.

Return Value

This message always returns zero.

Comments

Highlighting affects the exterior of a button. It has no effect on the check state of a radio button or check box.

A button is automatically highlighted when the user positions the cursor over it and presses and holds the left mouse button. The highlighting is removed when the user releases the mouse button.

See Also

»BM_GETSTATE«, »BM_SETCHECK«


  BM_SETSTYLE

BM_SETSTYLE

wParam =  (WPARAM) LOWORD(dwStyle); /* style       */

lParam =  MAKELPARAM(fRedraw, 0);   /* redraw flag */

An application sends a BM_SETSTYLE message to change the style of a button.

Parameters

dwStyle

Value of wParam. Specifies the button style. For an explanation of button styles, see the Comments section.

fRedraw

Value of the low-order word of lParam. Specifies whether the button is to be redrawn. A value of TRUE redraws the button. A value of FALSE does not redraw the button.

Return Value

This message always returns zero.

Comments

Following are the available button styles:

Style	Meaning
BS_3STATE	Creates a button that is the same as a check box, except that the box can be grayed as well as checked. Use the grayed state to show that the state of the check box is not determined.
BS_AUTO3STATE	Creates a button that is the same as a three-state check box, except that the box changes its state when the user selects it. The state cycles through checked, grayed, and normal.
BS_AUTOCHECKBOX	Creates a button that is the same as a check box, except that an X appears in the check box when the user selects the box; the X disappears the next time the user selects the box.
BS_AUTORADIOBUTTON	Creates a button that is the same as a radio button, except that when the user selects it, the button automatically highlights itself and removes the selection from any other buttons in the same group.
BS_CHECKBOX	Creates a small empty square, with text displayed to its right, unless this style is combined with the BS_LEFTTEXT style.
BS_DEFPUSHBUTTON	Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style is useful for enabling the user to quickly select the most likely (default) option.
BS_GROUPBOX	Creates a rectangle in which other controls can be grouped. Any text associated with this style is displayed in the rectangle's upper left corner.
BS_LEFTTEXT	Places text on the left side of the radio button or check box when combined with a radio button or check box style.
BS_OWNERDRAW	Creates an owner-drawn button. The owner window receives a WM_MEASUREITEM message when the button is created and a WM_DRAWITEM message when a visual aspect of the button has changed. Do not combine the BS_OWNERDRAW style with any other button styles.
BS_PUSHBOX	Unsupported. Applications should use BS_PUSHBUTTON instead.
BS_PUSHBUTTON	Creates a push button that posts a WM_COMMAND message to the owner window when the user selects the button.
BS_RADIOBUTTON	Creates a small circle that has text displayed to its right, unless this style is combined with the BS_LEFTTEXT style. Use radio buttons for groups of related but mutually exclusive choices.
BS_USERBUTTON	Obsolete. Applications should use BS_OWNERDRAW instead.


  BN_CLICKED

BN_CLICKED

idButton = (int) LOWORD(wParam);    /* identifier of button */

hwndButton = (HWND) lParam;         /* handle of button     */

The BN_CLICKED notification message is sent when the user clicks a mouse button. The parent window of the button receives this notification message through the WM_COMMAND message. Unlike the other button notification messages, this message is intended for applications written for any version of Windows.

Comments

A disabled button does not send a BN_CLICKED notification message to its parent window.

See Also

»WM_COMMAND«


  BN_DISABLE

BN_DISABLE

The BN_DISABLE notification message is sent when a button is disabled. The parent window of the button receives this notification message through the WM_COMMAND message. This notification is provided for compatibility with applications written for versions of Windows earlier than version 3.0. New applications should use the BS_OWNERDRAW button style and the DRAWITEMSTRUCT structure for this task.

See Also

»WM_COMMAND«, »WM_DRAWITEM«


  BN_DOUBLECLICKED

BN_DOUBLECLICKED

The BN_DOUBLECLICKED notification message is sent when the user double-clicks a mouse button. The parent window of the button receives this notification message through the WM_COMMAND message. This notification is provided for compatibility with applications written for versions of Windows earlier than version 3.0. New applications should use the BS_OWNERDRAW button style and the DRAWITEMSTRUCT structure for this task.

Comments

This notification message applies only to buttons with the BS_RADIOBUTTON and BS_OWNERDRAW styles.

See Also

»WM_COMMAND«, »WM_DRAWITEM«


  BN_HILITE

BN_HILITE

The BN_HILITE notification message is sent when the user highlights a button. The parent window of the button receives this notification message through the WM_COMMAND message. This notification is provided for compatibility with applications written for versions of Windows earlier than version 3.0. New applications should use the BS_OWNERDRAW button style and the DRAWITEMSTRUCT structure for this task.

See Also

»BN_UNHILITE« »WM_COMMAND«, »WM_DRAWITEM«


  BN_PAINT

BN_PAINT

The BN_PAINT notification message is sent when a button should be painted. The parent window of the button receives this notification message through the WM_COMMAND message. This notification is provided for compatibility with applications written for versions of Windows earlier than version 3.0. New applications should use the BS_OWNERDRAW button style and the DRAWITEMSTRUCT structure for this task.

See Also

»WM_COMMAND«, »WM_DRAWITEM«


  BN_UNHILITE

BN_HILITE

The BN_UNHILITE notification message is sent when the highlight should be removed from a button. The parent window of the button receives this notification message through the WM_COMMAND message. This notification is provided for compatibility with applications written for versions of Windows earlier than version 3.0. New applications should use the BS_OWNERDRAW button style and the DRAWITEMSTRUCT structure for this task.

See Also

»BN_HILITE«, »WM_COMMAND«, »WM_DRAWITEM«


  CB_ADDSTRING

CB_ADDSTRING

wParam = 0;                         /* not used, must be zero   */

lParam = (LPARAM) (LPCSTR) lpsz;    /* address of string to add */

An application sends a CB_ADDSTRING message to add a string to the list box of a combo box. If the combo box does not have the CBS_SORT style, the string is added to the end of the list. Otherwise, the string is inserted into the list, and the list is sorted.

Parameters

lpsz

Value of lParam. Points to the null-terminated string to be added. If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, the value of the lpsz parameter is stored rather than the string it would otherwise point to.

Return Value

The return value is the zero-based index to the string in the list box of the combo box. If an error occurs, the return value is CB_ERR. If insufficient space is available to store the new string, it is CB_ERRSPACE.

Comments

If you create an owner-drawn combo box with the CBS_SORT style but without the CBS_HASSTRINGS style, the WM_COMPAREITEM message is sent one or more times to the owner of the combo box so the new item can be properly placed in the list.

To insert a string at a specific location within the list, use the CB_INSERTSTRING message.

See Also

»CB_DIR«, »CB_INSERTSTRING«, »WM_COMPAREITEM«


  CB_DELETESTRING

CB_DELETESTRING

wParam = (WPARAM) index;  /* item to delete         */

lParam = 0;               /* not used, must be zero */

An application sends a CB_DELETESTRING message to delete a string in the list box of a combo box.

Parameters

index

Value of wParam. Specifies the zero-based index of the string to delete.

Return Value

The return value is a count of the strings remaining in the list. If the index parameter specifies an index greater than the number of items in the list, the return value is CB_ERR.

Comments

If you create the combo box with an owner-draw style but without the CBS_HASSTRINGS style, Windows sends a WM_DELETEITEM message to the owner of the combo box so the application can free any additional data associated with the item.

See Also

»CB_RESETCONTENT«, »WM_DELETEITEM«


  CB_DIR

CB_DIR

wParam = (WPARAM) (UINT) uAttrs;          /* file attributes     */

lParam = (LPARAM) (LPCTSTR) lpszFileSpec; /* address of filename */

An application sends a CB_DIR message to add a list of file names to the list box of a combo box.

Parameters

uAttrs

Value of wParam. Specifies the attributes of the files to be added to the list box. It can be any combination of the following values:

Value	Description
DDL_ARCHIVE	Includes archived files.
DDL_DIRECTORY	Includes subdirectories. Subdirectory names are enclosed in square brackets ([ ]).
DDL_DRIVES	Includes drives. Drives are listed in the form [-x-], where x is the drive letter.
DDL_EXCLUSIVE	Includes only files with the specified attributes. By default, read-write files are listed even if DDL_READWRITE is not specified.
DDL_HIDDEN	Includes hidden files.
DDL_READONLY	Includes read-only files.
DDL_READWRITE	Includes read-write files with no additional attributes.
DDL_SYSTEM	Includes system files.
lpszFileSpec

Value of lParam. Points to the null-terminated string that specifies the filename to add to the list. If the filename contains any wildcards (for example, *.*), all files that match and have the attributes specified by the uAttrs parameter are added to the list.

Return Value

The return value is the zero-based index of the last filename added to the list. If an error occurs, the return value is CB_ERR. If insufficient space is available to store the new strings, it is CB_ERRSPACE.

See Also

»DlgDirList«, »DlgDirListComboBox«, »CB_ADDSTRING«, »CB_INSERTSTRING«


  CB_FINDSTRING

CB_FINDSTRING

wParam = (WPARAM) indexStart;        /* item before start of search */

lParam = (LPARAM) (LPCSTR) lpszFind; /* prefix string address       */

An application sends a CB_FINDSTRING message to search the list box of a combo box for an item beginning with the characters in a specified string.

Parameters

indexStart

Value of wParam. Specifies the zero-based index of the item preceding the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the indexStart parameter. If indexStart is −1, the entire list box is searched from the beginning.

lpszFind

Value of lParam. Points to the null-terminated string that contains the prefix to search for. The search is not case sensitive, so this string can contain any combination of uppercase and lowercase letters.

Return Value

The return value is the zero-based index of the matching item. If the search is unsuccessful, it is CB_ERR.

Comments

If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, what the CB_FINDSTRING message does depend on whether your application uses the CBS_SORT style. If you use the CBS_SORT style, WM_COMPAREITEM messages are sent to the owner of the combo box to determine which item matches the specified string. The CB_FINDSTRING message searches for a list item that matches the value of the lpszFind parameter.

See Also

»CB_FINDSTRINGEXACT«, »CB_SELECTSTRING«, »CB_SETCURSEL«, »WM_COMPAREITEM«


  CB_FINDSTRINGEXACT

CB_FINDSTRINGEXACT

wParam = (WPARAM) indexStart;      /* item before start of search */

lParam = (LPARAM)(LPCSTR)lpszFind; /* address of prefix string    */

An application sends a CB_FINDSTRINGEXACT message to find the first list box string in a combo box that matches the string specified in the lpszFind parameter.

Parameters

indexStart

Value of wParam. Specifies the zero-based index of the item preceding the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the indexStart parameter. If indexStart is −1, the entire list box is searched from the beginning.

lpszFind

Value of lParam. Points to the null-terminated string to search for. This string can contain a complete filename, including the extension. The search is not case-sensitive, so this string can contain any combination of uppercase and lowercase letters.

Return Value

The return value is the zero-based index of the matching item. If the search is unsuccessful, it is CB_ERR.

Comments

If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, what the CB_FINDSTRINGEXACT message does depends on whether your application uses the CBS_SORT style. If you use the CBS_SORT style, WM_COMPAREITEM messages are sent to the owner of the combo box to determine which item matches the specified string. If you do not use the CBS_SORT style, the CB_FINDSTRINGEXACT message searches for a list item that matches the value of the lpszFind parameter.

See Also

»CB_FINDSTRING«, »CB_SELECTSTRING«, »WM_COMPAREITEM«


  CB_GETCOUNT

CB_GETCOUNT

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a CB_GETCOUNT message to retrieve the number of items in the list box of a combo box.

Parameters

This message has no parameters.

Return Value

The return value is the number of items in the list box. If an error occurs, it is CB_ERR.

Comments

The index is zero-based, so the returned count is one greater than the index value of the last item.


  CB_GETCURSEL

CB_GETCURSEL

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a CB_GETCURSEL message to retrieve the index of the currently selected item, if any, in the list box of a combo box.

Parameters

This message has no parameters.

Return Value

The return value is the zero-based index of the currently selected item. If no item is selected, it is CB_ERR.

See Also

»CB_SELECTSTRING«, »CB_SETCURSEL«


  CB_GETDROPPEDCONTROLRECT

CB_GETDROPPEDCONTROLRECT

wParam = 0;                         /* not used, must be zero    */

lParam = (LPARAM) (RECT FAR*) lprc; /* address of RECT structure */

An application sends a CB_GETDROPPEDCONTROLRECT message to retrieve the screen coordinates of the drop-down list box of a combo box.

Parameters

lprc

Value of lParam. Points to the RECT structure that is to receive the coordinates. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

This message always returns CB_OKAY.


  CB_GETDROPPEDSTATE

CB_GETDROPPEDSTATE

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a CB_GETDROPPEDSTATE message to determine whether the list box of a combo box is dropped down.

Parameters

This message has no parameters.

Return Value

If the list box is visible, the return value is TRUE; otherwise, it is FALSE.

See Also

»CB_SHOWDROPDOWN«


  CB_GETEDITSEL

CB_GETEDITSEL

wParam = (WPARAM) (LPDWORD) lpdwStart; /* receives starting pos. */

lParam = (LPARAM) (LPDWORD) lpdwEnd;   /* receives ending pos.   */

An application sends a CB_GETEDITSEL message to get the starting and ending character positions of the current selection in the edit control of a combo box.

Parameters

lpdwStart

Value of wParam. Points to a 32-bit value that receives the starting position of the selection. This parameter can be set to NULL.

lpdwEnd

Value of lParam. Points to a 32-bit value that receives the ending position of the selection. This parameter can be set to NULL.

Return Value

The return value is a zero-based 32-bit value with the starting position of the selection in the low-order word and with the ending position of the first character after the last selected character in the high-order word.

See Also

»CB_SETEDITSEL«


  CB_GETEXTENDEDUI

CB_GETEXTENDEDUI

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a CB_GETEXTENDEDUI message to determine whether a combo box has the default user interface or the extended user interface.

Parameters

This message has no parameters.

Return Value

If the combo box has the extended user interface, the return value is TRUE; otherwise, it is FALSE.

Comments

By default, the F4 key opens or closes the list and the DOWN ARROW changes the current selection. In a combo box with the extended user interface, the F4 key is disabled and pressing the DOWN ARROW key opens the drop-down list.

See Also

»CB_SETEXTENDEDUI«


  CB_GETITEMDATA

CB_GETITEMDATA

wParam = (WPARAM) index;  /* item index             */

lParam = 0;               /* not used, must be zero */

An application sends a CB_GETITEMDATA message to a combo box to retrieve the application-supplied 32-bit value associated with the specified item in the combo box.

Parameters

index

Value of wParam. Specifies the zero-based index of the item.

Return Value

The return value is the 32-bit value associated with the item. If an error occurs, it is CB_ERR.

If the item is in an owner-drawn combo box created without the CBS_HASSTRINGS style, the return value is the 32-bit value contained in the lParam parameter of the CB_ADDSTRING or CB_INSERTSTRING message that added the item to the combo box. If the CBS_HASSTRINGS style was not used, the return value is the lParam parameter contained in a CB_SETITEMDATA message.

See Also

»CB_ADDSTRING«, »CB_INSERTSTRING«, »CB_SETITEMDATA«


  CB_GETITEMHEIGHT

CB_GETITEMHEIGHT

wParam = (WPARAM) index;  /* item index             */

lParam = 0;               /* not used, must be zero */

An application sends a CB_GETITEMHEIGHT message to determine the height of list items or the selection field in a combo box.

Parameters

index

Value of wParam. Specifies the component of the combo box whose height is to be retrieved.

This parameter must be −1 to retrieve the height of the selection field. It must be zero to retrieve the height of list items, unless the combo box has the CBS_OWNERDRAWVARIABLE style. In that case, the index parameter is the zero-based index of a specific list item.

Return Value

The return value is the height, in pixels, of the list items in a combo box. If the combo box has the CBS_OWNERDRAWVARIABLE style, it is is the height of the item specified by the index parameter. If index is −1, the return value is the height of the edit control (or static-text) portion of the combo box. If an error occurs, the return value is CB_ERR.

See Also

»CB_SETITEMHEIGHT«, »WM_MEASUREITEM«


  CB_GETLBTEXT

CB_GETLBTEXT

wParam = (WPARAM) index;                /* item index        */

lParam = (LPARAM) (LPCSTR) lpszBuffer;  /* address of buffer */

An application sends a CB_GETLBTEXT message to retrieve a string from the list of a combo box.

Parameters

index

Value of wParam. Specifies the zero-based index of the string to retrieve.

lpszBuffer

Value of lParam. Points to the buffer that receives the string. The buffer must have sufficient space for the string and a terminating null character. You can send a CB_GETLBTEXTLEN message prior to the CB_GETLBTEXT message to retrieve the length, in bytes, of the string.

Return Value

The return value is the length of the string, in bytes, excluding the terminating null character. If the index parameter does not specify a valid index, the return value is CB_ERR.

Comments

If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, the buffer pointed to by the lpszBuffer parameter of the message receives the 32-bit value associated with the item.

See Also

»CB_GETLBTEXTLEN«


  CB_GETLBTEXTLEN

CB_GETLBTEXTLEN

wParam = (WPARAM) index;  /* item index             */

lParam = 0;               /* not used, must be zero */

An application sends a CB_GETLBTEXTLEN message to retrieve the length, in characters, of a string in the list of a combo box.

Parameters

index

Value of wParam. Specifies the zero-based index of the string.

Return Value

The return value is the length of the string, in characters, excluding the terminating null character. If the index parameter does not specify a valid index, the return value is CB_ERR.

See Also

»CB_GETLBTEXT«


  CB_GETLOCALE

CB_GETLOCALE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a CB_GETLOCALE message to retrieve the current locale of the combo box. The locale is used to determine the correct sorting order of displayed text for combo boxes with the CBS_SORT style and text added by using the CB_ADDSTRING message.

Parameters

This message has no parameters.

Return Value

The return value is a 32-bit value that specifies the current locale of the combo box. The high word contains the country code and the low word contains the language identifier.

Comments

The language identifier is made up of a sublanguage identifier and a primary language identifier. The PRIMARYLANGID macro obtains the primary language identifier and the SUBLANGID macro obtains the sublanguage identifier.

See Also

»CB_ADDSTRING«, »CB_SETLOCALE«


  CB_INSERTSTRING

CB_INSERTSTRING

wParam = (WPARAM) index;         /* item index                  */

lParam = (LPARAM) (LPCSTR) lpsz; /* address of string to insert */

An application sends a CB_INSERTSTRING message to insert a string into the list box of a combo box. Unlike the CB_ADDSTRING message, the CB_INSERTSTRING message does not cause a list with the CBS_SORT style to be sorted.

Parameters

index

Value of wParam. Specifies the zero-based index of the position at which to insert the string. If this parameter is −1, the string is added to the end of the list.

lpsz

Value of lParam. Points to the null-terminated string to be inserted. If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, the value of the lpsz parameter is stored rather than the string it would otherwise point to.

Return Value

The return value is the index of the position at which the string was inserted. If an error occurs, the return value is CB_ERR. If there is insufficient space available to store the new string, it is CB_ERRSPACE.

See Also

»CB_ADDSTRING«, »CB_INSERTSTRING«, »CB_DIR«


  CB_LIMITTEXT

CB_LIMITTEXT

wParam = (WPARAM) cchLimit;   /* maximum number of characters */

lParam = 0;                   /* not used, must be zero       */

An application sends a CB_LIMITTEXT message to limit the length of the text the user may type into the edit control of a combo box.

Parameters

cchLimit

Value of wParam. Specifies the maximum number of characters the user can enter. If this parameter is zero, the text length is set to 0x7FFFFFFE characters.

Return Value

The return value is always TRUE.

Comments

If the combo box does not have the CBS_AUTOHSCROLL style, setting the text limit to be larger than the size of the edit control has no effect.

The CB_LIMITTEXT message limits only the text the user can enter. It has no effect on any text already in the edit control when the message is sent, nor does it affect the length of the text copied to the edit control when a string in the list box is selected.

The default limit to the text a user can enter in the edit control is 30,000 characters.


  CB_RESETCONTENT

CB_RESETCONTENT

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends a CB_RESETCONTENT message to remove all items from the list box and edit control of a combo box.

Parameters

This message has no parameters.

Return Value

This message always returns CB_OKAY.

Comments

If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, the owner of the combo box receives a WM_DELETEITEM message for each item in the combo box.

See Also

»CB_DELETESTRING«, »WM_DELETEITEM«


  CB_SELECTSTRING

CB_SELECTSTRING

wParam = (WPARAM) indexStart;          /* item before first selection */

lParam = (LPARAM) (LPCSTR) lpszSelect; /* addr. of prefix string      */

An application sends a CB_SELECTSTRING message to search the list of a combo box for an item that begins with the characters in a specified string. If a matching item is found, it is selected and copied to the edit control.

Parameters

indexStart

Value of wParam. Specifies the zero-based index of the item preceding the first item to be searched. When the search reaches the bottom of the list, it continues from the top of the list back to the item specified by the indexStart parameter. If indexStart is −1, the entire list is searched from the beginning.

lpszSelect

Value of lParam. Points to the null-terminated string that contains the prefix to search for. The search is not case sensitive so this string can contain any combination of uppercase and lowercase letters.

Return Value

If the string is found, the return value is the index of the selected item. If the search is unsuccessful, the return value is CB_ERR and the current selection is not changed.

Comments

A string is selected only if the characters from the starting point match the characters in the prefix string.

If you create the combo box with an owner-drawn style but without the CBS_HASSTRINGS style, what the CB_SELECTSTRING message does depends on whether you use the CBS_SORT style. If the CBS_SORT style is used, the system sends WM_COMPAREITEM messages to the owner of the combo box to determine which item matches the specified string. If you do not use the CBS_SORT style, CB_SELECTSTRING attempts to match the doubleword value against the value of the lpszFind parameter.

See Also

»CB_FINDSTRING«, »CB_FINDSTRINGEXACT«, »CB_SETCURSEL«, »WM_COMPAREITEM«


  CB_SETCURSEL

CB_SETCURSEL

wParam = (WPARAM) index;  /* item index             */

lParam = 0;               /* not used, must be zero */

An application sends a CB_SETCURSEL message to select a string in the list of a combo box. If necessary, the list scrolls the string into view. The text in the edit control of the combo box changes to reflect the new selection and any previous selection in the list is removed.

Parameters

index

Value of wParam. Specifies the zero-based index of the string to select. If the index parameter is −1, any current selection in the list is removed and the edit control is cleared.

Return Value

If the message is successful, the return value is the index of the item selected. If the index parameter is greater than the number of items in the list or if index is set to −1, the return value is CB_ERR and the selection is cleared.

See Also

»CB_FINDSTRING«, »CB_GETCURSEL«, »CB_SELECTSTRING«


  CB_SETEDITSEL

CB_SETEDITSEL

wParam = 0;                                /* not used, must be zero */

lParam = MAKELPARAM((ichStart), (ichEnd);  /* start and end pos      */

An application sends a CB_SETEDITSEL message to select characters in the edit control of a combo box.

Parameters

ichStart

Value of the low-order word of lParam. Specifies the starting position. If this parameter is set to −1, the selection, if any, is removed.

ichEnd

Value of the high-order word of lParam. Specifies the ending position. If this parameter is set to −1, all text from the starting position to the last character in the edit control is selected.

Return Value

If the message succeeds, the return value is TRUE. If the message is sent to a combo box with the CBS_DROPDOWNLIST style, it is CB_ERR.

Comments

The positions are zero-based. The first character of the edit control is in the zero position. The first character after the last selected character is in the ending position. For example, to select the first four characters of the edit control, use a starting position of 0 and an ending position of 4.

See Also

»CB_GETEDITSEL«


  CB_SETEXTENDEDUI

CB_SETEXTENDEDUI

wParam = (WPARAM) (BOOL) fExtended;    /* extended UI flag       */

lParam = 0;                            /* not used, must be zero */

An application sends a CB_SETEXTENDEDUI message to select either the default user interface or the extended user interface for a combo box that has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.

Parameters

fExtended

Value of wParam. Specifies whether the combo box uses the extended user interface or the default user interface. A value of TRUE selects the extended user interface; a value of FALSE selects the standard user interface.

Return Value

If the operation succeeds, the return value is CB_OKAY. If an error occurs, it is CB_ERR.

Comments

By default, the F4 key opens or closes the list and the DOWN ARROW changes the current selection. In the extended user interface, the F4 key is disabled and the DOWN ARROW key opens the drop-down list.

See Also

»CB_GETEXTENDEDUI«


  CB_SETITEMDATA

CB_SETITEMDATA

wParam = (WPARAM) index;            /* item index */

lParam = (LPARAM) (DWORD) dwData;   /* item data  */

An application sends a CB_SETITEMDATA message to set the 32-bit value associated with the specified item in a combo box.

Parameters

index

Value of wParam. Specifies the  item's zero-based index.

dwData

Value of lParam. Specifies the new value to be associated with the item.

Return Value

If an error occurs, the return value is CB_ERR.

Comments

If the specified item is in an owner-drawn combo box created without the CBS_HASSTRINGS style, this message replaces the 32-bit value in the lParam parameter of the CB_ADDSTRING or CB_INSERTSTRING message that added the item to the combo box.

See Also

»CB_ADDSTRING«, »CB_GETITEMDATA«, »CB_INSERTSTRING«


  CB_SETITEMHEIGHT

CB_SETITEMHEIGHT

wParam = (WPARAM) index;        /* item index  */

lParam = (LPARAM) (int) height; /* item height */

An application sends a CB_SETITEMHEIGHT message to set the height of list items or the selection field in a combo box.

Parameters

index

Value of wParam. Specifies the component of the combo box for which to set the height.

This parameter must be −1 to set the height of the selection field. It must be zero to set the height of list items, unless the combo box has the CBS_OWNERDRAWVARIABLE style. In that case, the index parameter is the zero-based index of a specific list item.

height

Value of lParam. Specifies the height, in pixels, of the combo box component identified by index.

Return Value

If the index or height is invalid, the return value is CB_ERR.

Comments

The selection field height in a combo box is set independently of the height of the list items. An application must ensure that the height of the selection field is not smaller than the height of a particular list item.

See Also

»CB_GETITEMHEIGHT«, »WM_MEASUREITEM«


  CB_SETLOCALE

CB_SETLOCALE

wParam = (WPARAM) (WORD) wLocaleID; /* locale identifier      */

lParam = 0;                         /* not used, must be zero */

An application sends a CB_SETLOCALE message to set the current locale of the combo box. If the combo box has the CBS_SORT style and strings are added using CB_ADDSTRING, the locale of a combo box affects how list items are sorted.

Parameters

wLocaleID

Value of wParam. Specifies the locale identifier for the combo box to use for sorting when adding text.

Return Value

The return value is the previous locale identifier. If wParam specifies a locale not installed on the system, the return value is CB_ERR and the current combo box locale is not changed.

Comments

Use the MAKELCID macro to construct a locale identifier and the MAKELANGID macro to construct a language identifier. The language identifier is made up of a primary language identifier and a sublanguage identifier.

See Also

»CB_ADDSTRING«, »CB_GETLOCALE«


  CB_SHOWDROPDOWN

CB_SHOWDROPDOWN

wParam = (WPARAM) (BOOL) fShow;     /* the show/hide flag     */

lParam = 0;                         /* not used, must be zero */

An application sends a CB_SHOWDROPDOWN message to show or hide the list box of a combo box that has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.

Parameters

fShow

Value of wParam. Specifies whether the drop-down list box is to be shown or hidden. A value of TRUE shows the list box; a value of FALSE hides it.

Return Value

The return value is always TRUE.

Comments

This message has no effect on a combo box created with the CBS_SIMPLE style.

See Also

»CB_GETDROPPEDSTATE«


  CBN_CLOSEUP

CBN_CLOSEUP

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_CLOSEUP notification message is sent when the list box of a combo box has been closed. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

This notification message is not sent to a combo box that has the CBS_SIMPLE style.

In general, you cannot predict the order in which notifications will be sent. In particular, a CBN_SELCHANGE notification may occur either before or after a CBN_CLOSEUP notification.

See Also

»CBN_DROPDOWN«, »CBN_SELCHANGE«, »WM_COMMAND«


  CBN_DBLCLK

CBN_DBLCLK

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_DBLCLK notification message is sent when the user double-clicks a string in the list box of a combo box. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

This notification message occurs only for a combo box with the CBS_SIMPLE style. In a combo box with the DBS_DROPDOWN or CBS_DROPDOWNLIST style, a double-click cannot occur because a single click closes the list box.

See Also

»CBN_SELCHANGE«, »WM_COMMAND«


  CBN_DROPDOWN

CBN_DROPDOWN

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_DROPDOWN notification message is sent when the list box of a combo box is about to be made visible. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

This notification message can occur only for a combo box with the CBS_DROPDOWN or CBS_DROPDOWNLIST style.

See Also

»CBN_CLOSEUP«, »WM_COMMAND«


  CBN_EDITCHANGE

CBN_EDITCHANGE

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND)lParam;        /* handle of combo box     */

The CBN_EDITCHANGE notification message is sent after the user has taken an action that may have altered the text in the edit control portion of a combo box. Unlike the CBN_EDITUPDATE notification message, this notification message is sent after Windows updates the screen. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

If the combo box has the CBS_DROPDOWNLIST style, this notification message does not occur.

See Also

»CBN_EDITUPDATE«, »WM_COMMAND«


  CBN_EDITUPDATE

CBN_EDITUPDATE

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_EDITUPDATE notification message is sent when the edit control portion of a combo box is about to display altered text. This notification is sent after the control has formatted the text, but before it displays the text. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

If the combo box has the CBS_DROPDOWNLIST style, this notification message does not occur.

See Also

»CBN_EDITCHANGE«, »WM_COMMAND«


  CBN_ERRSPACE

CBN_ERRSPACE

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_ERRSPACE notification message is sent when a combo box cannot allocate enough memory to meet a specific request. The parent window of the combo box receives this notification message through the WM_COMMAND message.

See Also

»WM_COMMAND«


  CBN_KILLFOCUS

CBN_KILLFOCUS

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_KILLFOCUS notification message is sent when a combo box loses the keyboard focus. The parent window of the combo box receives this notification message through the WM_COMMAND message.

See Also

»CBN_SETFOCUS«, »WM_COMMAND«


  CBN_SELCHANGE

CBN_SELCHANGE

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_SELCHANGE notification message is sent when the selection in the list box of a combo box is about to be changed as a result of the user either clicking in the list box or changing the selection by using the arrow keys. The parent window of the combo box receives this message through the WM_COMMAND message.

See Also

»CBN_DBLCLK«, »CB_SETCURSEL«, »WM_COMMAND«


  CBN_SELENDCANCEL

CBN_SELENDCANCEL

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_SELENDCANCEL notification is sent when the user selects an item, but then selects another control or closes the dialog box. It indicates the user's initial selection is to be ignored. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

In a combo box with the CBS_SIMPLE style, the CBN_SELENDCANCEL notification message is not sent. The CBN_SELENDOK notification message is sent immediately before every CBN_SELCHANGE message.

If the WS_EX_NOPARENTNOTIFY extended window style is specified for the combo box, the CBN_SELENDCANCEL notification message is not sent.

See Also

»CBN_SELENDOK«, »WM_COMMAND«


  CBN_SELENDOK

CBN_SELENDOK

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_SELENDOK notification is sent when the user clicks a list item, or selects an item and then closes the list. It indicates the user's selection is to be processed. The parent window of the combo box receives this notification message through the WM_COMMAND message.

Comments

In a combo box with the CBS_SIMPLE style, the CBN_SELENDOK notification message is sent immediately before every CBN_SELCHANGE message.

If the WS_EX_NOPARENTNOTIFY extended window style is specified for the combo box, the CBN_SELENDOK notification message is not sent.

See Also

»CBN_SELENDCANCEL«, »WM_COMMAND«


  CBN_SETFOCUS

CBN_SETFOCUS

idComboBox = (int) LOWORD(wParam);  /* identifier of combo box */

hwndComboBox = (HWND) lParam;       /* handle of combo box     */

The CBN_SETFOCUS notification message is sent when a combo box receives the keyboard focus. The parent window of the combo box receives this notification message through the WM_COMMAND message.

See Also

»CBN_KILLFOCUS«, »WM_COMMAND«


  CPL_DBLCLK

CPL_DBLCLK

uAppNum = (UINT) lParam1;   /* application number        */

lData = (LONG) lParam2;     /* application-defined value */

The CPL_DBLCLK message is sent to a Windows Control Panel dynamic-link library (DLL) when the user double-clicks the icon of an application supported by the DLL.

Parameters

uAppNum

Value of lParam1. Specifies the application number. This number must be in the range zero through one less than the value returned in response to the CPL_GETCOUNT message (CPL_GETCOUNT − 1).

lData

Value of lParam2. Specifies the value that the Control Panel DLL loaded into the lData member of the CPLINFO or NEWCPLINFO structure for the application. The DLL loads lData member in response to the CPL_INQUIRE or CPL_NEWINQUIRE message.

Return Value

If a Control Panel DLL processes this message successfully, the return value is zero; otherwise, it is nonzero.

Comments

In response to this message, a Control Panel DLL must display the dialog box for the application.

See Also

»CPL_GETCOUNT«, »CPL_INQUIRE«, »CPL_NEWINQUIRE«, »CPL_SELECT«


  CPL_EXIT

CPL_EXIT

The CPL_EXIT message is sent once to a Windows Control Panel dynamic-link library (DLL) before Control Panel calls the FreeLibrary function to free the DLL.

Parameters

This function has no parameters.

Return Value

If a Control Panel DLL processes this message successfully, it should return zero.

Comments

This message is sent after the last WM_STOP message is sent.

In response to this message, a Control Panel DLL must free any memory that it has allocated and perform global-level cleanup.

See Also

»CPL_STOP«, »FreeLibrary«


  CPL_GETCOUNT

CPL_GETCOUNT

The CPL_GETCOUNT message is sent to a Windows Control Panel dynamic-link library (DLL) to retrieve the number of applications the DLL services.

Parameters

This function has no parameters.

Return Value

A Control Panel DLL should return the number of applications it services.

Comments

This message is sent immediately after the CPL_INIT message.

See Also

»CPL_INIT«


  CPL_INIT

CPL_INIT

The CPL_INIT message is sent to a Windows Control Panel dynamic-link library (DLL) to prompt the DLL to perform global initialization, especially memory allocation.

Parameters

This function has no parameters.

Return Value

If initialization succeeds, a Control Panel DLL should return nonzero. Otherwise, it should return zero. If the DLL returns zero, Control Panel calls the FreeLibrary function and ends communication with the DLL.

Comments

Because this is the only way a Control Panel DLL can signal an error condition, the DLL should allocate memory in response to this message.

This message is sent immediately after the DLL is loaded.

See Also

»FreeLibrary«


  CPL_INQUIRE

CPL_INQUIRE

uAppNum = (UINT) lParam1;     /* application number              */

lpcpli = (LPCPLINFO) lParam2; /* structure for application info. */

The CPL_INQUIRE message is sent to a Windows Control Panel dynamic-link library (DLL) to request information about an application that the DLL supports.

This message is provided for backward compatibility with Windows, version 3.1. Use the CPL_NEWINQUIRE message instead of the CPL_INQUIRE message for new applications.

Parameters

uAppNum

Value of lParam1. Specifies the application number. This number must be in the range zero through one less than the value returned in response to the CPL_GETCOUNT message (CPL_GETCOUNT − 1).

lpcpli

Value of lParam2. Points to a CPLINFO structure. The DLL must fill this structure with resource identifiers for the icon, short name, description, and any user-defined value associated with the application. The CPLINFO structure has the following form:

typedef struct tagCPLINFO { /* cpli */

    int  idIcon;

    int  idName;

    int  idInfo;

    LONG lData;

} CPLINFO;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If a Control Panel DLL processes this message successfully, it should return zero.

Comments

This message is sent once for each application serviced by the DLL. It is sent immediately after the CPL_GETCOUNT message. A DLL can perform application-level initialization when it receives this message. If the DLL must allocate memory, it should do so in response to the CPL_INIT message.

See Also

»CPL_GETCOUNT«, »CPL_INIT«, »CPL_NEWINQUIRE«


  CPL_NEWINQUIRE

CPL_NEWINQUIRE

uAppNum = (UINT) lParam1;         /* application number        */

lpncpli = (LPNEWCPLINFO) lParam2; /* structure for appl. info. */

The CPL_NEWINQUIRE message is sent to a Windows Control Panel dynamic-link library (DLL) to request information about an application that the DLL supports.

Parameters

uAppNum

Value of lParam1. Specifies the application number. This number must be in the range zero through one less than the value returned in response to the CPL_GETCOUNT message (CPL_GETCOUNT − 1).

lpncpli

Value of lParam2. Specifies a far pointer to a NEWCPLINFO structure. The DLL should fill this structure with information about the application. The CPLINFO structure has the following form:

typedef struct tagNEWCPLINFO {  /* ncpli */

    DWORD dwSize;

    DWORD dwFlags;

    DWORD dwHelpContext;

    LONG  lData;

    HICON hIcon;

    char  szName[32];

    char  szInfo[64];

    char  szHelpFile[128];

} NEWCPLINFO;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If a Control Panel DLL processes this message successfully, it should return zero.

Comments

This message is sent once for each application serviced by the DLL. It is sent immediately after the CPL_GETCOUNT message. Upon receiving this message, a DLL can do application-level initialization. If the DLL must allocate memory, it should do so in response to the CPL_INIT message.

See Also

»CPL_GETCOUNT«, »CPL_INIT«, »CPL_INQUIRE«


  CPL_SELECT

CPL_SELECT

uAppNum = (UINT) lParam1;   /* application number        */

lData = (LONG) lParam2;     /* application-defined value */

The CPL_SELECT message from Windows Control Panel is sent to a Control Panel dynamic-link library (DLL) when the user selects the icon of an application supported by the DLL.

Parameters

uAppNum

Value of lParam1. Specifies the application number.

lData

Value of lParam2. Specifies the value that the Control Panel DLL loaded into the lData member of the CPLINFO or NEWCPLINFO structure for the application. The DLL loads lData member in response to the CPL_INQUIRE or CPL_NEWINQUIRE message.

Return Value

If a Control Panel DLL processes this message successfully, it should return zero.

See Also

»CPL_DBLCLK«, »CPL_INQUIRE«, »CPL_NEWINQUIRE«


  CPL_STOP

CPL_STOP

uAppNum = (UINT) lParam1;   /* application number        */

lData = (LONG) lParam2;     /* application-defined value */

The CPL_STOP message is sent once for each application when Windows Control Panel closes.

Parameters

uAppNum

Value of lParam1. Specifies the application number.

lData

Value of lParam2. Specifies the value that the Control Panel DLL loaded into the lData member of the CPLINFO or NEWCPLINFO structure for the application. The DLL loads lData member in response to the CPL_INQUIRE or CPL_NEWINQUIRE message.

Return Value

If a Control Panel DLL processes this message successfully, it should return zero.

Comments

In response to this message, a Control Panel DLL must perform application-specific cleanup.

See Also

»CPL_EXIT«, »CPL_GETCOUNT«, »CPL_INQUIRE« »CPL_NEWINQUIRE«


  DM_GETDEFID

DM_GETDEFID

An application sends a DM_GETDEFID message to retrieve the identifier of the default push button control for a dialog box.

Parameters

This message has no parameters.

Return Value

If a default push button exists, the high-order word of the return value contains the value DC_HASDEFID and the low-order word contains the control identifier. Otherwise, the return value is zero.

Comments

The DefDlgProc function processes this message.

See Also

»DefDlgProc«, »DM_SETDEFID«


  DM_SETDEFID

DM_SETDEFID

wParam = idControl; /* identifier of new default push button */

An application sends a DM_SETDEFID message to change the identifier of the default push button for a dialog box.

Parameters

idControl

Value of wParam. Specifies the identifier of a push button control that will become the default.

Comments

This message is processed by the DefDlgProc function. To set the default push button, the function can send WM_GETDLGCODE and BM_SETSTYLE messages to the given control and the current default push button.

Using the DM_SETDEFID message can result in more than one button appearing to have the default push button state. When Windows NT brings up a dialog, it draws the first push button in the dialog template with the default state border. Sending a DM_SETDEFID message to change ,the default button will not always remove the default state border from the first push button. In these cases, the application should send a BM_SETSTYLE message to change the first push button border style.

Return Value

The return value is always TRUE.

See Also

»DefDlgProc«, »BM_SETSTYLE«, »DM_GETDEFID«, »WM_GETDLGCODE«


  EM_CANUNDO

EM_CANUNDO

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_CANUNDO message to determine whether an edit-control operation can be undone; that is, whether the control can respond to the EM_UNDO message.

Parameters

This message has no parameters.

Return Value

If the edit control can correctly process the EM_UNDO message, the return value is TRUE; otherwise, it is FALSE.

See Also

»EM_UNDO«


  EM_EMPTYUNDOBUFFER

EM_EMPTYUNDOBUFFER

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_EMPTYUNDOBUFFER message to reset the undo flag of an edit control. The undo flag is set whenever an operation within the edit control can be undone.

Parameters

This message has no parameters.

Return Value

This message does not return a value.

Comments

The undo flag is automatically reset whenever the edit control receives a WM_SETTEXT or EM_SETHANDLE message.

See Also

»EM_CANUNDO«, »EM_SETHANDLE«, »EM_UNDO«, »WM_SETTEXT«


  EM_FMTLINES

EM_FMTLINES

wParam = (WPARAM) (BOOL) fAddEOL;   /* line break flag        */

lParam = 0;                         /* not used, must be zero */

An application sends an EM_FMTLINES message to set the inclusion flag of soft line-break characters on or off within a multiline edit control. A soft line break consists of two carriage returns and a linefeed and is inserted at the end of a line that is broken because of wordwrapping.

Parameters

fAddEOL

Value of wParam. Specifies whether soft-line break characters are to be inserted. A value of TRUE inserts the characters; a value of FALSE removes them.

Return Value

The return value is identical to the fAddEOL parameter.

Comments

This message affects only the buffer returned by the EM_GETHANDLE message and the text returned by the WM_GETTEXT message. It has no effect on the display of the text within the edit control.

The EM_FMTLINES message does not affect a line that ends with a hard line break. A hard line break consists of one carriage return and a linefeed.

Note that the size of the text changes when this message is processed.

See Also

»EM_GETHANDLE«, »WM_GETTEXT«


  EM_GETFIRSTVISIBLELINE

EM_GETFIRSTVISIBLELINE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_GETFIRSTVISIBLELINE message to determine the uppermost visible line in an edit control.

Parameters

This message has no parameters.

Return Value

The return value is the zero-based index of the uppermost visible line in a multiline edit control. For single-line edit controls, the return value is the zero-based index of the first visible character.


  EM_GETHANDLE

EM_GETHANDLE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_GETHANDLE message to retrieve a handle of the memory currently allocated for a multiline edit control's text.

Parameters

This message has no parameters.

Return Value

The return value is a memory handle identifying the buffer that holds the contents of the edit control. If an error occurs, such as sending the message to a single-line edit control, the return value is zero.

Comments

In a 16-bit Windows-based application, the handle is a local memory handle and can be used only by functions that take a local memory handle as a parameter. The application can send this message to a multiline edit control in a dialog box only if it created the dialog box with the DS_LOCALEDIT style flag set. If the DS_LOCALEDIT style is not set, the return value is still nonzero, but the return value will not be meaningful.

See Also

»EM_SETHANDLE«


  EM_GETLINE

EM_GETLINE

wParam = (WPARAM) line;          /* line number to retrieve    */

lParam = (LPARAM) (LPCSTR) lpch; /* address of buffer for line */

An application sends an EM_GETLINE message to copy a line of text from an edit control and place it in a specified buffer.

Parameters

line

Value of wParam. Specifies the zero-based index of the line to retrieve from a multiline edit control. A value of zero specifies the topmost line. This parameter is ignored by a single-line edit control.

lpch

Value of lParam. Points to the buffer that receives a copy of the line. The first word of the buffer specifies the maximum number of characters that can be copied to the buffer.

Return Value

The return value is the number of characters copied. The return value is zero if the line number specified by the line parameter is greater than the number of lines in the edit control.

Comments

The copied line does not contain a terminating null character.

See Also

»EM_LINELENGTH«, »WM_GETTEXT«


  EM_GETLINECOUNT

EM_GETLINECOUNT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_GETLINECOUNT message to retrieve the number of lines in a multiline edit control.

Parameters

This message has no parameters.

Return Value

The return value is an integer specifying the number of lines in the multiline edit control. If no text is in the edit control, the return value is 1.

See Also

»EM_GETLINE«, »EM_LINELENGTH«


  EM_GETMODIFY

EM_GETMODIFY

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_GETMODIFY message to determine whether the contents of an edit control have been modified.

Parameters

This message has no parameters.

Return Value

If the contents of edit control have been modified, the return value is TRUE; otherwise, it is FALSE.

Comments

Windows maintains an internal flag indicating whether the contents of the edit control have been changed. This flag is cleared when the edit control is first created; alternatively, an application can send an EM_SETMODIFY message to the edit control to clear the flag.

See Also

»EM_SETMODIFY«


  EM_GETPASSWORDCHAR

EM_GETPASSWORDCHAR

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_GETPASSWORDCHAR message to retrieve the password character displayed in an edit control when the user enters text.

Parameters

This message has no parameters.

Return Value

The return value specifies the character to be displayed in place of the character typed by the user. The return value is NULL if no password character exists.

Comments

If the edit control is created with the ES_PASSWORD style, the default password character is set to an asterisk (*).

See Also

»EM_SETPASSWORDCHAR«


  EM_GETRECT

EM_GETRECT

wParam = 0;                    /* not used, must be zero         */

lParam (LPARAM) (LPRECT) lprc; /* address of structure for rect. */

An application sends an EM_GETRECT message to retrieve the formatting rectangle of an edit control. The formatting rectangle is the limiting rectangle of the text. The limiting rectangle is independent of the size of the edit-control window.

Parameters

lprc

Value of lParam. Points to the RECT structure that receives the formatting rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

The return value is not a meaningful value.

Comments

You can modify the formatting rectangle of a multiline edit control by using the EM_SETRECT and EM_SETRECTNP messages.

See Also

»EM_SETRECT«, »EM_SETRECTNP«


  EM_GETSEL

EM_GETSEL

wParam = (WPARAM) (LPDWORD) lpdwStart; /* receives starting pos. */

lParam = (WPARAM) (LPDWORD) lpdwEnd;   /* receives ending pos.   */

An application sends an EM_GETSEL message to get the starting and ending character positions of the current selection in an edit control.

Parameters

lpdwStart

Value of wParam. Points to a 32-bit value that receives the starting position of the selection. This parameter can be NULL.

lpdwEnd

Value of lParam. Points to a 32-bit value that receives the position of the first nonselected character after the end of the selection. This parameter can be NULL.

Return Value

The return value is a zero-based 32-bit value with the starting position of the selection in the low-order word and the position of the first character after the last selected character in the high-order word.

See Also

»EM_SETSEL«


  EM_GETWORDBREAKPROC

EM_GETWORDBREAKPROC

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_GETWORDBREAKPROC message to an edit control to retrieve the address of the current wordwrap function.

Parameters

This message has no parameters.

Return Value

The return value specifies the address of the application-defined wordwrap function. The return value is NULL if no wordwrap function exists.

Comments

A wordwrap function scans a text buffer that contains text to be sent to the display, looking for the first word that does not fit on the current display line. The wordwrap function places this word at the beginning of the next line on the display. A wordwrap function defines the point at which Windows should break a line of text for multiline edit controls, usually at a space character that separates two words.

See Also

»WordBreakProc«, »EM_FMTLINES«, »EM_SETWORDBREAKPROC«


  EM_LIMITTEXT

EM_LIMITTEXT

wParam = (WPARAM) cchMax;   /* text length            */

lParam = 0;                 /* not used, must be zero */

An application sends an EM_LIMITTEXT message to limit the amount of text the user may enter into an edit control.

Parameters

cchMax

Value of wParam. Specifies the maximum number of characters the user can enter. If this parameter is zero, the text length is set to 0x7FFFFFFE characters for single-line edit controls or 0xFFFFFFFF for multiline edit controls.

Return Value

This message does not return a value.

Comments

The EM_LIMITTEXT message limits only the text the user can enter. It has no effect on any text already in the edit control when the message is sent, nor does it affect the length of the text copied to the edit control by the WM_SETTEXT message. If an application uses the WM_SETTEXT message to place more text into an edit control than is specified in the EM_LIMITTEXT message, the user can edit the entire contents of the edit control.

The default limit to the amount of text a user can enter in an edit control is 30,000 characters.

See Also

»WM_SETTEXT«


  EM_LINEFROMCHAR

EM_LINEFROMCHAR

wParam = (WPARAM) ich;  /* character index        */

lParam = 0;             /* not used, must be zero */

An application sends an EM_LINEFROMCHAR message to retrieve the index of the line that contains the specified character index in a multiline edit control. A character index is the number of characters from the beginning of the edit control.

Parameters

ich

Value of wParam. Specifies the character index of the character contained in the line whose number is to be retrieved. If the ich parameter is −1, either the line number of the current line (the line containing the caret) is retrieved or, if there is a selection, the line number of the line containing the beginning of the selection is retrieved.

Return Value

The return value is the zero-based line number of the line containing the character index specified by ich.

See Also

»EM_LINEINDEX«


  EM_LINEINDEX

EM_LINEINDEX

wParam = (WPARAM) line; /* line number            */

lParam = 0;             /* not used, must be zero */

An application sends an EM_LINEINDEX message to retrieve the character index of a line in a multiline edit control. The character index is the number of characters from the beginning of the edit control to the specified line.

Parameters

line

Value of wParam. Specifies the zero-based line number. A value of −1 specifies the current line number (the line that contains the caret).

Return Value

The return value is the character index of the line specified in the line parameter, or it is −1 if the specified line number is greater than the number of lines in the edit control.

See Also

»EM_LINEFROMCHAR«


  EM_LINELENGTH

EM_LINELENGTH

wParam = (WPARAM) ich;  /* character index        */

lParam = 0;             /* not used, must be zero */

An application sends an EM_LINELENGTH message to retrieve the length of a line, in characters, in an edit control.

Parameters

ich

Value of wParam. Specifies the character index of a character in the line whose length is to be retrieved when EM_LINELENGTH is sent to a multiline edit control. If this parameter is −1, the message returns the number of unselected characters on lines containing selected characters. For example, if the selection extended from the fourth character of one line through the eighth character from the end of the next line, the return value would be 10 (three characters on the first line and seven on the next).

Return Value

The return value is the length, in characters, of the line specified by the ich parameter when an EM_LINELENGTH message is sent to a multiline edit control. The return value is the length, in characters, of the text in the edit control when an EM_LINELENGTH message is sent to a single-line edit control.

Comments

Use the EM_LINEINDEX message to retrieve a character index for a given line number within a multiline edit control.

See Also

»EM_LINEINDEX«


  EM_LINESCROLL

EM_LINESCROLL

wParam = (WPARAM) cxScroll; /* characters to scroll horizontally */

lParam = (LPARAM) cyScroll; /* lines to scroll vertically        */

An application sends an EM_LINESCROLL message to scroll the text vertically or horizontally in a multiline edit control.

Parameters

cxScroll

Value of wParam. Specifies the number of characters to scroll horizontally.

cyScroll

Value of lParam. Specifies the number of lines to scroll vertically.

Return Value

If the message is sent to a multiline edit control, the return value is TRUE; if the message is sent to a single-line edit control, the return value is FALSE.

Comments

The edit control does not scroll vertically past the last line of text in the edit control. If the current line plus the number of lines specified by the cyScroll parameter exceeds the total number of lines in the edit control, the value is adjusted so that the last line of the edit control is scrolled to the top of the edit-control window.

The EM_LINESCROLL message can be used to scroll horizontally past the last character of any line.


  EM_REPLACESEL

EM_REPLACESEL

wParam = 0;                               /* not used, must be zero */

lParam = (LPARAM) (LPCTSTR) lpszReplace;  /* address of string      */

An application sends an EM_REPLACESEL message to replace the current selection in an edit control with the specified text.

Parameters

lpszReplace

Value of lParam. Points to a null-terminated string containing the replacement text.

Return Value

This message does not return a value.

Comments

Use the EM_REPLACESEL message to replace only a portion of the text in an edit control. To replace all of the text, use the WM_SETTEXT message.

If there is no current selection, the replacement text is inserted at the current location of the caret.

See Also

»WM_SETTEXT«


  EM_SCROLLCARET

EM_SCROLLCARET

wParam = 0 ;    /* not used now; reserved for future use; must be zero  */

lParam = 0 ;    /* not used now; reserved for future use; must be zero */

An application sends an EM_SCROLLCARET message to scroll the caret into view in an edit control.

Parameters

wParam

This parameter is currently unused. It is reserved for future use. It should be set to zero.

lParam

This parameter is currently unused. It is reserved for future use. It should be set to zero.

Return Value

The return value is nonzero if the message is sent to an edit control.

Comments

In previous versions of Windows, scrolling the caret into view was done by specifying fScroll = FALSE in the EM_SETSEL message. A Win32 application should use the EM_SCROLLCARET message to scroll the caret into view.

See Also

»EM_SETSEL«


  EM_SCROLL

EM_SCROLL

wParam = (WPARAM) (INT) nScroll;    /* scroll action          */

lParam = 0;                         /* not used, must be zero */

An application sends an EM_SCROLL message to scroll the text vertically in a multiline edit control. This message is equivalent to sending a WM_VSCROLL message to the edit control.

Parameters

nScroll

Value of wParam. Specifies the action the scroll bar is to take. This parameter may be one of the following values:

Value	Description
SB_LINEDOWN	Scroll down one line.
SB_LINEUP	Scroll up one line.
SB_PAGEDOWN	Scroll down one page.
SB_PAGEUP	Scroll up one page.
Return Value

If the message is successful, the high-order word of the return value is TRUE and the low-order word is the number of lines that the command scrolls. The number returned may not be the same as the actual number of lines scrolled if the scrolling moves to the beginning or the end of the text. If the nScroll parameter specifies an invalid value, the return value is FALSE.

Comments

An application should use the EM_LINESCROLL message to scroll to a specific line or character position.

An application should use the EM_SCROLLCARET message to scroll the caret into view.

See Also

»EM_LINESCROLL«, »EM_SCROLLCARET« »WM_VSCROLL«


  EM_SETHANDLE

EM_SETHANDLE

wParam = (WPARAM) (HLOCAL) hloc; /* handle of memory buffer */

lParam = 0;                      /* not used, must be zero  */

An application sends an EM_SETHANDLE message to set the handle of the memory that will be used by a multiline edit control.

Parameters

hloc

Value of wParam. Identifies the memory the edit control uses to store the currently displayed text instead of allocating its own memory. If necessary, the control reallocates this memory.

Return Value

This message does not return a value.

Comments

Before an application sets a new memory handle, it should send an EM_GETHANDLE  message to retrieve the handle of the current memory buffer and should free that memory.

An edit control automatically reallocates the given buffer whenever it needs additional space for text, or it removes enough text so that additional space is no longer needed.

Sending an EM_SETHANDLE message clears the undo buffer (EM_CANUNDO returns zero) and the internal modification flag (EM_GETMODIFY returns zero). The edit control window is redrawn.

An application can send this message to a multiline edit control in a dialog box only if it has created the dialog box with the DS_LOCALEDIT style flag set.

See Also

»EM_CANUNDO«, »EM_GETHANDLE«, »EM_GETMODIFY«


  EM_SETMODIFY

EM_SETMODIFY

wParam = (WPARAM) (UINT) fModified;    /* modification flag      */

lParam = 0;                            /* not used, must be zero */

An application sends an EM_SETMODIFY message to set or clear the modification flag for an edit control. The modification flag indicates whether the text within the edit control has been modified. It is automatically set whenever the user changes the text. An EM_GETMODIFY message can be sent to retrieve the value of the modification flag.

Parameters

fModified

Value of wParam. Specifies the new value for the modification flag. A value of TRUE indicates the text has been modified, and a value of FALSE indicates it has not been modified.

Return Value

This message does not return a value.

See Also

»EM_GETMODIFY«


  EM_SETPASSWORDCHAR

EM_SETPASSWORDCHAR

wParam = (WPARAM) (UINT) ch;    /* character to display   */

lParam = 0;                     /* not used, must be zero */

An application sends an EM_SETPASSWORDCHAR message to set or remove a password character displayed in a single-line edit control when the user types text. When a password character is set, that character is displayed in place of each character the user types.

Parameters

ch

Value of wParam. Specifies the character to be displayed in place of the character typed by the user. If this parameter is zero, the characters typed by the user are displayed.

Return Value

This message does not return a value.

Comments

When the EM_SETPASSWORDCHAR message is received by an edit control, the edit control redraws all visible characters by using the character specified by the ch parameter.

If the edit control is created with the ES_PASSWORD style, the default password character is set to an asterisk (*). This style is removed if an EM_SETPASSWORDCHAR message is sent with the ch parameter set to zero.

See Also

»EM_GETPASSWORDCHAR«


  EM_SETREADONLY

EM_SETREADONLY

wParam = (WPARAM) (BOOL) fReadOnly;  /* read-only flag         */

lParam = 0L;                         /* not used, must be zero */

An application sends an EM_SETREADONLY message to set or remove the read-only style (ES_READONLY) of an edit control.

Parameters

fReadOnly

Value of wParam. Specifies whether to set or remove the ES_READONLY style. A value of TRUE sets the ES_READONLY style; a value of FALSE removes the ES_READONLY style.

Return Value

If the operation succeeds, the return value is nonzero; otherwise, it is zero.

Comments

When an edit control has the ES_READONLY style, the user cannot change the text within the edit control.

To determine whether an edit control has the ES_READONLY style, use the GetWindowLong function with the GWL_STYLE flag.

See Also

»GetWindowLong«


  EM_SETRECT

EM_SETRECT

wParam = 0;                         /* not used, must be zero   */

lParam = (LPARAM) (LPRECT) lprc;    /* address of new rectangle */

An application sends an EM_SETRECT message to set the formatting rectangle of a multiline edit control. The formatting rectangle is the limiting rectangle of the text. The limiting rectangle is independent of the size of the edit control window. When the edit control is first created, the formatting rectangle is the same as the client area of the edit control window. By using the EM_SETRECT message, an application can make the formatting rectangle larger or smaller than the edit control window.

This message is processed only by multiline edit controls.

Parameters

lprc

Value of lParam. Points to a RECT structure that specifies the new dimensions of the rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

This message does not return a value.

Comments

The EM_SETRECT message causes the text of the edit control to be redrawn. To change the size of the formatting rectangle without redrawing the text, use the EM_SETRECTNP message.

If the edit control does not have a horizontal scroll bar, and the formatting rectangle is set to be larger than the edit control window, lines of text exceeding the width of the edit control window (but smaller than the width of the formatting rectangle) are clipped instead of wrapped.

If the edit control contains a border, the formatting rectangle is reduced by the size of the border. If you are adjusting the rectangle returned by an EM_GETRECT message, you must remove the size of the border before using the rectangle with the EM_SETRECT message.

See Also

»EM_GETRECT«, »EM_SETRECTNP«


  EM_SETRECTNP

EM_SETRECTNP

wParam = 0;                         /* not used, must be zero   */

lParam = (LPARAM) (LPRECT) lprc;    /* address of new rectangle */

An application sends an EM_SETRECTNP message to set the formatting rectangle of a multiline edit control. The formatting rectangle is the limiting rectangle of the text. The limiting rectangle is independent of the size of the edit control window. When the edit control is first created, the formatting rectangle is the same as the client area of the edit control window. By using the EM_SETRECTNP message, an application can make the formatting rectangle larger or smaller than the edit control window.

The EM_SETRECTNP message is identical to the EM_SETRECT message, except that the edit control window is not redrawn.

This message is processed only by multiline edit controls.

Parameters

lprc

Value of lParam. Points to a RECT structure that specifies the new dimensions of the rectangle. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

This message does not return a value.

See Also

»EM_SETRECT«


  EM_SETSEL

EM_SETSEL

wParam = (WPARAM) (INT) nStart;    /* starting position */

lParam = (LPARAM) (INT) nEnd;      /* ending position   */

An application sends an EM_SETSEL message to select a range of characters in an edit control.

Parameters

nStart

Value of wParam. Specifies the starting character position of the selection.

nEnd

Specifies the ending character position of the selection.

Return Value

This message does not return a value.

Comments

If the nStart parameter is 0 and the nEnd parameter is −1, all the text in the edit control is selected. If nStart is −1, any current selection is removed. The caret is placed at the end of the selection indicated by the greater of the two values nEnd and nStart.

In previous versions of Windows, the wParam parameter is a flag that is FALSE to scroll the caret into view or TRUE to omit the scrolling. A Win32 application should use the EM_SCROLLCARET message to scroll the caret into view.

In previous versions of Windows, the starting and ending positions of the selection are indicated by the low- and high-order words, respectively, of the lParam parameter.

See Also

»EM_GETSEL«, »EM_REPLACESEL«, »EM_SCROLLCARET«


  EM_SETTABSTOPS

EM_SETTABSTOPS

wParam = (WPARAM) cTabs;             /* number of tab stops */

lParam = (LPARAM) (LPWORD) lpwTabs;  /* tab stop array      */

An application sends an EM_SETTABSTOPS message to set the tab stops in a multiline edit control. When text is copied to the control, any tab character in the text causes space to be generated up to the next tab stop.

This message is processed only by multiline edit controls.

Parameters

cTabs

Value of wParam. Specifies the number of tab stops contained in the lpwTabs parameter. If this parameter is zero, the lpwTabs parameter is ignored and default tab stops are set at every 32 dialog box units. If this parameter is 1, tab stops are set at every n dialog box units, where n is the distance pointed to by the lpwTabs parameter. If the cTabs parameter is greater than 1, lpwTabs points to an array of tab stops.

lpwTabs

Value of lParam. Points to an array of unsigned integers specifying the tab stops, in dialog units. If the cTabs parameter is 1, lpwTabs points to an unsigned integer containing the distance between all tab stops, in dialog box units.

Return Value

If all the tabs are set, the return value is TRUE; otherwise, it is FALSE.

Comments

The EM_SETTABSTOPS message does not automatically redraw the edit control window. If the application is changing the tab stops for text already in the edit control, it should call the InvalidateRect function to redraw the edit control window.

See Also

»GetDialogBaseUnits«, »InvalidateRect«


  EM_SETWORDBREAK

The EM_SETWORDBREAK message is not supported. Applications that must replace the default wordwrap function of a multiline edit control with an application-defined wordwrap function should use the EM_SETWORDBREAKPROC message.


  EM_SETWORDBREAKPROC

EM_SETWORDBREAKPROC

wParam = 0;                                 /* not used, must be zero */

lParam = (LPARAM)(EDITWORDBREAKPROC)ewbprc; /* function address       */

An application sends the EM_SETWORDBREAKPROC message to an edit control to replace the default wordwrap function with an application-defined wordwrap function.

Parameters

ewbprc

Value of lParam. Specifies the address of the application-defined wordwrap function. For more information, see the description of the »WordBreakProc« callback function.

Return Value

This message does not return a value.

Comments

A wordwrap function scans a text buffer that contains text to be sent to the screen, looking for the first word that does not fit on the current screen line. The wordwrap function places this word at the beginning of the next line on the screen.

A wordwrap function defines the point at which Windows should break a line of text for multiline edit controls, usually at a space character that separates two words. Either a multiline or a single-line edit control might call this function when the user presses arrow keys in combination with the CTRL key to move the caret to the next word or previous word. The default wordwrap function breaks a line of text at a space character. The application-defined function may define the wordwrap to occur at a hyphen or a character other than the space character.

See Also

»WordBreakProc«, »EM_FMTLINES«, »EM_GETWORDBREAKPROC«


  EM_UNDO

EM_UNDO

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an EM_UNDO message to undo the last edit control operation.

Parameters

This message has no parameters.

Return Value

For a single-line edit control, the return value is always TRUE. For a multiple-line edit control, the return value is TRUE if the undo operation is successful, or FALSE if the undo operation fails.

Comments

An undo operation can also be undone. For example, you can restore deleted text with the first EM_CANUNDO message, and remove the text again with a second EM_CANUNDO message as long as there is no intervening edit operation.

See Also

»EM_CANUNDO«


  EN_CHANGE

EN_CHANGE

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_CHANGE notification message is sent when the user has taken an action that may have altered text in an edit control. Unlike the EN_UPDATE notification message, this notification message is sent after Windows updates the screen. The parent window of the edit control receives this notification message through the WM_COMMAND message.

See Also

»EN_UPDATE«, »WM_COMMAND«


  EN_ERRSPACE

EN_ERRSPACE

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_ERRSPACE notification message is sent when an edit control cannot allocate enough memory to meet a specific request. The parent window of the edit control receives this notification message through the WM_COMMAND message.

See Also

»WM_COMMAND«


  EN_HSCROLL

EN_HSCROLL

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_HSCROLL notification message is sent when the user clicks an edit control's horizontal scroll bar. The parent window of the edit control receives this notification message through the WM_COMMAND message. The parent window is notified before the screen is updated.

See Also

»EN_VSCROLL«, »WM_COMMAND«


  EN_KILLFOCUS

EN_KILLFOCUS

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

wNotifyCode = HIWORD(wParam);      /* notification code          */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_KILLFOCUS notification message is sent when an edit control loses the keyboard focus. The parent window of the edit control receives this notification message through the WM_COMMAND message.

Comments

In previous versions of Windows, the notication code was in HIWORD(lParam).

See Also

»EN_SETFOCUS«, »WM_COMMAND«


  EN_MAXTEXT

EN_MAXTEXT

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_MAXTEXT notification message is sent when the current text insertion has exceeded the specified number of characters for the edit control. The text insertion has been truncated.

This message is also sent when an edit control does not have the ES_AUTOHSCROLL style and the number of characters to be inserted would exceed the width of the edit control.

This message is also sent when an edit control does not have the ES_AUTOVSCROLL style and the total number of lines resulting from a text insertion would exceed the height of the edit control.

The parent window of the edit control receives this notification message through the WM_COMMAND message.

See Also

»EM_LIMITTEXT«, »WM_COMMAND«


  EN_SETFOCUS

EN_SETFOCUS

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

wNotifyCode = HIWORD(wParam);      /* notification code          */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_SETFOCUS notification message is sent when an edit control receives the keyboard focus. The parent window of the edit control receives this notification message through the WM_COMMAND message.

Comments

In previous versions of Windows, the notication code was in HIWORD(lParam).

See Also

»EN_KILLFOCUS«, »WM_COMMAND«


  EN_UPDATE

EN_UPDATE

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_UPDATE notification message is sent when an edit control is about to display altered text. This notification is sent after the control has formatted the text but before it displays the text. This makes it possible to resize the edit control window, if necessary. The parent window of the edit control receives this notification message through the WM_COMMAND message.

See Also

»EN_CHANGE«, »WM_COMMAND«


  EN_VSCROLL

EN_VSCROLL

idEditCtrl = (int) LOWORD(wParam); /* identifier of edit control */

hwndEditCtrl = (HWND) lParam;      /* handle of edit control     */

The EN_VSCROLL notification message is sent when the user clicks an edit control's vertical scroll bar. The parent window of the edit control receives this notification message through the WM_COMMAND message. The parent window is notified before the screen is updated.

See Also

»EN_HSCROLL«, »WM_COMMAND«


  FM_GETDRIVEINFO

FM_GETDRIVEINFO

wParam = 0;                                      /* not used, must be zero */

lParam = (LPARAM) (LPFMS_GETDRIVEINFO) lpfmsgdi; /* drive data             */

A File Manager extension sends an FM_GETDRIVEINFO message to retrieve drive information from the active File Manager window.

Parameters

lpfmsgdi

Value of lParam. Points to an FMS_GETDRIVEINFO structure that receives drive information. The FMS_GETDRIVEINFO structure has the following form:

typedef struct _FMS_GETDRIVEINFO { /* fmsgdi */

    DWORD dwTotalSpace;

    DWORD dwFreeSpace;

    CHAR  szPath[260];

    CHAR  szVolume[14];

    CHAR  szShare[128];

} FMS_GETDRIVEINFO;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

The return value is always nonzero.

Comments

If 0xFFFFFFFF is returned in the dwTotalSpace or dwFreeSpace member of the FMS_GETDRIVEINFO structure, the extension library must compute the value or values.

See Also

»FMExtensionProc«


  FM_GETFILESEL

FM_GETFILESEL

wParam = (WPARAM) index;                       /* index of selected file */

lParam = (LPARAM) (LPFMS_GETFILESEL) lpfmsgfs; /* file data              */

A File Manager extension sends an FM_GETFILESEL message to retrieve information about a selected file from the active File Manager window (either the directory window or the Search Results window).

Parameters

index

Value of wParam. Specifies the zero-based index of the selected file to retrieve.

lpfmsgfs

Value of lParam. Points to an FMS_GETFILESEL structure that receives information about the selection. The FMS_GETFILESEL structure has the following form:

typedef struct _FMS_GETFILESEL { /* fmsgfs */

    FILETIME ftTime;

    DWORD    dwSize;

    BYTE     bAttr;

    CHAR     szName[260];

} FMS_GETFILESEL;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

The return value is the zero-based index of the selected file that was retrieved.

Comments

An extension can use the FM_GETSELCOUNT message to get the count of selected files.

See Also

»FMExtensionProc«, »FM_GETFILESELLFN«, »FM_GETSELCOUNT«, »FM_GETSELCOUNTLFN«


  FM_GETFILESELLFN

FM_GETFILESELLFN

wParam = (WPARAM) index;                       /* index of selected file */

lParam = (LPARAM) (LPFMS_GETFILESEL) lpfmsgfs; /* selection data         */

A File Manager extension sends an FM_GETFILESELLFN message to retrieve information about a selected file from the active File Manager window (either the directory window or the Search Results window). The selected file can have a long filename.

Parameters

index

Value of wParam. Specifies the zero-based index of the selected file to retrieve.

lpfmsgfs

Value of lParam. Points to an FMS_GETFILESEL structure that receives information about the selection. The FMS_GETFILESEL structure has the following form:

typedef struct _FMS_GETFILESEL { /* fmsgfs */

    FILETIME ftTime;

    DWORD    dwSize;

    BYTE     bAttr;

    CHAR     szName[260];

} FMS_GETFILESEL;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

The return value is the zero-based index of the selected file that was retrieved.

Comments

Only extensions that support long filenames (for example, network-aware extensions) should use this message.

An extension can use the FM_GETSELCOUNT message to get the count of selected files.

See Also

»FMExtensionProc«, »FM_GETFILESEL«, »FM_GETSELCOUNT«, »FM_GETSELCOUNTLFN«


  FM_GETFOCUS

FM_GETFOCUS

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

A File Manager extension sends a FM_GETFOCUS message to retrieve the type of the File Manager window that has the input focus.

Parameters

This message has no parameters.

Return Value

The return value is the type of File Manager window that has input focus. It can be one of the following values:

Value	Meaning
FMFOCUS_DIR	Directory portion of a directory window
FMFOCUS_TREE	Tree portion of a directory window
FMFOCUS_DRIVES	Drive bar of a directory window
FMFOCUS_SEARCH	Search Results window


  FM_GETSELCOUNT

FM_GETSELCOUNT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

A File Manager extension sends a FM_GETSELCOUNT message to retrieve a count of the selected files in the active File Manager window (either the directory window or the Search Results window).

Parameters

This message has no parameters.

Return Value

The return value is the number of selected files.

See Also

»FM_GETFILESEL«, »FM_GETFILESELLFN«, »FM_GETSELCOUNTLFN«


  FM_GETSELCOUNTLFN

FM_GETSELCOUNTLFN

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

A File Manager extension sends an FM_GETSELCOUNTLFN message to retrieve the number of selected files in the active File Manager window (either the directory window or the Search Results window). The count includes files that have long filenames.

Parameters

This message has no parameters.

Return Value

The return value is the number of selected files.

Comments

Only extensions that support long filenames (for example, network-aware extensions) should use this message.

See Also

»FM_GETFILESEL«, »FM_GETFILESELLFN«, »FM_GETSELCOUNT«


  FM_REFRESH_WINDOWS

FM_REFRESH_WINDOWS

wParam = (WPARAM) (BOOL) fRepaint;  /* repaint flag           */

lParam = 0;                         /* not used, must be zero */

A File Manager extension sends an FM_REFRESH_WINDOWS message to cause File Manager to repaint either its active window or all of its windows.

Parameters

fRepaint

Value of wParam. Specifies whether File Manager repaints its active window or all of its windows. If this parameter is TRUE, File Manager repaints all of its windows. Otherwise, File Manager repaints only its active window.

Return Value

This message does not return a meaningful value.

Comments

File-system changes caused by an extension are automatically detected by File Manager. An extension should use this message only in situations where drive connections are made or canceled.

See Also

»FMExtensionProc«


  FM_RELOAD_EXTENSIONS

FM_RELOAD_EXTENSIONS

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

A File Manager extension (or another application) sends an FM_RELOAD_EXTENSIONS message to cause File Manager to reload all extension DLLs listed in the [AddOns] section of the WINFILE.INI file.

Parameters

This message has no parameters.

Return Value

This message does not return a meaningful value.

Comments

Other applications can use the PostMessage function to send this message to File Manager. To obtain the appropriate File Manager window handle, an application can specify "WFS_Frame" as the lpszClassName parameter in a call to the FindWindow function.

See Also

»FindWindow«, »FMExtensionProc«, »PostMessage«


  FMEVENT_INITMENU

FMEVENT_INITMENU

hmenu = (HMENU) lParam; /* handle of File Manager menu */

The FMEVENT_INITMENU message is sent to an extension DLL when the user selects the menu for the extension from the File Manager menu bar. The extension can use this notification to initialize menu items in the menu.

Parameters

hmenu

Specifies the handle of the File Manager menu bar.

Return Value

An extension DLL should return zero if it processes this message.

Comments

An extension DLL receives this message only when the user selects the top-level menu. If the extension contains submenus, it must initialize them at the same time it initializes the top-level menu.

See Also

»FMExtensionProc«


  FMEVENT_LOAD

FMEVENT_LOAD

lpfmsld = (LPFMS_LOAD) lParam;  /* address of struct. with delta */

The FMEVENT_LOAD message is sent to an extension DLL when File Manager is loading the DLL.

Parameters

lpfmsld

Points to an FMS_LOAD structure that specifies the menu-item delta value. An extension DLL should save the menu-item delta value and fill the other structure members with information about the extension. The FMS_LOAD structure has the following form:

typedef struct _FMS_LOAD { /* fmsld */

    DWORD dwSize;

    CHAR  szMenuName[MENU_TEXT_LEN];

    HMENU hMenu;

    UINT  wMenuDelta;

} FMS_LOAD;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

An extension DLL must return TRUE to continue loading the DLL. If the DLL returns FALSE, File Manager calls the FreeLibrary function and ends any communication with the extension DLL.

Comments

An application should fill the dwSize, szMenuName, and hMenu members in the FMS_LOAD structure. It should also save the value of the wMenuDelta member and use it to identify menu items when modifying the menu.

See Also

»FMExtensionProc«


  FMEVENT_SELCHANGE

FMEVENT_SELCHANGE

The FMEVENT_SELCHANGE message is sent to an extension DLL when the user selects a filename in the File Manager directory window or Search Results window.

Parameters

This message has no parameters.

Return Value

An extension DLL should return zero if it processes this message.

Comments

Changes in the tree portion of the directory window do not produce this message.

Because the user can change the selection many times, the extension DLL must return promptly after processing this message to avoid slowing the selection process for the user.

See Also

»FMExtensionProc«


  FMEVENT_TOOLBARLOAD

FMEVENT_TOOLBARLOAD

lpfmstbl = (LPFMS_TOOLBARLOAD) lParam;   /* toolbar data */

The FMEVENT_TOOLBARLOAD message is sent to an extension DLL when File Manager is loading its toolbar. This message allows an extension DLL to add a button to the File Manager toolbar.

Parameters

lpfmstbl

Points to an FMS_TOOLBARLOAD structure. If the extension DLL adds a button to the toolbar in File Manager, the DLL should fill the structure with information about the button. The FMS_TOOLBARLOAD structure has the following form:

typedef struct tagFMS_TOOLBARLOAD { /* fmstbl */

    DWORD        dwSize;

    LPEXT_BUTTON lpButtons;

    WORD         cButtons;

    WORD         cBitmaps;

    WORD         idBitmap;

    HBITMAP      hBitmap;

} FMS_TOOLBARLOAD;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

An extension DLL must return TRUE to add the button to the toolbar. If the DLL returns FALSE, File Manager does not add the button.

See Also

»FMExtensionProc«


  FMEVENT_UNLOAD

FMEVENT_UNLOAD

The FMEVENT_UNLOAD message is sent to an extension DLL when File Manager is unloading the DLL.

Parameters

This message has no parameters.

Return Value

An extension DLL should return zero if it processes this message.

Comments

The hwnd and hMenu values passed with the FMEVENT_LOAD and FMEVENT_INITMENU messages may not be valid at the time this message is sent.

See Also

»FMExtensionProc«


  FMEVENT_USER_REFRESH

FMEVENT_USER_REFRESH

The FMEVENT_USER_REFRESH message is sent to an extension DLL when the user chooses the Refresh command from the Window menu in File Manager. The extension can use this notification to update its menu.

Parameters

This message has no parameters.

Return Value

An extension DLL should return zero if it processes this message.

See Also

»FMExtensionProc«


  LB_ADDFILE

LB_ADDFILE

wParam = 0;                               /* not used, must be zero */

lParam = (LPARAM) (LPCTSTR) lpszFilename; /* name of file to add    */

An application sends an LB_ADDFILE message to add the specified filename to a list box that contains a directory listing.

Parameters

lpszFilename

Value of lParam. Points to the name of the file to add.

Return Value

The return value is the zero-based index of the file that was added, or LB_ERR if an error occurs.

Comments

The list box to which lpszFilename is added must have been filled by the DlgDirList function.

See Also

»DlgDirList«, »LB_ADDSTRING«


  LB_ADDSTRING

LB_ADDSTRING

wParam = 0;                         /* not used, must be zero   */

lParam = (LPARAM) (LPCTSTR) lpsz;   /* address of string to add */

An application sends an LB_ADDSTRING message to add a string to a list box. If the list box does not have the LBS_SORT style, the string is added to the end of the list. Otherwise, the string is inserted into the list and the list is sorted.

Parameters

lpsz

Value of lParam. Points to the null-terminated string that is to be added. If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, the value of the lpsz parameter is stored instead of the string it would otherwise point to.

Return Value

The return value is the zero-based index of the string in the list box. If an error occurs, the return value is LB_ERR. If there is insufficient space to store the new string, the return value is LB_ERRSPACE.

Comments

If you create an owner-drawn list box with the LBS_SORT style but not the LBS_HASSTRINGS style, the system sends the WM_COMPAREITEM message one or more times to the owner of the list box to place the new item properly in the list box.

See Also

»LB_DELETESTRING«, »LB_INSERTSTRING«, »LB_SELECTSTRING«, »WM_COMPAREITEM«


  LB_DELETESTRING

LB_DELETESTRING

wParam = (WPARAM) index;    /* index of string to delete */

lParam = 0;                 /* not used, must be zero    */

An application sends an LB_DELETESTRING message to delete a string in a list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the string to be deleted.

Return Value

The return value is a count of the strings remaining in the list. The return value is LB_ERR if the index parameter specifies an index greater than the number of items in the list.

Comments

If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, the system sends a WM_DELETEITEM message to the owner of the list box so the application can free any additional data associated with the item.

See Also

»LB_ADDSTRING«, »LB_INSERTSTRING«, »WM_DELETEITEM«


  LB_DIR

LB_DIR

wParam = (WPARAM) (UINT) uAttrs;          /* file attributes  */

lParam = (LPARAM) (LPCTSTR) lpszFileSpec; /* filename address */

An application sends an LB_DIR message to add a list of filenames to a list box.

Parameters

uAttrs

Value of wParam. Specifies the attributes of the files to be added to the list box. This parameter can be a combination of the following values:

Value	Description
DDL_ARCHIVE	Includes archived files.
DDL_DIRECTORY	Includes subdirectories. Subdirectory names are enclosed in square brackets ([ ]).
DDL_DRIVES	Includes drives. Drives are listed in the form [-x-], where x is the drive letter.
DDL_EXCLUSIVE	Includes only files with the specified attributes. By default, read-write files are listed even if DDL_READWRITE is not specified.
DDL_HIDDEN	Includes hidden files.
DDL_READONLY	Includes read-only files.
DDL_READWRITE	Includes read-write files with no additional attributes.
DDL_SYSTEM	Includes system files.
lpszFileSpec

Value of lParam. Points to the null-terminated string that specifies the filename to add to the list. If the filename contains wildcards (for example, *.*), all files that match the wildcards and have the attributes specified by the uAttrs parameter are added to the list.

Return Value

The return value is the zero-based index of the last filename added to the list. If an error occurs, the return value is LB_ERR. If there is insufficient space to store the new strings, the return value is LB_ERRSPACE.

See Also

»DlgDirList«


  LB_FINDSTRING

LB_FINDSTRING

wParam = (WPARAM) indexStart;           /* item before start of search */

lParam = (LPARAM) (LPCTSTR) lpszFind;   /* search string address       */

An application sends an LB_FINDSTRING message to find the first string in a list box that contains the specified prefix.

Parameters

indexStart

Value of wParam. Specifies the zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the indexStart parameter. If indexStart is −1, the entire list box is searched from the beginning.

lpszFind

Value of lParam. Points to the null-terminated string that contains the prefix to search for. The search is case-indepentdent, so this string can contain any combination of uppercase and lowercase letters.

Return Value

The return value is the index of the matching item, or LB_ERR if the search was unsuccessful.

Comments

If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, this message returns the index of the item whose long value (supplied as the lParam parameter of the LB_ADDSTRING or LB_INSERTSTRING message) matches the value supplied as the lpszFind parameter.

See Also

»LB_ADDSTRING«, »LB_INSERTSTRING«, »LB_SELECTSTRING«


  LB_FINDSTRINGEXACT

LB_FINDSTRINGEXACT

wParam = (WPARAM) indexStart;      /* item before start of search */

lParam = (LPARAM)(LPCSTR)lpszFind; /* address of search string    */

An application sends a LB_FINDSTRINGEXACT message to find the first list box string that matches the string specified in the lpszFind parameter.

Parameters

indexStart

Value of wParam. Specifies the zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the indexStart parameter. If indexStart is &(EN_DASH)1, the entire list box is searched from the beginning.

lpszFind

Value of lParam. Points to the null-terminated string to search for. This string can contain a complete filename, including the extension. The search is not case-sensitive, so this string can contain any combination of uppercase and lowercase letters.

Return Value

The return value is the zero-based index of the matching item, or LB_ERR if the search was unsuccessful.

Comments

If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, the action taken by the LB_FINDSTRINGEXACT message depends on whether the LBS_SORT style is used. If the LBS_SORT style is used, the system sends WM_COMPAREITEM messages to the owner of the list box to determine which item matches the specified string. Otherwise, LB_FINDSTRINGEXACT attempts to match the 32-bit value against the value of the lpszFind parameter.

See Also

»LB_FINDSTRING«, »LB_SELECTSTRING«, »WM_COMPAREITEM«


  LB_GETANCHORINDEX

LB_GETANCHORINDEX

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETANCHORINDEX message to retrieve the index of the anchor item.

Parameters

This message has no parameters.

Return Value

The return value is the index of the current anchor item — that is, the item most recently selected by the user pressing a mouse button.

Comments

In a multiple-selection list box, the anchor item is the first or last item in a block of contiguous selected items.

See Also

»LB_SETANCHORINDEX«


  LB_GETCARETINDEX

LB_GETCARETINDEX

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETCARETINDEX message to determine the index of the item that has the focus rectangle in a multiple-selection list box. The item may or may not be selected.

Parameters

This message has no parameters.

Return Value

The return value is the zero-based index of the list box item that has the focus rectangle. If the list box is a single-selection list box, the return value is the zero-based index of the item that is selected, if any.

See Also

»LB_SETCARETINDEX«


  LB_GETCOUNT

LB_GETCOUNT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETCOUNT message to retrieve the number of items in a list box.

Parameters

This message has no parameters.

Return Value

The return value is the number of items in the list box, or LB_ERR if an error occurs.

Comments

The returned count is one greater then the index value of the last item (the index is zero-based).

See Also

»LB_SETCOUNT«


  LB_GETCURSEL

LB_GETCURSEL

wParam = 0;     /* not used, must be zero */

lParam = 0;     /* not used, must be zero */

An application sends an LB_GETCURSEL message to retrieve the index of the currently selected item, if any, in a single-selection list box.

Parameters

This message has no parameters.

Return Value

The return value is the zero-based index of the currently selected item, or LB_ERR if no item is currently selected.

Comments

Use the LB_GETCARETINDEX message to retrieve the index of the item that has the focus rectangle in a multiple-selection list box. An application cannot send the LB_GETCURSEL message to a multiple-selection list box.

See Also

»LB_GETCARETINDEX« »LB_SETCURSEL«


  LB_GETHORIZONTALEXTENT

LB_GETHORIZONTALEXTENT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETHORIZONTALEXTENT message to retrieve from a list box the width, in pixels, by which the list box can be scrolled horizontally (the scrollable width) if the list box has a horizontal scroll bar.

Parameters

This message has no parameters.

Return Value

The return value is the scrollable width, in pixels, of the list box.

Comments

To respond to the LB_GETHORIZONTALEXTENT message, the list box must have been defined with the WS_HSCROLL style.

See Also

»LB_SETHORIZONTALEXTENT«


  LB_GETITEMDATA

LB_GETITEMDATA

wParam = (WPARAM) index; /* item index             */

lParam = 0;              /* not used, must be zero */

An application sends an LB_GETITEMDATA message to retrieve the application-defined 32-bit value associated with the specified list box item.

Parameters

index

Value of wParam. Specifies the index of the item.

Return Value

The return value is the 32-bit value associated with the item, or LB_ERR if an error occurs.

Comments

If the item is in an owner-drawn list box created without the LBS_HASSTRINGS style, this 32-bit value was contained in the lParam parameter of the LB_ADDSTRING or LB_INSERTSTRING message that added the item to the list box. Otherwise, it is the value in the lParam parameter of an LB_SETITEMDATA message.

See Also

»LB_ADDSTRING«, »LB_INSERTSTRING«, »LB_SETITEMDATA«


  LB_GETITEMHEIGHT

LB_GETITEMHEIGHT

wParam = (WPARAM) index;    /* item index             */

lParam = 0;                 /* not used, must be zero */

An application sends an LB_GETITEMHEIGHT message to retrieve the height of items in a list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the item in the list box. This parameter is used only if the list box has the LBS_OWNERDRAWVARIABLE style; otherwise, set it to zero.

Return Value

The return value is the height, in pixels, of each item in the list box. The return value is the height of the item specified by the index parameter if the list box has the LBS_OWNERDRAWVARIABLE style. The return value is LB_ERR if an error occurs.

See Also

»LB_SETITEMHEIGHT«


  LB_GETITEMRECT

LB_GETITEMRECT

wParam = (WPARAM) index;            /* item index           */

lParam = (LPARAM) (RECT FAR*) lprc; /* address of rectangle */

An application sends an LB_GETITEMRECT message to retrieve the dimensions of the rectangle that bounds a list box item as it is currently displayed in the list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the item.

lprc

Value of lParam. Points to a RECT structure that will receive the client coordinates for the item in the list box. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an error occurs, the return value is LB_ERR.


  LB_GETLOCALE

LB_GETLOCALE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETLOCALE message to retrieve the current locale of the list box. You can use the locale to determine the correct sorting order of displayed text (for list boxes with the LBS_SORT style) and of text added by the LB_ADDSTRING message.

Parameters

This message has no parameters.

Return Value

The return value is a 32-bit value that specifies the current locale of the list box. The high-order word contains the country code and the low-order word contains the language identifier.

Comments

The language identifier consists of a sublanguage identifier and a primary language identifier. Use the PRIMARYLANGID macro to extract the primary language identifier from the low-order word of the return value, and the SUBLANGID macro to extract the sublanguage identifier.

See Also

»LB_SETLOCALE«, »PRIMARYLANGID«, »SUBLANGID«


  LB_GETSEL

LB_GETSEL

wParam = (WPARAM) index;    /* item index             */

lParam = 0;                 /* not used, must be zero */

An application sends an LB_GETSEL message to retrieve the selection state of an item.

Parameters

index

Value of wParam. Specifies the zero-based index of the item.

Return Value

If an item is selected, the return value is greater than zero; otherwise, it is zero. If an error occurs, the return value is LB_ERR.

See Also

»LB_SETSEL«


  LB_GETSELCOUNT

LB_GETSELCOUNT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETSELCOUNT message to retrieve the total number of selected items in a multiple-selection list box.

Parameters

This message has no parameters.

Return Value

The return value is the count of selected items in the list box. If the list box is a single-selection list box, the return value is LB_ERR.

See Also

»LB_SETSEL«


  LB_GETSELITEMS

LB_GETSELITEMS

wParam = (WPARAM) cItems;           /* maximum number of items */

lParam = (LPARAM) (LPINT) lpnItems; /* address of buffer       */

An application sends an LB_GETSELITEMS message to fill a buffer with an array of integers that specify the item numbers of selected items in a multiple-selection list box.

Parameters

cItems

Value of wParam. Specifies the maximum number of selected items whose item numbers are to be placed in the buffer.

lpnItems

Value of lParam. Points to a buffer large enough for the number of integers specified by the cItems parameter.

Return Value

The return value is the number of items placed in the buffer. If the list box is a single-selection list box, the return value is LB_ERR.

See Also

»LB_GETSELCOUNT«


  LB_GETTEXT

LB_GETTEXT

wParam = (WPARAM) index;                /* item index        */

lParam = (LPARAM) (LPCTSTR) lpszBuffer; /* address of buffer */

An application sends an LB_GETTEXT message to retrieve a string from a list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the string to retrieve.

lpszBuffer

Value of lParam. Points to the buffer that will receive the string. The buffer must have sufficient space for the string and a terminating null character. An LB_GETTEXTLEN message can be sent before the LB_GETTEXT message to retrieve the length, in characters, of the string.

Return Value

The return value is the length of the string, in characters, excluding the terminating null character. If index does not specify a valid index, the return value is LB_ERR.

Comments

If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, the buffer pointed to by the lpszBuffer parameter will receive the 32-bit value associated with the item.

See Also

»LB_GETTEXTLEN«


  LB_GETTEXTLEN

LB_GETTEXTLEN

wParam = (WPARAM) index;    /* item index             */

lParam = 0;                 /* not used, must be zero */

An application sends an LB_GETTEXTLEN message to retrieve the length of a string in a list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the string.

Return Value

The return value is the length of the string, in characters, excluding the terminating null character. If the index parameter does not specify a valid index, the return value is LB_ERR.

See Also

»LB_GETTEXT«


  LB_GETTOPINDEX

LB_GETTOPINDEX

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_GETTOPINDEX message to retrieve the index of the first visible item in a list box. Initially the item with index 0 is at the top of the list box, but if the list box contents have been scrolled another item may be at the top.

Parameters

This message has no parameters.

Return Value

The return value is the index of the first visible item in the list box.

See Also

»LB_SETTOPINDEX«


  LB_INSERTSTRING

LB_INSERTSTRING

wParam = (WPARAM) index;          /* item index                  */

lParam = (LPARAM) (LPCTSTR) lpsz; /* address of string to insert */

An application sends an LB_INSERTSTRING message to insert a string into a list box. Unlike the LB_ADDSTRING message, the LB_INSERTSTRING message does not cause a list with the LBS_SORT style to be sorted.

Parameters

index

Value of wParam. Specifies the zero-based index of the position at which to insert the string. If this parameter is −1, the string is added to the end of the list.

lpsz

Value of lParam. Points to the null-terminated string to be inserted. If the list was created with an owner-drawn style but without the LBS_HASSTRINGS style, the value of the lpsz parameter is stored instead of the string it would otherwise point to.

Return Value

The return value is the index of the position at which the string was inserted. If an error occurs, the return value is LB_ERR. If there is insufficient space to store the new string, the return value is LB_ERRSPACE.

See Also

»LB_ADDSTRING«, »LB_SELECTSTRING«


  LB_RESETCONTENT

LB_RESETCONTENT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends an LB_RESETCONTENT to remove all items from a list box.

Parameters

This message has no parameters.

Return Value

This message does not return a value.

Comments

If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, the owner of the list box receives a WM_DELETEITEM message for each item in the list box.

See Also

»WM_DELETEITEM«


  LB_SELECTSTRING

LB_SELECTSTRING

wParam = (WPARAM) indexStart;        /* item before start of search */

lParam = (LPARAM)(LPCTSTR)lpszFind;  /* address of search string    */

An application sends an LB_SELECTSTRING message to search a list box for an item that begins with the characters in a specified string. If a matching item is found, the item is selected.

Parameters

indexStart

Value of wParam. Specifies the zero-based index of the item before the first item to be searched. When the search reaches the bottom of the list box, it continues from the top of the list box back to the item specified by the indexStart parameter. If indexStart is −1, the entire list box is searched from the beginning.

lpszFind

Value of lParam. Points to the null-terminated string that contains the prefix to search for. The search is case independent, so this string can contain any combination of uppercase and lowercase letters.

Return Value

If the search is successful, the return value is the index of the selected item. If the search is unsuccessful, the return value is LB_ERR and the current selection is not changed.

Comments

The list box is scrolled, if necessary, to bring the selected item into view.

Do not use this message with a list box that has the LBS_MULTIPLESEL style.

An item is selected only if its initial characters from the starting point match the characters in the string specified by the lpszFind parameter.

If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, this message returns the index of the item whose long value (supplied as the lParam parameter of the LB_ADDSTRING or LB_INSERTSTRING message) matches the value supplied as the lParam parameter of LB_SELECTSTRING.

See Also

»LB_ADDSTRING«, »LB_FINDSTRING«, »LB_INSERTSTRING«


  LB_SELITEMRANGE

LB_SELITEMRANGE

wParam = (WPARAM) (BOOL) fSelect;   /* selection flag       */

lParam = MAKELPARAM(wFirst, wLast); /* first and last items */

An application sends an LB_SELITEMRANGE message to select one or more consecutive items in a multiple-selection list box.

Parameters

fSelect

Value of wParam. Specifies how to set the selection. If the fSelect parameter is TRUE, the string is selected and highlighted; if fSelect is zero, the highlight is removed and the string is no longer selected.

wFirst

Value of the low-order word of lParam. Specifies the zero-based index of the first item to select.

wLast

Value of the high-order word of lParam. Specifies the zero-based index of the last item to select.

Return Value

If an error occurs, the return value is LB_ERR.

Comments

Use this message only with multiple-selection list boxes.

This message can select a range only within the first 65,536 items.

See Also

»LB_SELITEMRANGEEX«, »LB_SETSEL«


  LB_SELITEMRANGEEX

LB_SELITEMRANGEEX

wParam = (WPARAM) wFirst; /* first item */

lParam = (LPARAM) wLast); /* last item  */

An application sends an LB_SELITEMRANGEEX message to select one or more consecutive items in a multiple-selection list box.

Parameters

wFirst

Value of wParam. Specifies the zero-based index of the first item to select.

wLast

Value of lParam. Specifies the zero-based index of the last item to select.

Return Value

If an error occurs, the return value is LB_ERR.

Comments

If wFirst is less than wLast, the specified range of items is selected. If wFirst is greater than wLast, the selection is removed from the specified range of items.

Use this message only with multiple-selection list boxes.

This message can select a range only within the first 65,536 items.

See Also

»LB_SELITEMRANGE«, »LB_SETSEL«


  LB_SETANCHORINDEX

LB_SETANCHORINDEX

wParam = (WPARAM) index; /* index to set as anchor */

lParam = 0;              /* not used, must be zero */

An application sends an LB_SETANCHORINDEX message to set the position of the anchor item.

Parameters

index

Value of wParam. Specifies the index of the list box item that will be the anchor.

Return Value

The return value is zero.

Comments

This message sets the anchor by setting the internal value that represents the list box item most recently selected by the user pressing a mouse button. In a multiple-selection list box, the anchor item is the first or last item in a block of contiguous selected items.

See Also

»LB_GETANCHORINDEX«


  LB_SETCARETINDEX

LB_SETCARETINDEX

wParam = (WPARAM) index;            /* item index              */

lParam = MAKELPARAM(fScroll, 0);    /* flag for scrolling item */

An application sends an LB_SETCARETINDEX message to set the focus rectangle to the item at the specified index in a multiple-selection list box. If the item is not visible, it is scrolled into view.

Parameters

index

Value of wParam. Specifies the zero-based index of the list box item that is to receive the focus rectangle.

fScroll

Value of lParam. If this value is FALSE, the item is scrolled until it is fully visible. If this value is TRUE, the item is scrolled until it is at least partially visible.

Return Value

If an error occurs, the return value is LB_ERR.

See Also

»LB_GETCARETINDEX«


  LB_SETCOLUMNWIDTH

LB_SETCOLUMNWIDTH

wParam = (WPARAM) cxColumn; /* column width in pixels */

lParam = 0;                 /* not used, must be zero */

An application sends an LB_SETCOLUMNWIDTH message to a multiple-column list box (created with the LBS_MULTICOLUMN style) to set the width, in pixels, of all columns in the list box.

Parameters

cxColumn

Value of wParam. Specifies the width, in pixels, of all columns.

Return Value

This message does not return a value.

See Also

»LB_SETTABSTOPS«


  LB_SETCOUNT

LB_SETCOUNT

wParam = (WPARAM) (int) cItems; /* count of list box items */

lParam = 0;                     /* not used; must be zero  */

An application sends an LB_SETCOUNT message to set the count of items in a list box created with the LBS_NODATA style.

Parameters

cItems

Value of wParam. Specifies the new count of items in the list box.

Return Value

If an error occurs, the return value is LB_ERR. If there is insufficient memory to store the items, the return value is LB_ERRSPACE.

Comments

Only list boxes created with the LBS_NODATA style support the LB_SETCOUNT message. All other list boxes return LB_ERR in response to this message.

See Also

»LB_GETCOUNT«


  LB_SETCURSEL

LB_SETCURSEL

wParam = (WPARAM) index;    /* item index             */

lParam = 0;                 /* not used, must be zero */

An application sends an LB_SETCURSEL message to select a string and scroll it into view, if necessary. When the new string is selected, the list box removes the highlight from the previously selected string.

Parameters

index

Value of wParam. Specifies the zero-based index of the string that is selected. If the index parameter is -1, the list box is set to have no selection.

Return Value

If an error occurs, the return value is LB_ERR. If the index parameter is −1, the return value is LB_ERR even though no error occurred.

Comments

Use this message only with single-selection list boxes. You cannot use it to set or remove a selection in a multiple-selection list box.

See Also

»LB_GETCURSEL«


  LB_SETHORIZONTALEXTENT

LB_SETHORIZONTALEXTENT

wParam = (WPARAM) cxExtent; /* horizontal scroll width */

lParam = 0;                 /* not used, must be zero  */

An application sends an LB_SETHORIZONTALEXTENT message to set the width, in pixels, by which a list box can be scrolled horizontally (the scrollable width). If the width of the list box is smaller than this value, the horizontal scroll bar horizontally scrolls items in the list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden.

Parameters

cxExtent

Value of wParam. Specifies the number of pixels by which the list box can be scrolled.

Return Value

This message does not return a value.

Comments

To respond to the LB_SETHORIZONTALEXTENT message, the list box must have been defined with the WS_HSCROLL style.

See Also

»LB_GETHORIZONTALEXTENT«


  LB_SETITEMDATA

LB_SETITEMDATA

wParam = (WPARAM) index;    /* item index                   */

lParam = (LPARAM) dwData;   /* value to associate with item */

An application sends an LB_SETITEMDATA message to set a 32-bit value associated with the specified item in a list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the item.

dwData

Value of lParam. Specifies the 32-bit value to be associated with the item.

Return Value

If an error occurs, the return value is LB_ERR.

Comments

If the item is in an owner-drawn list box created without the LBS_HASSTRINGS style, this message replaces the 32-bit value that was contained in the lParam parameter of the LB_ADDSTRING or LB_INSERTSTRING message that added the item to the list box.

See Also

»LB_ADDSTRING«, »LB_GETITEMDATA«, »LB_INSERTSTRING«


  LB_SETITEMHEIGHT

LB_SETITEMHEIGHT

wParam = (WPARAM) index;        /* item index  */

lParam = MAKELPARAM(cyItem, 0); /* item height */

An application sends an LB_SETITEMHEIGHT message to set the height, in pixels, of items in a list box. If the list box has the LBS_OWNERDRAWVARIABLE style, this message sets the height of the item specified by the index parameter. Otherwise, this message sets the height of all items in the list box.

Parameters

index

Value of wParam. Specifies the zero-based index of the item in the list box. Use this parameter only if the list box has the LBS_OWNERDRAWVARIABLE style; otherwise, set it to zero.

cyItem

Value of lParam. Specifies the height, in pixels, of the item.

Return Value

If the index or height is invalid, the return value is LB_ERR.

See Also

»LB_GETITEMHEIGHT«


  LB_SETLOCALE

LB_SETLOCALE

wParam = (WPARAM) wLocaleID;    /* locale identifier      */

lParam = 0;                     /* not used, must be zero */

An application sends an LB_SETLOCALE message to set the current locale of the list box. You can use the locale to determine the correct sorting order of displayed text (for list boxes with the LBS_SORT style) and of text added by the LB_ADDSTRING message.

Parameters

wLocaleID

Value of wParam. Specifies the locale identifier that the list box will use for sorting when adding text.

Return Value

The return value is the previous locale identifier. If the wLocaleID parameter specifies a locale that is not installed on the system, the return value is LB_ERR and the current list box locale is not changed.

Comments

Use the MAKELCID macro to construct a locale identifier.

See Also

»LB_GETLOCALE«, »MAKELCID«


  LB_SETSEL

LB_SETSEL

wParam = (WPARAM) (BOOL) fSelect;   /* selection flag */

lParam = (LPARAM) (UINT) index;     /* item index     */

An application sends an LB_SETSEL message to select a string in a multiple-selection list box.

Parameters

fSelect

Value of wParam. Specifies how to set the selection. If the fSelect parameter is TRUE, the string is selected and highlighted; if fSelect is FALSE, the highlight is removed and the string is no longer selected.

index

Value of lParam. Specifies the zero-based index of the string to set. If index is −1, the selection is added to or removed from all strings, depending on the value of fSelect.

Return Value

If an error occurs, the return value is LB_ERR.

Comments

Use this message only with multiple-selection list boxes.

See Also

»LB_GETSEL«, »LB_SELITEMRANGE«


  LB_SETTABSTOPS

LB_SETTABSTOPS

wParam = (WPARAM) cTabs;            /* number of tab stops       */

lParam = (LPARAM) (LPINT) lpnTabs;  /* address of tab-stop array */

An application sends an LB_SETTABSTOPS message to set the tab-stop positions in a list box.

Parameters

cTabs

Value of wParam. Specifies the number of tab stops in the list box.

lpnTabs

Value of lParam. Points to the first member of an array of integers containing the tab stops, in dialog box units. The tab stops must be sorted in ascending order; backward tabs are not allowed.

Return Value

If all the specified tabs are set, the return value is TRUE; otherwise, it is FALSE.

Comments

To respond to the LB_SETTABSTOPS message, the list box must have been created with the LBS_USETABSTOPS style.

If cTabs parameter is 0 and lpnTabs is NULL, the default tab stop is two dialog box units. If cTabs is 1, the list box will have tab stops separated by the distance specified by lpnTabs.

If lpnTabs points to more than a single value, a tab stop will be set for each value in lpnTabs, up to the number specified by cTabs.

A dialog box unit is a horizontal or vertical distance. One horizontal dialog box unit is equal to one-fourth of the current dialog box base-width unit. These units are computed based on the height and width of the current system font. The GetDialogBaseUnits function returns the current dialog box base units, in pixels.

See Also

»GetDialogBaseUnits«


  LB_SETTOPINDEX

LB_SETTOPINDEX

wParam = (WPARAM) index;    /* item index             */

lParam = 0;                 /* not used, must be zero */

An application sends an LB_SETTOPINDEX message to ensure that a particular item in a list box is visible.

Parameters

index

Value of wParam. Specifies the zero-based index of the item in the list box.

Return Value

If an error occurs, the return value is LB_ERR.

Comments

The system scrolls the list box contents so that either the specified item appears at the top of the list box or the maximum scroll range has been reached.

See Also

»LB_GETTOPINDEX«


  LBN_DBLCLK

LBN_DBLCLK

idListBox = (int) LOWORD(wParam);  /* identifier of list box */

hwndListBox = (HWND) lParam;       /* handle of list box     */

An application sends the LBN_DBLCLK notification message when the user double-clicks a string in a list box. The parent window of the list box receives this notification message through the WM_COMMAND message.

Comments

Only a list box that has the LBS_NOTIFY style will send this notification message.

See Also

»LBN_SELCHANGE«, »WM_COMMAND«


  LBN_ERRSPACE

LBN_ERRSPACE

idListBox = (int) LOWORD(wParam);  /* identifier of list box */

hwndListBox = (HWND) lParam;       /* handle of list box     */

An application sends the LBN_ERRSPACE notification message when a list box cannot allocate enough memory to meet a specific request. The parent window of the list box receives this notification message through the WM_COMMAND message.

See Also

»WM_COMMAND«


  LBN_KILLFOCUS

LBN_KILLFOCUS

idListBox = (int) LOWORD(wParam);  /* identifier of list box */

hwndListBox = (HWND) lParam;       /* handle of list box     */

An application sends the LBN_KILLFOCUS notification message when a list box loses the keyboard focus. The parent window of the list box receives this notification message through the WM_COMMAND message.

See Also

»LBN_SETFOCUS«, »WM_COMMAND«


  LBN_SELCANCEL

LBN_SELCANCEL

idListBox = (int) LOWORD(wParam);  /* identifier of list box */

hwndListBox = (HWND) lParam;       /* handle of list box     */

An application sends the LBN_SELCANCEL notification message when the user cancels the selection in a list box. The parent window of the list box receives this notification message through the WM_COMMAND message.

Comments

This notification message applies only to a list box that has the LBS_NOTIFY style.

See Also

»LBN_DBLCLK«, »LBN_SELCHANGE«, »LB_SETCURSEL«, »WM_COMMAND«


  LBN_SELCHANGE

LBN_SELCHANGE

idListBox = (int) LOWORD(wParam);  /* identifier of list box */

hwndListBox = (HWND) lParam;       /* handle of list box     */

An application sends the LBN_SELCHANGE notification message when the selection in a list box is about to change. The parent window of the list box receives this notification message through the WM_COMMAND message.

Comments

This notification message is not sent if the LB_SETCURSEL message changes the selection.

This notification message applies only to a list box that has the LBS_NOTIFY style.

For a multiple-selection list box, the LBN_SELCHANGE notification is sent whenever the user presses an arrow key, even if the selection does not change.

See Also

»LBN_DBLCLK«, »LBN_SELCANCEL«, »LB_SETCURSEL«, »WM_COMMAND«


  LBN_SETFOCUS

LBN_SETFOCUS

idListBox = (int) LOWORD(wParam);  /* identifier of list box */

hwndListBox = (HWND) lParam;       /* handle of list box     */

An application sends the LBN_SETFOCUS notification message when a list box receives the keyboard focus. The parent window of the list box receives this notification message through the WM_COMMAND message.

See Also

»LBN_KILLFOCUS«, »WM_COMMAND«


  MCI_BREAK

This MCI command message sets a break key for an MCI device. MCI supports this message directly rather than passing it to the device.

Parameters

DWORD dwFlags

The following flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpBreak.
MCI_WAIT
	Specifies that the break operation should finish before MCI returns control to the application.
MCI_BREAK_KEY
	Indicates the nVirtKey member of the structure identified by lpBreak specifies the virtual key code used for the break key. By default, MCI assigns CTRL+BREAK as the break key. This flag is required if MCI_BREAK_OFF is not specified.
MCI_BREAK_HWND
	Indicates the hwndBreak member of the structure identified by lpBreak contains a window handle which must be the current window in order to enable break detection for that MCI device. This is usually the application's main window. If omitted, MCI does not check the window handle of the current window.
MCI_BREAK_OFF
	Used to disable any existing break key for the indicated device
LPMCI_BREAK_PARMS lpBreak

Points to the MCI_BREAK_PARMS structure. The MCI_BREAK_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    int  nVirtKey;

    HWND  hwndBreak;

} MCI_BREAK_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

You might have to press the break key multiple times to interrupt a wait operation. Pressing the break key after a device wait is broken can send the break to an application. If an application has an action defined for the virtural key code, then it can inadvertantly respond to the break. For example, an application using VK_CANCEL for an accelerator key can respond to the default CTRL+BREAK key if it is pressed after a wait is canceled.


  MCI_CLOSE

This MCI command message releases access to a device or device element. All devices respond to this message.

Parameters

DWORD dwFlags

The following flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpDefault.
MCI_WAIT
	Specifies that the close operation should finish before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpDefault
	Points to the MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this data structure with a device-specific data structure.) The MCI_GENERIC_PARMS structure has the following form:
typedef struct {     DWORD  dwCallback; } MCI_GENERIC_PARMS;
	For a full description of this structure, see Chapter 3, »Structures«.
Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

Exiting an application without closing any MCI devices it has opened can leave the device opened and unaccessible. Your application should explicitly close each device or device element when it is finished with it. MCI unloads the device when all instances of the device or all device elements are closed.

See Also

»MCI_OPEN«


  MCI_COPY

This MCI command message copies data to the Clipboard. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_COPY:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the data structure identified by lpCopy.
MCI_WAIT
	Specifies that the copy should finish before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpCopy

Points to an MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this data structure with a device-specific data structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_CUT«, »MCI_DELETE«, »MCI_PASTE«


  MCI_CUE

This MCI command message cues a device so that playback or recording begins with minimum delay. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_CUE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpDefault.
MCI_WAIT
	Specifies that the cue operation should finish before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpDefault

Points to the MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Waveform Audio Extensions

Parameters

DWORD dwFlags

The following additional flags apply to wave audio devices:

Value	Meaning
MCI_WAVE_INPUT
	Specifies that a wave input device should be cued.
MCI_WAVE_OUTPUT
	Specifies that a wave output device should be cued. This is the default flag if a flag is not specified.
LPMCI_GENERIC_PARMS lpDefault

Points to the MCI_GENERIC_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_SEEK«, »MCI_PLAY«, »MCI_RECORD«


  MCI_CUT

This MCI command message removes data from the MCI element and copies it to the Clipboard. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_CUT:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpCut.
MCI_WAIT
	Specifies that the cut operation should finish before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpCut

Points to an MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_COPY«, »MCI_DELETE«, »MCI_PASTE«


  MCI_DELETE

This MCI command message removes data from the MCI element. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_DELETE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpCut.
MCI_WAIT
	Specifies that the delete operation should finish before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpDelete

Points to an MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Wave Audio Extensions

Parameters

DWORD dwFlags

The following extensions apply to wave audio devices:

Value	Meaning
MCI_FROM
	Specifies that a beginning position is included in the dwFrom member of the structure identified by lpDelete. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command.
MCI_TO
	Specifies that an ending position is included in the dwTo member of the structure identified by lpDelete. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command.
LPMCI_WAVE_DELETE_PARMS lpDelete

Points to an MCI_WAVE_DELETE_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.)

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

The waveform audio device uses this command.

See Also

»MCI_COPY«, »MCI_DELETE«, »MCI_PASTE«


  MCI_FREEZE

This MCI command message freezes motion on the display. This command is part of the video overlay command set. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_FREEZE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpFreeze.
MCI_WAIT
	Specifies that the freeze operation should finish before MCI returns control to the application.
MCI_OVLY_RECT
	Specifies that the rc member of the data structure identified by lpFreeze contains a valid rectangle. If this flag is not specified, the device driver will freeze the entire frame.
LPMCI_OVLY_RECT_PARMS lpFreeze

Points to a MCI_OVLY_RECT_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.) The MCI_OVLY_RECT_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_OVLY_RECT_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_UNFREEZE«


  MCI_GETDEVCAPS

This MCI command message is used to obtain static information about a device. All devices must respond to this message. The parameters and flags available for this message depend on the selected device. Information is returned in the dwReturn member of the structure identified by lpCapsParms.

Parameters

DWORD dwFlags

The following standard and command-specific flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpCapsParms.
MCI_WAIT
	Specifies that the query operation should finish before MCI returns control to the application.
MCI_GETDEVCAPS_ITEM
	Specifies that the dwItem member of the structure identified by lpCapsParms contains a constant specifying which device capability to obtain. The following constants define which capability to return in the dwReturn member of the structure:
MCI_GETDEVCAPS_CAN_EJECT
	The dwReturn member is set to TRUE if the device can eject the media; otherwise, it is set to FALSE.
MCI_GETDEVCAPS_CAN_PLAY
	The dwReturn member is set to TRUE if the device can play the media; otherwise, it is set to FALSE.
	If a device specifies TRUE, it implies the device supports MCI_PAUSE and MCI_STOP as well as MCI_PLAY.
MCI_GETDEVCAPS_CAN_RECORD
	The dwReturn member is set to TRUE if the device supports recording; otherwise, it is set to FALSE.
	If a device specifies TRUE, it implies the device supports MCI_PAUSE and MCI_STOP as well as MCI_RECORD.
MCI_GETDEVCAPS_CAN_SAVE
	The dwReturn member is set to TRUE if the device can save a file; otherwise, it is set to FALSE.
MCI_GETDEVCAPS_COMPOUND_DEVICE
	The dwReturn member is set to TRUE if the device uses device elements; otherwise, it is set to FALSE.
MCI_GETDEVCAPS_DEVICE_TYPE
	The dwReturn member is set to one of the following values indicating the device type: • MCI_DEVTYPE_ANIMATION  • MCI_DEVTYPE_CD_AUDIO  • MCI_DEVTYPE_DAT  • MCI_DEVTYPE_DIGITAL_VIDEO  • MCI_DEVTYPE_OTHER  • MCI_DEVTYPE_OVERLAY  • MCI_DEVTYPE_SCANNER  • MCI_DEVTYPE_SEQUENCER  • MCI_DEVTYPE_VIDEODISC  • MCI_DEVTYPE_VCR  • MCI_DEVTYPE_WAVEFORM_AUDIO
MCI_GETDEVCAPS_HAS_AUDIO
	The dwReturn member is set to TRUE if the device has audio output; otherwise, it is set to FALSE.
MCI_GETDEVCAPS_HAS_VIDEO
	The dwReturn member is set to TRUE if the device has video output; otherwise, it is set to FALSE.
	For example, the member is set to TRUE for devices that support the animation or videodisc command set.
MCI_GETDEVCAPS_USES_FILES
	The dwReturn member is set to TRUE if the device requires a filename as its element name; otherwise, it is set to FALSE.
	Only compound devices use files.
LPMCI_GETDEVCAPS_PARMS lpCapsParms

Points to the MCI_GETDEVCAPS_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GETDEVCAPS_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwReturn;

    DWORD  dwItem;

} MCI_GETDEVCAPS_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Animation Extensions

Parameters

DWORD dwFlags

The following extensions apply to animation devices:

Value	Meaning
MCI_GETDEVCAPS_ITEM
	Specifies that the dwItem member of the structure identified by lpCapsParms contains a constant specifying which device capability to obtain. The following additional device-capability constants are defined for animation devices and specify which value to return in the dwReturn member of the structure:
MCI_ANIM_GETDEVCAPS_CAN_REVERSE
	The dwReturn member is set to TRUE if the device can play in reverse; otherwise, it is set to FALSE.
MCI_ANIM_GETDEVCAPS_CAN_STRETCH
	The dwReturn member is set to TRUE if the device can stretch the image to fill the frame; otherwise, it is set to FALSE.
	MCIMMP returns FALSE.
MCI_ANIM_GETDEVCAPS_FAST_RATE
	The dwReturn member is set to the standard fast play rate in frames per second.
	MCIMMP returns MCIERR_UNSUPPORTED_FUNCTION.
MCI_ANIM_GETDEVCAPS_MAX_WINDOWS
	The dwReturn member is set to the maximum number of windows that the device can handle simultaneously.
MCI_ANIM_GETDEVCAPS_NORMAL_RATE
	The dwReturn member is set to the normal rate of play in frames per second.
	MCIMMP returns MCIERR_UNSUPPORTED_FUNCTION.
MCI_ANIM_GETDEVCAPS_PALETTES
	The dwReturn member is set to TRUE if the device can return a palette handle; otherwise, it is set to FALSE.
	MCIMMP returns TRUE.
MCI_ANIM_GETDEVCAPS_SLOW_RATE
	The dwReturn member is set to the standard slow play rate in frames per second.
	MCIMMP returns MCIERR_UNSUPPORTED_FUNCTION.
LPMCI_GETDEVCAPS_PARMS lpCapsParms

Points to the MCI_GETDEVCAPS_PARMS structure.

Videodisc Extensions

Parameters

DWORD dwFlags

The following extensions apply to videodisc devices:

Value	Meaning
MCI_GETDEVCAPS_ITEM
	Specifies that the dwItem member of the structure identified by lpCapsParms contains a constant specifying which device capability to obtain. The following additional device-capability constants are defined for videodisc devices and specify which value to return in the dwReturn member of the structure:
MCI_VD_GETDEVCAPS_CAN_REVERSE
	The dwReturn member is set to TRUE if the videodisc player can play in reverse; otherwise, it is set to FALSE.
	Some players can play CLV discs in reverse as well as CAV discs.
MCI_VD_GETDEVCAPS_FAST_RATE
	The dwReturn member is set to the standard fast play rate in frames per second.
MCI_VD_GETDEVCAPS_NORMAL_RATE
	The dwReturn member is set to the normal play rate in frames per second.
MCI_VD_GETDEVCAPS_SLOW_RATE
	The dwReturn member is set to the standard slow play rate in frames per second.
MCI_VD_GETDEVCAPS_CLV
	Indicates the information requested applies to CLV format discs. By default, the capabilities apply to the current disc.
MCI_VD_GETDEVCAPS_CAV
	Indicates the information requested applies to CAV format discs. By default, the capabilities apply to the current disc.
LPMCI_GETDEVCAPS_PARMS lpCapsParms

Points to the MCI_GETDEVCAPS_PARMS structure.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following extensions apply to video overlay devices:

Value	Meaning
MCI_GETDEVCAPS_ITEM
	Specifies that the dwItem member of the structure identified by lpCapsParms contains a constant specifying which device capability to obtain. The following additional device-capability constants are defined for video overlay devices and specify which value to return in the dwReturn member of the structure:
MCI_OVLY_GETDEVCAPS_CAN_FREEZE
	The dwReturn member is set to TRUE if the device can freeze the image; otherwise, it is set to FALSE.
MCI_OVLY_GETDEVCAPS_CAN_STRETCH
	The dwReturn member is set to TRUE if the device can stretch the image to fill the frame; otherwise, it is set to FALSE.
MCI_OVLY_GETDEVCAPS_MAX_WINDOWS
	The dwReturn member is set to the maximum number of windows that the device can handle simultaneously.
LPMCI_GETDEVCAPS_PARMS lpCapsParms

Points to the MCI_GETDEVCAPS_PARMS structure.

Waveform Audio Extensions

Parameters

DWORD dwFlags

The following extended flag applies to waveform audio devices:

Value	Meaning
MCI_GETDEVCAPS_ITEM
	Specifies that the dwItem member of the structure identified by lpCapsParms contains a constant specifying which device capability to obtain. The following additional device-capability constants are defined for waveform audio devices and specify which value to return in the dwReturn member of the structure:
MCI_WAVE_GETDEVCAPS_INPUT
	The dwReturn member is set to the total number of waveform input (recording) devices.
MCI_WAVE_GETDEVCAPS_OUTPUT
	The dwReturn member is set to the total number of waveform output (playback) devices.
LPMCI_GETDEVCAPS_PARMS lpCapsParms

Points to the MCI_GETDEVCAPS_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.


  MCI_INFO

This MCI command message obtains string information from a device. All devices respond to this message. The parameters and flags available for this message depend on the selected device. Information is returned in the lpstrReturn member of the structure identified by lpInfo. The dwReturnSize member specifies the buffer length for the return data.

Parameters

DWORD dwFlags

The following standard and command-specific flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpInfo.
MCI_WAIT
	Specifies that the query operation should finish before MCI returns control to the application.
MCI_INFO_PRODUCT
	Obtains a description of the hardware associated with a device. Devices should supply a description that identifies both the driver and the hardware used.
LPMCI_INFO_PARMS lpInfo

Points to the MCI_INFO_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_INFO_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    LPTSTR  lpstrReturn;

    DWORD  dwRetSize;

} MCI_INFO_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Animation Extensions

Parameters

DWORD dwFlags

The following additional flags apply to animation devices:

Value	Meaning
MCI_INFO_FILE
	Obtains the filename of the current file. This flag is only supported by devices that return TRUE to the MCI_GETDEVCAPS_USES_FILES query.
MCI_ANIM_INFO_TEXT
	Obtains the window caption.
LPMCI_INFO_PARMS lpInfo

Points to the MCI_INFO_PARMS structure.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices:

Value	Meaning
MCI_INFO_FILE
	Obtains the filename of the current file. This flag is only supported by devices that return TRUE to the MCI_GETDEVCAPS_USES_FILES query.
MCI_OVLY_INFO_TEXT
	Obtains the caption of the window associated with the overlay device.
LPMCI_INFO_PARMS lpInfo

Points to the MCI_INFO_PARMS structure.

Waveform Audio Extensions

Parameters

DWORD dwFlags

The following additional flags apply to waveform audio devices:

Value	Meaning
MCI_INFO_FILE
	Obtains the filename of the current file. This flag is supported by devices that return TRUE to the MCI_GETDEVCAPS_USES_FILES query.
MCI_WAVE_INPUT
	Obtains the product name of the current input.
MCI_WAVE_OUTPUT
	Obtains the product name of the current output.
LPMCI_INFO_PARMS lpInfo

Points to the MCI_INFO_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.


  MCI_LOAD

This MCI command message loads a file. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_LOAD:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpLoad.
MCI_WAIT
	Specifies that the load operation should finish before MCI returns control to the application.
MCI_LOAD_FILE
	Indicates the lpfilename member of the structure identified by lpLoad contains a pointer to a buffer containing the file name.
LPMCI_LOAD_PARMS lpLoad

Points to the MCI_LOAD_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.) The MCI_LOAD_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpfilename;

} MCI_LOAD_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices supporting MCI_LOAD:

Value	Meaning
MCI_OVLY_RECT
	Specifies that the rc member of the structure identified by lpLoad contains a valid display rectangle that identifies the area of the video buffer to update.
LPMCI_OVLY_LOAD_PARMS lpLoad

Points to a MCI_OVLY_LOAD_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

This command applies to video overlay devices.

See Also

»MCI_SAVE«


  MCI_OPEN

This MCI command message initializes a device or device element. All devices respond to this message. The parameters and flags available for this message depend on the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpOpen.
MCI_WAIT
	Specifies that the open operation should finish before MCI returns control to the application.
MCI_OPEN_ALIAS
	Specifies that an alias is included in the lpstrAlias member of the structure identified by lpOpen.
MCI_OPEN_SHAREABLE
	Specifies that the device or device element should be opened as shareable.
MCI_OPEN_TYPE
	Specifies that a device type name or constant is included in the lpstrDeviceType member of the structure identified by lpOpen.
MCI_OPEN_TYPE_ID
	Specifies that the low-order word of the lpstrDeviceType member of the associated structure contains a standard MCI device type ID and the high-order word optionally contains the ordinal index for the device. Use this flag with the MCI_OPEN_TYPE flag.
LPMCI_OPEN_PARMS lpOpen

Points to the MCI_OPEN_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_OPEN_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    MCIDEVICEID  wDeviceID;

    LPCTSTR  lpstrDeviceType;

    LPCTSTR  lpstrElementName;

    LPCTSTR  lpstrAlias;

} MCI_OPEN_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Flags for Compound Devices

Parameters

DWORD dwFlags

The following additional flags apply to compound devices:

Value	Meaning
MCI_OPEN_ELEMENT
	Specifies that an element name is included in the lpstrElementName member of the structure identified by lpOpen.
MCI_OPEN_ELEMENT_ID
	Specifies that the lpstrElementName member of the structure identified by lpOpen is interpreted as a DWORD and has meaning internal to the device. Use this flag with the MCI_OPEN_ELEMENT flag.
LPMCI_OPEN_PARMS lpOpen

Points to the MCI_OPEN_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.)

Animation Extensions

Parameters

DWORD dwFlags

The following flags apply to animation devices:

Value	Meaning
MCI_ANIM_OPEN_NOSTATIC
	Specifies that the device should reduce the number of static (system) colors in the palette to two.
MCI_ANIM_OPEN_PARENT
	Indicates the parent window handle is specified in the hWndParent member of the structure identified by lpOpen. The parent window handle is required for some window styles.
MCI_ANIM_OPEN_WS
	Indicates a window style is specified in the dwStyle member of the structure identified by lpOpen. The dwStyle value specifies the style of the window that the driver will create and display if the application does not provide one. The style parameter takes an integer which defines the window style. These constants are the same as the ones in WINDOWS.H (such as WS_CHILD, WS_OVERLAPPEDWINDOW, or WS_POPUP).
LPMCI_ANIM_OPEN_PARMS lpOpen

Points to the MCI_ANIM_OPEN_PARMS structure.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following flags apply to video overlay devices:

Value	Meaning
MCI_OVLY_OPEN_PARENT
	Indicates the parent window handle is specified in the hWndParent member of the structure identified by lpOpen.
MCI_OVLY_OPEN_WS
	Indicates a window style is specified in the dwStyle member of the structure identified by lpOpen. The dwStyle value specifies the style of the window that the driver will create and display if the application does not provide one. The style parameter takes an integer that defines the window style. These constants are the same as those in WINDOWS.H (for example, WS_CHILD, WS_OVERLAPPEDWINDOW, or WS_POPUP).
LPMCI_OVLY_OPEN_PARMS lpOpen

Points to the MCI_OVLY_OPEN_PARMS structure.

Waveform Audio Extensions

Parameters

DWORD dwFlags

The following flags apply to waveform audio devices:

Value	Meaning
MCI_WAVE_OPEN_BUFFER
	Indicates a buffer length is specified in the dwBuffer member of the structure identified by lpOpen.
LPMCI_WAVE_OPEN_PARMS lpOpen

Points to the MCI_WAVE_OPEN_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.)

Return Value

Returns zero if the open succeeds. If an error occurs, it returns the following values:

Value	Meaning
MCIERR_CANNOT_LOAD_DRIVER
	Error loading media device driver.
MCIERR_DEVICE_OPEN
	The device name is in use by this task. Use a unique alias.
MCIERR_DUPLICATE_ALIAS
	The specified alias is an open device in this task.
MCIERR_EXTENSION_NOT_FOUND
	Cannot deduce a device type from the given extension.
MCIERR_FILENAME_REQUIRED
	A valid filename is required.
MCIERR_MISSING_PARAMETER
	Required parameter is missing.
MCIERR_MUST_USE_SHAREABLE
	The device is already open; use the shareable flag with each open.
MCIERR_NO_ELEMENT_ALLOWED
	An element name cannot be used with this device.
Comments

If MCI_OPEN_SHAREABLE is not specified when a device or device element is initially opened, then all subsequent MCI_OPEN messages to the device or device element will fail. If the device or device element is already open, and this flag is not specified, the call will fail even if the first open command specified MCI_OPEN_SHAREABLE. Files for the MCIMMP, MCISEQ, and MCIWAVE devices are nonshareable.

Case is ignored in the device name, but there must not be any leading or trailing blanks.

To use automatic type selection (via the [mci extensions] section of the registry file), assign the file name (including file extension) to the lpstrElementName member, assign a NULL pointer to the lpstrDeviceType member, and set the MCI_OPEN_ELEMENT flag.

See Also

»MCI_CLOSE«


  MCI_PASTE

This MCI command message pastes data from the clipboard into a device element.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_PASTE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpPaste.
MCI_WAIT
	Specifies that the device should complete the operation before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpPaste

Points to the MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_CUT«, »MCI_COPY«, »MCI_DELETE«


  MCI_PAUSE

This MCI command message pauses the current action.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_PAUSE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCi should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpPause.
MCI_WAIT
	Specifies that the device should be paused before MCi returns control to the application.
LPMCI_GENERIC_PARMS lpPause

Points to the MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

The difference between MCI_STOP and MCI_PAUSE depends upon the device. If possible, MCI_PAUSE suspends device operation but leaves the device ready to resume play immediately.

See Also

»MCI_PLAY«, »MCI_RECORD«, »MCI_RESUME«, »MCI_STOP«


  MCI_PLAY

This MCI command message signals the device to begin transmitting output data. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_PLAY:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpPlay.
MCI_WAIT
	Specifies that the play operation should finish before MCI returns control to the application.
MCI_FROM
	Specifies that a starting position is included in the dwFrom member of the structure identified by lpPlay. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command. If MCI_FROM is not specified, the starting position defaults to the current location.
MCI_TO
	Specifies that an ending position is included in the dwTo member of the structure identified by lpPlay. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command. If MCI_TO is not specified, the end position defaults to the end of the media.
LPMCI_PLAY_PARMS lpPlay

Points to an MCI_PLAY_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_PLAY_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Animation Extensions

Parameters

DWORD dwFlags

The following additional flags apply to animation devices:

Value	Meaning
MCI_ANIM_PLAY_FAST
	Specifies to play fast.
MCI_ANIM_PLAY_REVERSE
	Specifies to play in reverse.
MCI_ANIM_PLAY_SCAN
	Specifies to scan quickly.
MCI_ANIM_PLAY_SLOW
	Specifies to play slowly.
MCI_ANIM_PLAY_SPEED
	Specifies that the play speed is included in the dwSpeed member in the structure identified by lpPlay.
LPMCI_ANIM_PLAY_PARMS lpPlay

Points to an MCI_ANIM_PLAY_PARMS structure.

Videodisc Extensions

Parameters

DWORD dwFlags

The following additional flags apply to videodisc devices:

Value	Meaning
MCI_VD_PLAY_FAST
	Specifies to play fast.
MCI_VD_PLAY_REVERSE
	Specifies to play in reverse.
MCI_VD_PLAY_SCAN
	Specifies to scan quickly.
MCI_VD_PLAY_SLOW
	Specifies to play slowly.
MCI_VD_PLAY_SPEED
	Specifies that the play speed is included in the dwSpeed member in the structure identified by lpPlay.
LPMCI_VD_PLAY_PARMS lpPlay

Points to an MCI_VD_PLAY_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_CUE«, »MCI_PAUSE«, »MCI_RECORD«, »MCI_RESUME«, »MCI_SEEK«, »MCI_STOP«


  MCI_PUT

This MCI command message sets the source, destination, and frame rectangles. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_PUT:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpDest.
MCI_WAIT
	Specifies that the operation should finish before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpDest

Points to an MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Animation Extensions

Parameters

DWORD dwFlags

The following additional flags apply to animation devices supporting MCI_PUT:

Value	Meaning
MCI_ANIM_RECT
	Specifies that the rc member of the structure identified by lpDest contains a valid rectangle. If this flag is not specified, the default rectangle matches the coordinates of the image or window being clipped.
MCI_ANIM_PUT_DESTINATION
	Indicates the rectangle defined for MCI_ANIM_RECT specifies the area of the client window used to display an image. The rectangle contains the offset and visible extent of the image relative to the window origin. If the frame is being stretched, the source is stretched to the destination rectangle.
MCI_ANIM_PUT_SOURCE
	Indicates the rectangle defined for MCI_ANIM_RECT specifies a clipping rectangle for the animation image. The rectangle contains the offset and extent of the image relative to the image origin.
LPMCI_ANIM_RECT_PARMS lpDest

Points to a MCI_ANIM_RECT_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.)

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices supporting MCI_PUT:

Value	Meaning
MCI_OVLY_RECT
	Specifies that the rc member of the structure identified by lpDest contains a valid display rectangle. If this flag is not specified, the default rectangle matches the coordinates of the video buffer or window being clipped.
MCI_OVLY_PUT_DESTINATION
	Indicates the rectangle defined for MCI_OVLY_RECT specifies the area of the client window used to display an image. The rectangle contains the offset and visible extent of the image relative to the window origin. If the frame is being stretched, the source is stretched to the destination rectangle.
MCI_OVLY_PUT_FRAME
	Indicates the rectangle defined for MCI_OVLY_RECT specifies the area of the video buffer used to receive the video image. The rectangle contains the offset and extent of the buffer area relative to the video buffer origin.
MCI_OVLY_PUT_SOURCE
	Indicates that the rectangle defined for MCI_OVLY_RECT specifies the area of the video buffer used as the source of the digital image. The rectangle contains the offset and extent of the clipping rectangle for the video buffer relative to its origin.
MCI_OVLY_PUT_VIDEO
	Indicates that the rectangle defined for MCI_OVLY_RECT specifies the area of the video source capture by the video buffer. The rectangle contains the offset and extent of the clipping rectangle for the video source relative to its origin.
LPMCI_OVLY_RECT_PARMS lpDest

Points to a MCI_OVLY_RECT_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_WHERE«


  MCI_RECORD

This MCI command message starts recording from the current position or from the specified position until the specified position. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_RECORD:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpRecord.
MCI_WAIT
	Specifies that recording should finish before MCI returns control to the application.
MCI_RECORD_INSERT
	Indicates that newly recorded information should be inserted or pasted into the existing data. (Some devices may not support this.) If supported, this is the default.
MCI_FROM
	Specifies that a starting position is included in the dwFrom member of the structure identified by lpRecord. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command. If MCI_FROM is not specified, the starting position defaults to the current location.
MCI_RECORD_OVERWRITE
	Specifies that data should overwrite existing data.
	MCIWAVE returns MCIERR_UNSUPPORTED_FUNCTION in response to this flag.
MCI_TO
	Specifies that an ending position is included in the dwTo member of the structure identified by lpRecord. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command. If MCI_TO is not specified, the ending position defaults to the end of the media.
LPMCI_RECORD_PARMS lpRecord

Points to the MCI_RECORD_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_RECORD_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_RECORD_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

MCISEQ returns MCIERR_UNSUPPORTED_FUNCTION for this command.

Comments

This command is supported by devices that return TRUE to the MCI_GETDEVCAPS_CAN_RECORD query.

See Also

»MCI_CUE«, »MCI_PAUSE«, »MCI_PLAY«, »MCI_RESUME«, »MCI_SEEK«


  MCI_RESUME

This MCI command message resumes a paused device. Support of this message by a device is optional.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_RESUME:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpDefault.
MCI_WAIT
	Specifies that the device should resume before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpDefault

Points to the MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this data structure with a device-specific data structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

This command resumes playing and recording without changing the stop position set with MCI_PLAY or MCI_RECORD.

See Also

»MCI_STOP«, »MCI_PLAY«, »MCI_RECORD«


  MCI_SAVE

This MCI command message saves the current file. Devices which modify files should not destroy the original copy until they receive the save message. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_SAVE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpSave.
MCI_WAIT
	Specifies that the save operation should finish before MCI returns control to the application.
MCI_SAVE_FILE
	Indicates the lpfilename member of the structure identified by lpSave contains a pointer to a buffer containing the destination file name.
LPMCI_SAVE_PARMS lpSave

Points to the MCI_SAVE_PARMS structure. (Devices with additional parameters might replace this data structure with a device-specific data structure.) The MCI_SAVE_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpfilename;

} MCI_SAVE_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices supporting MCI_SAVE:

Value	Meaning
MCI_OVLY_RECT
	Specifies that the rc member of the structure identified by lpSave contains a valid display rectangle indicating the area of the video buffer to save.
LPMCI_OVLY_SAVE_PARMS lpSave

Points to a MCI_OVLY_SAVE_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code. MCISEQ returns MCIERR_UNSUPPORTED_FUNCTION.

Comments

This command is supported by devices that return true to the MCI_GETDEVCAPS_CAN_SAVE query. MCIWAVE supports this command.

See Also

»MCI_LOAD«


  MCI_SEEK

This MCI command message changes the current position of media as quickly as possible. Video and audio output are disable during the seek. After the seek is complete, the device will be stopped. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_SEEK:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpSeek.
MCI_WAIT
	Specifies that the seek operation should finish before MCI returns control to the application.
MCI_SEEK_TO_END
	Specifies to seek to the end of the media.
MCI_SEEK_TO_START
	Specifies to seek to the start of the media.
MCI_TO
	Specifies a position is included in the dwTo member of the MCI_SEEK_PARMS structure. The units assigned to the position values is specified with the MCI_SET_TIME_FORMAT flag of the MCI_SET command. Do not use this flag with MCI_SEEK_END or MCI_SEEK_START.
LPMCI_SEEK_PARMS lpSeek

Points to the MCI_SEEK_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_SEEK_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTo;

} MCI_SEEK_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Videodisc Extensions

Parameters

DWORD dwFlags

The following additional flag applies to videodisc devices.

Value	Meaning
MCI_VD_SEEK_REVERSE
	Specifies to seek backward.
LPMCI_SEEK_PARMS lpSeek

Points to the MCI_SEEK_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

See Also

»MCI_PLAY«, »MCI_RECORD«


  MCI_SET

This MCI command message sets device information. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_SET:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpSet.
MCI_WAIT
	Specifies that the set operation should finish before MCI returns control to the application.
MCI_SET_AUDIO
	Specifies an audio channel number is included in the dwAudio member of the structure identified by lpSet. This flag must be used with MCI_SET_ON or MCI_SET_OFF. Use one of the following constants to indicate the channel number:
Value	Meaning
MCI_SET_AUDIO_ALL
	Specifies all audio channels.
MCI_SET_AUDIO_LEFT
	Specifies the left channel.
MCI_SET_AUDIO_RIGHT
	Specifies the right channel.
MCI_SET_DOOR_CLOSED
	Instructs the device to close the media cover (if any).
MCI_SET_DOOR_OPEN
	Instructs the device to open the media cover (if any).
MCI_SET_TIME_FORMAT
	Specifies a time format parameter is included in the dwTimeFormat member of the structure identified by lpSet. Specifying MCI_FORMAT_MILLISECONDS indicates that subsequent commands that specify time will use milliseconds for both input and output. Other units are device dependent.
MCI_SET_VIDEO
	Sets the video signal on or off. This flag must be used with either MCI_SET_ON or MCI_SET_OFF. Devices that do not have video return MCIERR_UNSUPPORTED_FUNCTION.
MCI_SET_ON
	Enables the specified video or audio channel.
MCI_SET_OFF
	Disables the specified video or audio channel.
LPMCI_SET_PARMS lpSet

Points to the MCI_SET_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_SET_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTimeFormat;

    DWORD  dwAudio;

} MCI_SET_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Animation Extensions

Parameters

DWORD dwFlags

The following additional flags apply to animation devices:

Value	Meaning
MCI_SET_TIME_FORMAT
	Specifies a time format parameter is included in the dwTimeFormat member of the structure identified by lpSet. The following constants are defined for the time format:
MCI_FORMAT_MILLISECONDS
	Changes the time format to milliseconds.
	MCIMMP returns MCIERR_UNSUPPORTED_FUNCTION if the time format is set to MCI_FORMAT_MILLISECONDS.
MCI_FORMAT_FRAMES
	Changes the time format to frames.
LPMCI_SET_PARMS lpSet

Points to the MCI_SET_PARMS structure.

CD Audio Extensions

Parameters

DWORD dwFlags

The following additional flags apply to videodisc devices:

Value	Meaning
MCI_SET_TIME_FORMAT
	Specifies a time format parameter is included in the dwTimeFormat member of the structure identified by lpSet. The following constants are defined for the time format:
MCI_FORMAT_MILLISECONDS
	Changes the time format to milliseconds.
MCI_FORMAT_MSF
	Changes the time format to minutes, seconds, and frames.
MCI_FORMAT_TMSF
	Changes the time format to tracks, minutes, seconds, and frames. (MCI uses continuous track numbers.)
LPMCI_SET_PARMS lpSet

Points to the MCI_SET_PARMS structure.

MIDI Sequencer Extensions

Parameters

DWORD dwFlags

The following additional flags apply to MIDI sequencer devices:

Value	Meaning
MCI_SEQ_SET_MASTER
	Sets the sequencer as a source of synchronization data and indicates that the type of synchronization is specified in the dwMaster member of the structure identified by lpSet.
	MCISEQ returns MCIERR_UNSUPPORTED_FUNCTION.
	The following constants are defined for the synchronization type:
Value	Meaning
MCI_SEQ_MIDI
	The sequencer will send MIDI format synchronization data.
MCI_SEQ_SMPTE
	The sequencer will send SMPTE format synchronization data.
MCI_SEQ_NONE
	The sequencer will not send synchronization data.
MCI_SEQ_SET_OFFSET
	Changes the SMPTE offset of a sequence to that specified by the dwOffset member of the structure identified by lpSet. This only affects sequences with a SMPTE division type.
MCI_SEQ_SET_PORT
	Sets the output MIDI port of a sequence to that specified by the MIDI device ID in the dwPort member of the structure identified by lpSet. The device will close the previous port (if any), and attempt to open and use the new port. If it fails, it will return an error and re-open the previously used port (if any). The following constants are defined for the ports:
MCI_SEQ_NONE
	Closes the previously used port (if any). The sequencer will behave exactly the same as if a port were open, except no MIDI message will be sent.
MIDI_MAPPER
	Sets the port opened to the MIDI Mapper.
MCI_SEQ_SET_SLAVE
	Sets the sequencer to receive synchronization data and indicates that the type of synchronization is specified in the dwSlave member of the structure identified by lpSet.
	MCISEQ returns MCIERR_UNSUPPORTED_FUNCTION.
	The following constants are defined for the synchronization type:
Value	Meaning
MCI_SEQ_FILE
	Sets the sequencer to receive synchronization data contained in the MIDI file.
MCI_SEQ_SMPTE
	Sets the sequencer to receive SMPTE synchronization data.
MCI_SEQ_MIDI
	Sets the sequencer to receive MIDI synchronization data.
MCI_SEQ_NONE
	Sets the sequencer to ignore synchronization data in a MIDI stream.
MCI_SEQ_SET_TEMPO
	Changes the tempo of the MIDI sequence to that specified by the dwTempo member of the structure pointed to by lpSet. For sequences with division type PPQN, tempo is specified in beats per minute; for sequences with division type SMPTE, tempo is specified in frames per second.
MCI_SET_TIME_FORMAT
	Specifies a time format parameter is included in the dwTimeFormat member of the structure identified by lpSet. The following constants are defined for the time format:
Value	Meaning
MCI_FORMAT_MILLISECONDS
	Changes the time format to milliseconds for both input and output.
MCI_FORMAT_SMPTE_24
	Sets the time format to 24 frame SMPTE.
MCI_FORMAT_SMPTE_25
	Sets the time format to 25 frame SMPTE.
MCI_FORMAT_SMPTE_30
	Sets the time format to 30 frame SMPTE.
MCI_FORMAT_SMPTE_30DROP
	Sets the time format to 30 drop-frame SMPTE.
MCI_SEQ_FORMAT_SONGPTR
	Sets the time format to song-pointer units.
LPMCI_SEQ_SET_PARMS lpSet

Points to the MCI_SEQ_SET_PARMS structure.

Videodisc Extensions

Parameters

DWORD dwFlags

The following additional flags apply to videodisc devices:

Value	Meaning
MCI_SET_TIME_FORMAT
	Specifies a time format parameter is included in the dwTimeFormat member of the structure identified by lpSet. The following constants are defined for the time format:
Value	Meaning
MCI_FORMAT_CHAPTERS
	Changes the time format to chapters.
MCI_FORMAT_FRAMES
	Changes the time format to frames.
MCI_FORMAT_HMS
	Changes the time format to hours, minutes, and seconds.
MCI_FORMAT_MILLISECONDS
	Changes the time format to milliseconds for both input and output.
MCI_VD_FORMAT_TRACK
	Changes the time format to tracks. MCI uses continuous track numbers.
LPMCI_VD_SET_PARMS lpSet

Points to the MCI_VD_SET_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.)

Waveform Audio Extensions

Parameters

DWORD dwFlags

The following additional flags apply to waveform audio devices:

Value	Meaning
MCI_WAVE_INPUT
	Sets the input used for recording to the wInput member of the structure identified by lpSet.
MCI_WAVE_OUTPUT
	Sets the output used for playing to the wOutput member of the structure identified by lpSet.
MCI_WAVE_SET_ANYINPUT
	Specifies that any wave input compatible with the current format can be used for recording.
MCI_WAVE_SET_ANYOUTPUT
	Specifies that any wave output compatible with the current format can be used for playing.
MCI_WAVE_SET_AVGBYTESPERSEC
	Sets the bytes per second used for playing, recording, and saving to the nAvgBytesPerSec member of the structure identified by lpSet.
MCI_WAVE_SET_BITSPERSAMPLE
	Sets the bits per sample used for playing, recording, and saving to the nBitsPerSample member of the structure identified by lpSet.
MCI_WAVE_SET_BLOCKALIGN
	Sets the block alignment used for playing, recording, and saving to the nBlockAlign member of the structure identified by lpSet.
MCI_WAVE_SET_CHANNELS
	Specifies the number of channels is indicated in the nChannels member of the structure identified by lpSet.
MCI_WAVE_SET_FORMATTAG
	Sets the format type used for playing, recording, and saving to the wFormatTag member of the structure identified by lpSet. Specifying WAVE_FORMAT_PCM changes the format to PCM.
MCI_WAVE_SET_SAMPLESPERSEC
	Sets the samples per second used for playing, recording, and saving to the nSamplesPerSec member of the structure identified by lpSet.
MCI_SET_TIME_FORMAT
	Specifies a time format parameter is included in the dwTimeFormat member of the structure identified by lpSet. The following constants are defined for the time format:
Value	Meaning
MCI_FORMAT_BYTES
	Changes the time format to bytes for input or output.
MCI_FORMAT_MILLISECONDS
	Changes the time format to milliseconds for input or output.
MCI_FORMAT_SAMPLES
	Changes the time format to samples for input or output.
LPMCI_WAVE_SET_PARMS lpSet

Points to the MCI_WAVE_SET_PARMS data structure. This parameter replaces the standard default parameter data structure identified by lpDefault.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.


  MCI_SOUND

This MCI command message plays system sounds identified in the [sounds] section of the registry file. The name of the sound is specified in the buffer pointed to by the lpstrSoundName member of the structure identified by lpInfo. This is an MCI system message that is not sent to any device.

Parameters

DWORD dwFlags

The following standard and command-specific flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpInfo.
MCI_WAIT
	Specifies that the playing of the sound should finish before MCI returns control to the application.
MCI_SOUND_NAME
	Indicates that the name of a sound to play is included in the lpstrSoundName of the structure identified by lpSound. If omitted, the default sound is played.
LPMCI_SOUND_PARMS lpInfo

Points to the MCI_SOUND_PARMS structure. The MCI_SOUND_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpstrSoundName;

} MCI_SOUND_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

This command will only play files that fit into available memory. Use the MCI waveform audio device to play longer waveform files.


  MCI_STATUS

This MCI command message is used to obtain information about an MCI device. All devices respond to this message. The parameters and flags available for this message depend on the selected device. Information is returned in the dwReturn member of the structure identified by lpStatus.

Parameters

DWORD dwFlags

The following standard and command-specific flags apply to all devices:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpStatus.
MCI_WAIT
	Specifies that the status operation should finish before MCI returns control to the application.
MCI_STATUS_ITEM
	Specifies that the dwItem member of the data structure identified by lpStatus contains a constant specifying which status item to obtain. The following constants define which status item to return in the dwReturn member of the structure:
Value	Meaning
MCI_STATUS_CURRENT_TRACK
	The dwReturn member is set to the current track number. MCI uses continuous track numbers.
MCI_STATUS_LENGTH
	The dwReturn member is set to the total media length.
MCI_STATUS_MODE
	The dwReturn member is set to the current mode of the device. The modes include the following: • MCI_MODE_NOT_READY  • MCI_MODE_PAUSE  • MCI_MODE_PLAY  • MCI_MODE_STOP  • MCI_MODE_OPEN  • MCI_MODE_RECORD  • MCI_MODE_SEEK
MCI_STATUS_NUMBER_OF_TRACKS
	The dwReturn member is set to the total number of playable tracks.
MCI_STATUS_POSITION
	The dwReturn member is set to the current position.
MCI_STATUS_READY
	The dwReturn member is set to TRUE if the device is ready; otherwise, it is set to FALSE.
MCI_STATUS_TIME_FORMAT
	The dwReturn member is set to the current time format of the device. The time formats include: • MCI_FORMAT_BYTES  • MCI_FORMAT_FRAMES  • MCI_FORMAT_HMS  • MCI_FORMAT_MILLISECONDS  • MCI_FORMAT_MSF  • MCI_FORMAT_SAMPLES  • MCI_FORMAT_TMSF
MCI_STATUS_START
	Obtains the starting position of the media. To get the starting position, combine this flag with MCI_STATUS_ITEM and set the dwItem member of the structure identified by lpStatus to MCI_STATUS_POSITION.
MCI_TRACK
	Indicates a status track parameter is included in the dwTrack member of the data structure identified by lpStatus. You must use this flag with the MCI_STATUS_POSITION or MCI_STATUS_LENGTH constants.
	When used with MCI_STATUS_POSITION, MCI_TRACK obtains the starting position of the specified track.
	When used with MCI_STATUS_LENGTH, MCI_TRACK obtains the length of the specified track. MCI uses continuous track numbers.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_STATUS_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwReturn;

    DWORD  dwItem;

    DWORD  dwTrack;

} MCI_STATUS_PARMS;

For a full description of this structure, see  Chapter 3, »Structures«.

Animation Extensions

Parameters

DWORD dwFlags

The following extensions apply to animation devices:

Value	Meaning
MCI_STATUS_ITEM
	Specifies that the dwItem member of the structure identified by lpStatus contains a constant specifying which status item to obtain. The following additional status constants are defined for animation devices and indicate which item to return in the dwReturn member of the structure:
MCI_ANIM_STATUS_FORWARD
	The dwReturn member is set to TRUE if playing forward; otherwise, it is set to FALSE.
MCI_ANIM_STATUS_HPAL
	The dwReturn member is set to the handle of the movie palette.
MCI_ANIM_STATUS_HWND
	The dwReturn member is set to the handle of the playback window.
MCI_ANIM_STATUS_SPEED
	The dwReturn member is set to the animation speed.
MCI_STATUS_MEDIA_PRESENT
	The dwReturn member is set to TRUE if the media is inserted in the device; otherwise, it is set to FALSE.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS structure.

CD Audio Extensions

Parameters

DWORD dwFlags

The following extensions applies to CD audio devices:

Value	Meaning
MCI_STATUS_ITEM
	Specifies that the dwItem member of the structure identified by lpStatus contains a constant specifying which status item to obtain. The following additional status constants are defined for CD audio devices and indicate which item to return in the dwReturn member of the structure:
MCI_STATUS_MEDIA_PRESENT
	The dwReturn member is set to TRUE if the media is inserted in the device; otherwise, it is set to FALSE.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS data structure. This parameter replaces the standard default parameter data structure.

MIDI Sequencer Extensions

Parameters

DWORD dwFlags

The following extensions apply to sequencers:

Value	Meaning
MCI_STATUS_ITEM
	Specifies that the dwItem member of the structure identified by lpStatus contains a constant specifying which status item to obtain. The following additional status constants are defined for sequencers and indicate which item to return in the dwReturn member of the structure:
MCI_SEQ_STATUS_DIVTYPE
	The dwReturn member is set to one of the following values indicating the current division type of a sequence: • MCI_SEQ_DIV_PPQN  • MCI_SEQ_DIV_SMPTE_24  • MCI_SEQ_DIV_SMPTE_25  • MCI_SEQ_DIV_SMPTE_30  • MCI_SEQ_DIV_SMPTE_30DROP
MCI_SEQ_STATUS_MASTER
	The dwReturn member is set to the synchronization type used for master operation.
MCI_SEQ_STATUS_OFFSET
	The dwReturn member is set to the current SMPTE offset of a sequence.
MCI_SEQ_STATUS_PORT
	The dwReturn member is set to the MIDI device ID for the current port used by the sequence.
MCI_SEQ_STATUS_SLAVE
	The dwReturn member is set to the synchronization type used for slave operation.
MCI_SEQ_STATUS_TEMPO
	The dwReturn member is set to the current tempo of a MIDI sequence in beats-per-minute for PPQN files, or frames-per-second for SMPTE files.
MCI_STATUS_MEDIA_PRESENT
	The dwReturn member is set to TRUE if the media for the device is present; otherwise, it is set to FALSE.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS structure. This parameter replaces the standard default parameter structure.

Videodisc Extensions

Parameters

DWORD dwFlags

The following additional flags apply to videodisc devices:

Value	Meaning
MCI_STATUS_ITEM
	Specifies that the dwItem member of the structure identified by lpStatus contains a constant specifying which status item to obtain. The following additional status constants are defined for videodisc devices and indicate which item to return in the dwReturn member of the structure:
MCI_STATUS_MEDIA_PRESENT
	The dwReturn member is set to TRUE if the media is inserted in the device; otherwise, it is set to FALSE.
MCI_VD_STATUS_DISC_SIZE
	The dwReturn member is set to the size of the loaded disc in inches (8 or 12).
MCI_VD_STATUS_FORWARD
	The dwReturn member is set to TRUE if playing forward; otherwise, it is set to FALSE.
MCI_VD_STATUS_MEDIA_TYPE
	The dwReturn member is set to the media type of the inserted media. The following media types can be returned: • MCI_VD_MEDIA_CAV  • MCI_VD_MEDIA_CLV  • MCI_VD_MEDIA_OTHER
MCI_STATUS_MODE
	The dwReturn member is set to the current mode of the device. All devices can return the following constants to indicate the current mode: • MCI_MODE_NOT_READY  • MCI_MODE_PAUSE  • MCI_MODE_PLAY  • MCI_MODE_STOP  • MCI_VD_MODE_PARK (videodisc devices)
MCI_VD_STATUS_SIDE
	The dwReturn member is set to 1 or 2 to indicate which side of the disc is loaded. Not all videodisc devices support this flag.
MCI_VD_STATUS_SPEED
	The dwReturn member is set to the play speed in frames per second.
	MCIPIONR returns MCIERR_UNSUPPORTED_FUNCTION.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS structure. This parameter replaces the standard default parameter structure.

Waveform Audio Extensions

Parameters

DWORD dwFlags

The following additional flags apply to waveform audio devices:

Value	Meaning
MCI_STATUS_ITEM
	Specifies that the dwItem member of the structure identified by lpStatus contains a constant specifying which status item to obtain. The following additional status constants are defined for waveform audio devices and indicate which item to return in the dwReturn member of the structure:
MCI_STATUS_MEDIA_PRESENT
	The dwReturn member is set to TRUE if the media is inserted in the device; otherwise, it is set to FALSE.
MCI_WAVE_INPUT
	The dwReturn member is set to the wave input device used for recording. If no device is in use and no device has been explicitly set, then the error return is MCI_WAVE_INPUTUNSPECIFIED.
MCI_WAVE_OUTPUT
	The dwReturn member is set to the wave output device used for playing. If no device is in use and no device has been explicitly set, then the error return is MCI_WAVE_OUTPUTUNSPECIFIED.
MCI_WAVE_STATUS_AVGBYTESPERSEC
	The dwReturn member is set to the current bytes per second used for playing, recording, and saving.
MCI_WAVE_STATUS_BITSPERSAMPLE
	The dwReturn member is set to the current bits per sample used for playing, recording, and saving.
MCI_WAVE_STATUS_BLOCKALIGN
	The dwReturn member is set to the current block alignment used for playing, recording, and saving.
MCI_WAVE_STATUS_CHANNELS
	The dwReturn member is set to the current channel count used for playing, recording, and saving.
MCI_WAVE_FORMATTAG
	The dwReturn member is set to the current format tag used for playing, recording, and saving.
MCI_WAVE_STATUS_LEVEL
	The dwReturn member is set to the current record or playback level. The value is returned as an 8- or 16-bit value, depending on the sample size used. The right or mono channel level is returned in the low-order word. The left channel level is returned in the high-order word.
MCI_WAVE_STATUS_SAMPLESPERSEC
	The dwReturn member is set to the current samples per second used for playing, recording, and saving.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS structure.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices:

Value	Meaning
MCI_OVLY_STATUS_HWND
	The dwReturn member is set to the handle of the window associated with the video overlay device.
MCI_STATUS_ITEM
	Specifies that the dwItem member of the structure identified by lpStatus contains a constant specifying which status item to obtain. The following additional status constants are defined for video overlay devices and indicate which item to return in the dwReturn member of the structure:
MCI_STATUS_MEDIA_PRESENT
	The dwReturn member is set to TRUE if the media is inserted in the device; otherwise, it is set to FALSE.
LPMCI_STATUS_PARMS lpStatus

Points to the MCI_STATUS_PARMS structure.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.


  MCI_STEP

This MCI command message steps the player one or more frames.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_STEP:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpStep.
MCI_WAIT
	Specifies that the step operation should finish before MCI returns control to the application.
Animation Extensions

Parameters

DWORD dwFlags

The following additional flag applies to animation devices.

Value	Meaning
MCI_ANIM_STEP_FRAMES
	Indicates that the dwFrames member of the structure identified by lpStep specifies the number of frames to step.
MCI_ANIM_STEP_REVERSE
	Steps in reverse.
LPMCI_ANIM_STEP_PARMS lpStep

Points to the MCI_ANIM_STEP_PARMS structure.

Videodisc Extensions

Parameters

DWORD dwFlags

The following additional flags apply to videodisc devices.

Value	Meaning
MCI_VD_STEP_FRAMES
	Indicates that the dwFrames member of the structure identified by lpStep specifies the number of frames to step.
MCI_VD_STEP_REVERSE
	Steps in reverse.
LPMCI_VD_STEP_PARMS lpStep

Points to a MCI_VD_STEP_PARMS structure. The MCI_VD_STEP_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrames;

} MCI_VD_STEP_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

Only devices that return TRUE to the MCI_GETDEVCAPS_HAS_VIDEO capability query support this command at present.

See Also

»MCI_CUE«, »MCI_PLAY«, »MCI_SEEK«


  MCI_STOP

This MCI command message stops all play and record sequences, unloads all play buffers, and ceases display of video images. Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_STOP:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpStop.
MCI_WAIT
	Specifies that the device should stop before MCI returns control to the application.
LPMCI_GENERIC_PARMS lpStop

Points to the MCI_GENERIC_PARMS structure. (Devices with extended command sets might replace this structure with a device-specific structure.) The MCI_GENERIC_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

The difference between MCI_STOP and MCI_PAUSE depends upon the device. If possible, MCI_PAUSE suspends device operation but leaves the device ready to resume play immediately.

See Also

»MCI_PAUSE«, »MCI_PLAY«, »MCI_RECORD«, »MCI_RESUME«


  MCI_SYSINFO

This MCI command message returns information about MCI devices. MCI supports this message directly rather than passing it to the devices. String information is returned in the application-supplied buffer pointed to by the lpstrReturn member of the structure identified by lpSysInfo. Numeric information is returned as a DWORD placed in the application-supplied buffer. The dwReturnSize member specifies the buffer length.

Parameters

DWORD dwFlags

The following standard and command-specific flags apply to all devices:

Value	Meaning
MCI_SYSINFO_INSTALLNAME
	Obtains the name (listed in the registry) used to install the device.
MCI_SYSINFO_NAME
	Obtains a device name corresponding to the device number specified in the dwNumbermember of the structure identified by lpSysInfo . If the MCI_SYSINFO_OPEN flag is set, MCI returns the names of open devices.
MCI_SYSINFO_OPEN
	Obtains the quantity or name of open devices.
MCI_SYSINFO_QUANTITY
	Obtains the number of devices of the specified type that are listed in the [mci] section of the registry file. If the MCI_SYSINFO_OPEN flag is set, the number of open devices is returned.
LPMCI_SYSINFO_PARMS lpSysInfo

Points to the MCI_SYSINFO_PARMS structure. The MCI_SYSINFO_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    LPTSTR  lpstrReturn;

    DWORD  dwRetSize;

    DWORD  dwNumber;

    UINT  wDeviceType;

} MCI_SYSINFO_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

The wDeviceType element of the lpSysInfo structure is used to indicate the device type of the query. If the wDeviceID parameter is set to MCI_ALL_DEVICE_ID it will override the value of wDeviceType.

Integer return values are doublewords returned in the buffer pointed to by the lpstrReturn member of MCI_SYSINFO_PARMS.

String return values are NULL-terminated strings returned in the buffer pointed to by the lpstrReturn member.


  MCI_UNFREEZE

This MCI command message restores motion to an area of the video buffer frozen with MCI_FREEZE. This command is part of the video overlay command set. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_UNFREEZE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpFreeze.
MCI_WAIT
	Specifies that the unfreeze operation should finish before MCI returns control to the application.
MCI_OVLY_RECT
	Specifies that the rc member of the data structure identified by lpFreeze contains a valid display rectangle. This is a required parameter.
LPMCI_OVLY_RECT_PARMS lpFreeze

Points to a MCI_OVLY_RECT_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.) The MCI_OVLY_RECT_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_OVLY_RECT_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

This command applies to video overlay devices.

See Also

»MCI_FREEZE«


  MCI_WHERE

This MCI command message obtains the clipping rectangle for the video device. The top and left members of the returned rectangle contain the origin of the clipping rectangle, and the right and bottom members contain the width and height of the clipping rectangle. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_WHERE:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpQuery.
MCI_WAIT
	Specifies that the operation should complete before MCI returns control to the application.
DWORD lpQuery

Points to a device-specific structure. For a description of this parameter, see the lpQuery description included with the device extensions.

Animation Extensions

Parameters

DWORD dwFlags

The following additional flags apply to animation devices supporting MCI_WHERE:

Value	Meaning
MCI_ANIM_WHERE_DESTINATION
	Obtains the destination display rectangle. The rectangle coordinates are placed in the rc member of the data structure identified by lpQuery.
MCI_ANIM_WHERE_SOURCE
	Obtains the animation source rectangle. The rectangle coordinates are placed in the rc member of the data structure identified by lpQuery.
LPMCI_ANIM_RECT_PARMS lpQuery

Points to a MCI_ANIM_RECT_PARMS structure. The MCI_ANIM_RECT_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_ANIM_RECT_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices supporting MCI_WHERE:

Value	Meaning
MCI_OVLY_WHERE_DESTINATION
	Obtains the destination display rectangle. The rectangle coordinates are placed in the rc member of the structure identified by lpQuery.
MCI_OVLY_WHERE_FRAME
	Obtains the overlay frame rectangle. The rectangle coordinates are placed in the rc member of the structure identified by lpQuery.
MCI_OVLY_WHERE_SOURCE
	Obtains the source rectangle. The rectangle coordinates are placed in the rc member of the structure identified by lpQuery.
MCI_OVLY_WHERE_VIDEO
	Obtains the video rectangle. The rectangle coordinates are placed in the rc member of the structure identified by lpQuery.
LPMCI_OVLY_RECT_PARMS lpQuery

Points to a MCI_OVLY_RECT_PARMS structure. The MCI_OVLY_RECT_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_OVLY_RECT_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

This command applies to animation and video overlay devices.

See Also

»MCI_PUT«


  MCI_WINDOW

This MCI command message specifies the window and the window characteristics for graphic devices. Graphic devices should create a default window when a device is opened but should not display it until they receive the play command. The window command is used to supply an application-created window to the device and to change the display characteristics of an application-supplied or default display window. If the application supplies the display window, it should be prepared to update an invalid rectangle on the window.

Support of this message by a device is optional. The parameters and flags for this message vary according to the selected device.

Parameters

DWORD dwFlags

The following flags apply to all devices supporting MCI_WINDOW:

Value	Meaning
MCI_NOTIFY
	Specifies that MCI should post the MM_MCINOTIFY message when this command completes. The window to receive this message is specified in the dwCallback member of the structure identified by lpWindow.
MCI_WAIT
	Specifies that the operation should finish before MCI returns control to the application.
DWORD lpWindow

Points to a device specific structure. For a description of this parameter, see the lpWindow description included with the device extensions.

Animation Extensions

Parameters

DWORD dwFlags

The following additional flags apply to animation devices supporting MCI_WINDOW:

Value	Meaning
MCI_ANIM_WINDOW_HWND
	Indicates the handle of the window to use for the destination is included in the hWnd member of the structure identified by lpWindow. Set this to MCI_ANIM_WINDOW_DEFAULT to return to the default window.
MCI_ANIM_WINDOW_STATE
	Indicates the nCmdShow member of the MCI_ANIM_WINDOW_PARMS structure contains parameters for setting the window state. This flag is equivalent to calling ShowWindow with the state parameter. The constants are the same as the ones in WINDOWS.H (such as SW_HIDE, SW_MINIMIZE, or SW_SHOWNORMAL.)
MCI_ANIM_WINDOW_TEXT
	Indicates the lpstrText member of the MCI_ANIM_WINDOW_PARMS structure contains a pointer to a buffer containing the caption used for the window.
LPMCI_ANIM_WINDOW_PARMS lpWindow

Points to a MCI_ANIM_WINDOW_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.) The MCI_ANIM_WINDOW_PARMS structure has the following form:

typedef struct tagMCI_ANIM_WINDOW_PARMS {

    DWORD  dwCallback;

    DWORD  hWnd;

    UINT  nCmdShow;

    LPCTSTR  lpstrText;

} MCI_ANIM_WINDOW_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Video Overlay Extensions

Parameters

DWORD dwFlags

The following additional flags apply to video overlay devices supporting MCI_WINDOW:

Value	Meaning
MCI_OVLY_WINDOW_HWND
	Indicates the handle of the window used for the destination is included in the hWnd member of the MCI_OVLY_WINDOW_PARMS structure. Set this to MCI_OVLY_WINDOW_DEFAULT to return to the default window.
MCI_OVLY_WINDOW_STATE
	Indicates the nCmdShow member of the lpWindow structure contains parameters for setting the window state. This flag It is equivalent to calling showwindow with the state parameter. The constants are the same as those defined in WINDOWS.H (such as SW_HIDE, SW_MINIMIZE, or SW_SHOWNORMAL.)
MCI_OVLY_WINDOW_TEXT
	Indicates the lpstrText member of the MCI_OVLY_WINDOWS_PARMS structure contains a pointer to buffer containing the caption used for the window.
LPMCI_OVLY_WINDOW_PARMS lpWindow

Points to a MCI_OVLY_WINDOW_PARMS structure. (Devices with additional parameters might replace this structure with a device-specific structure.) The MCI_OVLY_WINDOW_PARMS structure has the following form:

typedef struct {

    DWORD  dwCallback;

    HWND   hWnd;

    UINT   nCmdShow;

    LPCTSTR  lpstrText;

} MCI_OVLY_WINDOW_PARMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

This command applies to animation, and video overlay devices.


  MIM_CLOSE

This message is sent to a MIDI input callback function when a MIDI input device is closed. The device handle is no longer valid once this message has been sent.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_MIM_CLOSE«


  MIM_DATA

This message is sent to a MIDI input callback function when a MIDI message is received by a MIDI input device.

Parameters

DWORD dwParam1

Specifies the MIDI message that was received. The message is packed into a DWORD with the first byte of the message in the low-order byte.

DWORD dwParam2

Specifies the time that the message was received by the input device driver. The timestamp is specified in milliseconds, beginning at 0 when midiInStart was called.

Return Value

None.

Comments

MIDI messages received from a MIDI input port have running status disabled; each message is expanded to include the MIDI status byte.

This message is not sent when a MIDI system-exclusive message is received.

See Also

»MM_MIM_DATA«, »MIM_LONGDATA«


  MIM_ERROR

This message is sent to a MIDI input callback function when an invalid MIDI message is received.

Parameters

DWORD dwParam1

Specifies the invalid MIDI message that was received. The message is packed into a DWORD with the first byte of the message in the low-order byte.

DWORD dwParam2

Specifies the time that the message was received by the input device driver. The timestamp is specified in milliseconds, beginning at 0 when midiInStart was called.

Return Value

None.

See Also

»MM_MIM_ERROR«


  MIM_LONGDATA

This message is sent to a MIDI input callback function when an input buffer has been filled with MIDI system-exclusive data and is being returned to the application.

Parameters

DWORD dwParam1

Points to a MIDIHDR structure identifying the input buffer. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Specifies the time that the data was received by the input device driver. The timestamp is specified in milliseconds, beginning at 0 when midiInStart was called.

Return Value

None.

Comments

The returned buffer may not be full. The dwBytesRecorded member of the MIDIHDR structure specified by dwParam1 will specify the number of bytes recorded into the buffer.

See Also

»MIM_DATA«, »MM_MIM_LONGDATA«


  MIM_LONGERROR

This message is sent to a MIDI input callback function when an invalid MIDI system-exclusive message is received.

Parameters

DWORD dwParam1

Specifies a pointer to a MIDIHDR structure identifying the buffer containing the invalid message. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Specifies the time that the data was received by the input device driver. The timestamp is specified in milliseconds, beginning at 0 when midiInStart was called.

Return Value

None.

Comments

The returned buffer may not be full. The dwBytesRecorded member of the MIDIHDR structure specified by dwParam1 will specify the number of bytes recorded into the buffer.

See Also

»MM_MIM_LONGERROR«


  MIM_OPEN

This message is sent to a MIDI input callback function when a MIDI input device is opened.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_MIM_OPEN«


  MM_JOY1BUTTONDOWN

This message is sent to the window that has captured joystick 1 when a button is pressed.

Parameters

WPARAM wParam

Indicates which button has changed state. It can be any one of the following combined with any of the flags defined in MM_JOY1MOVE.

Value	Meaning
JOY_BUTTON1CHG
	Set if first joystick button has changed.
JOY_BUTTON2CHG
	Set if second joystick button has changed.
JOY_BUTTON3CHG
	Set if third joystick button has changed.
JOY_BUTTON4CHG
	Set if fourth joystick button has changed.
LPARAM lParam

The low-order word contains the current x-position of the joystick. The high-order word contains the current y-position.

Return Value

None.

See Also

»MM_JOY1BUTTONUP«


  MM_JOY1BUTTONUP

This message is sent to the window that has captured joystick one when a button is released.

Parameters

WORD wParam

Indicates which button has changed state. It can be any one of the following combined with any of the flags defined in MM_JOY1MOVE.

Value	Meaning
JOY_BUTTON1CHG
	Set if first joystick button has changed.
JOY_BUTTON2CHG
	Set if second joystick button has changed.
JOY_BUTTON3CHG
	Set if third joystick button has changed.
JOY_BUTTON4CHG
	Set if fourth joystick button has changed.
DWORD lParam

The low-order word contains the current x-position of the joystick. The high-order word contains the current y-position.

Return Value

None.

See Also

»MM_JOY1BUTTONDOWN«


  MM_JOY1MOVE

This message is sent to the window that has captured joystick 1 when the joystick position changes.

Parameters

WPARAM wParam

Indicates which joystick buttons are pressed. It can be any combination of the following values:

Value	Meaning
JOY_BUTTON1
	Set if first joystick button is pressed.
JOY_BUTTON2
	Set if second joystick button is pressed.
JOY_BUTTON3
	Set if third joystick button is pressed.
JOY_BUTTON4
	Set if fourth joystick button is pressed.
LPARAM lParam

The low-order word contains the current x-position of the joystick. The high-order word contains the current y-position.

Return Value

None.

See Also

»MM_JOY1ZMOVE«


  MM_JOY1ZMOVE

This message is sent to the window that has captured joystick 1 when the z-axis position changes.

Parameters

WPARAM wParam

Indicates which joystick buttons are pressed. It can be any combination of the following values:

Value	Meaning
JOY_BUTTON1
	Set if first joystick button is pressed.
JOY_BUTTON2
	Set if second joystick button is pressed.
JOY_BUTTON3
	Set if third joystick button is pressed.
JOY_BUTTON4
	Set if fourth joystick button is pressed.
LPARAM lParam

The low-order word contains the current z-position of the joystick.

Return Value

None.

See Also

»MM_JOY1MOVE«


  MM_JOY2BUTTONDOWN

This message is sent to the window that has captured joystick 2 when a button is pressed.

Parameters

WPARAM wParam

Indicates which button has changed state. It can be any one of the following combined with any of the flags defined in MM_JOY1MOVE.

Value	Meaning
JOY_BUTTON1CHG
	Set if first joystick button has changed.
JOY_BUTTON2CHG
	Set if second joystick button has changed.
JOY_BUTTON3CHG
	Set if third joystick button has changed.
JOY_BUTTON4CHG
	Set if fourth joystick button has changed.
LPARAM lParam

The low-order word contains the current x-position of the joystick. The high-order word contains the current y-position.

Return Value

None.

See Also

»MM_JOY2BUTTONUP«


  MM_JOY2BUTTONUP

This message is sent to the window that has captured joystick 2 when a button is released.

Parameters

WORD wParam

Indicates which button has changed state. It can be any one of the following combined with any of the flags defined in MM_JOY1MOVE.

Value	Meaning
JOY_BUTTON1CHG
	Set if first joystick button has changed.
JOY_BUTTON2CHG
	Set if second joystick button has changed.
JOY_BUTTON3CHG
	Set if third joystick button has changed.
JOY_BUTTON4CHG
	Set if fourth joystick button has changed.
DWORD lParam

The low-order word contains the current x-position of the joystick. The high-order word contains the current y-position.

Return Value

None.

See Also

»MM_JOY2BUTTONDOWN«


  MM_JOY2MOVE

This message is sent to the window that has captured joystick 2 when the joystick position changes.

Parameters

WPARAM wParam

Indicates which joystick buttons are pressed. It can be any combination of the following values:

Value	Meaning
JOY_BUTTON1
	Set if first joystick button is pressed.
JOY_BUTTON2
	Set if second joystick button is pressed.
JOY_BUTTON3
	Set if third joystick button is pressed.
JOY_BUTTON4
	Set if fourth joystick button is pressed.
WPARAM lParam

The low-order word contains the current x-position of the joystick. The high-order word contains the current y-position.

Return Value

None.

See Also

»MM_JOY2ZMOVE«


  MM_JOY2ZMOVE

This message is sent to the window that has captured joystick 2 when the z-axis position changes.

Parameters

WPARAM wParam

Indicates which joystick buttons are pressed. It can be any combination of the following values:

Value	Meaning
JOY_BUTTON1
	Set if first joystick button is pressed.
JOY_BUTTON2
	Set if second joystick button is pressed.
JOY_BUTTON3
	Set if third joystick button is pressed.
JOY_BUTTON4
	Set if fourth joystick button is pressed.
LPARAM lParam

The low-order word contains the current z-position of the joystick.

Return Value

None.

See Also

»MM_JOY2MOVE«


  MM_MCINOTIFY

This message is sent to a window to notify an application that an MCI device has completed an operation. MCI devices send this message only when the MCI_NOTIFY flag is used with an MCI command message or when the notify flag is used with an MCI command string.

Parameters

WORD wParam

Contains one of the following flags:

Value	Meaning
MCI_NOTIFY_ABORTED
	Specifies that the device received a command that prevented the current conditions for initiating the callback from being met. If a new command interrupts the current command and it also requests notification, the device sends only this message and not MCI_NOTIFY_SUPERCEDED.
MCI_NOTIFY_SUCCESSFUL
	Specifies that the conditions initiating the callback have been met.
MCI_NOTIFY_SUPERSEDED
	Specifies that the device received another command with the MCI_NOTIFY flag set and the current conditions for initiating the callback have been superseded.
MCI_NOTIFY_FAILURE
	Specifies that a device error occurred while the device was executing the command.
LONG lParam

The low-order word specifies the ID of the device initiating the callback.

Return Value

Returns zero if successful. Otherwise, it returns an MCI error code.

Comments

A device returns the flag MCI_NOTIFY_SUCCESSFUL with MM_MCINOTIFY when the action for a command finishes. For example, a CD audio device uses this flag for notification for MCI_PLAY when the device finishes playing. The MCI_PLAY command is successful only when it reaches the specified end position or reaches the end of the media. Similarly, MCI_SEEK and MCI_RECORD do not return MCI_NOTIFY_SUCCESSFUL until they reach the specified end position or reach the end of the media.

A device returns the flag MCI_NOTIFY_ABORTED with MM_MCINOTIFY only when it receives a command that prevents it from meeting the notification conditions. For example, the command MCI_PLAY would not abort notification for a previous play command provided that the new command does not change the play direction or change the ending position for the play command with an active notify. The MCI_RECORD and MCI_SEEK commands behave similarly.

MCI also does not send MCI_NOTIFY_ABORTED when MCI_PLAY or MCI_RECORD is paused with MCI_PAUSE. Sending the MCI_RESUME command will let them continue to meet the callback conditions.

When your application requests notification for a command, check the error return of mciSendMessage or mciSendCommand. If these functions encounter an error and return a nonzero value, MCI will not set notification for the command.


  MM_MIM_CLOSE

This message is sent to a window when a MIDI input device is closed. The device handle is no longer valid once this message has been sent.

Parameters

WORD wParam

Specifies a handle to the MIDI input device that was closed.

LONG lParam

Currently unused.

Return Value

None.

See Also

»MIM_CLOSE«


  MM_MIM_DATA

This message is sent to a window when a MIDI message is received by a MIDI input device.

Parameters

WORD wParam

Specifies a handle to the MIDI input device that received the MIDI message.

LONG lParam

Specifies the MIDI message that was received. The message is packed into a DWORD with the first byte of the message in the low-order byte.

Return Value

None.

Comments

MIDI messages received from a MIDI input port have running status disabled; each message is expanded to include the MIDI status byte.

This message is not sent when a MIDI system-exclusive message is received. No timestamp is available with this message. For timestamped input data, you must use the messages that are sent to low-level callback functions.

See Also

»MIM_DATA«, »MM_MIM_LONGDATA«


  MM_MIM_ERROR

This message is sent to a window when an invalid MIDI message is received.

Parameters

WORD wParam

Specifies a handle to the MIDI input device that received the invalid message.

LONG lParam

Specifies the invalid MIDI message. The message is packed into a DWORD with the first byte of the message in the low-order byte.

Return Value

None.

See Also

»MIM_ERROR«


  MM_MIM_LONGDATA

This message is sent to a window when an input buffer has been filled with MIDI system-exclusive data and is being returned to the application.

Parameters

WORD wParam

Specifies a handle to the MIDI input device that received the data.

LONG lParam

Points to a MIDIHDR structure identifying the buffer. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

None.

Comments

The returned buffer may not be full. The dwBytesRecorded member of the MIDIHDR structure specified by lParam will specify the number of bytes recorded into the buffer.

No timestamp is available with this message. For timestamped input data, you must use the messages that are sent to low-level callback functions.

See Also

»MM_MIM_DATA«, »MIM_LONGDATA«


  MM_MIM_LONGERROR

This message is sent to a window when an invalid MIDI system-exclusive message is received.

Parameters

WORD wParam

Specifies a handle to the MIDI input device that received the invalid message.

LONG lParam

Points to a MIDIHDR structure identifying buffer containing the invalid message. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

None.

Comments

The returned buffer may not be full. The dwBytesRecorded member of the MIDIHDR structure specified by lParam will specify the number of bytes recorded into the buffer.

See Also

»MIM_LONGERROR«


  MM_MIM_OPEN

This message is sent to a window when a MIDI input device is opened.

Parameters

WORD wParam

Specifies the handle to the MIDI input device that was opened.

LONG lParam

Currently unused.

Return Value

None.

See Also

»MIM_OPEN«


  MM_MOM_CLOSE

This message is sent to a window when a MIDI output device is closed. The device handle is no longer valid once this message has been sent.

Parameters

WORD wParam

Specifies the handle to the MIDI output device.

LONG lParam

Currently unused.

Return Value

None.

See Also

»MOM_CLOSE«


  MM_MOM_DONE

This message is sent to a window when the specified system-exclusive buffer has been played and is being returned to the application.

Parameters

WORD wParam

Specifies a handle to the MIDI output device that played the buffer.

LONG lParam

Points to a MIDIHDR structure identifying the buffer. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

None.

See Also

»MOM_DONE«


  MM_MOM_OPEN

This message is sent to a window when a MIDI output device is opened.

Parameters

WORD wParam

Specifies the handle to the MIDI output device.

LONG lParam

Currently unused.

Return Value

None.

See Also

»MOM_OPEN«


  MM_WIM_CLOSE

This message is sent to a window when a waveform input device is closed. The device handle is no longer valid once this message has been sent.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»WIM_CLOSE«


  MM_WIM_DATA

This message is sent to a window when waveform data is present in the input buffer and the buffer is being returned to the application. The message can be sent either when the buffer is full, or after the waveInReset function is called.

Parameters

DWORD dwParam1

Points to a WAVEHDR structure identifying the buffer containing the waveform data. The WAVEHDR structure has the following form:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Currently unused.

Return Value

None.

Comments

The returned buffer may not be full. The dwBytesRecorded member of the WAVEHDR structure specified by dwParam1 will specify the number of bytes recorded into the buffer.

See Also

»WIM_DATA«


  MM_WIM_OPEN

This message is sent to a window when a waveform input device is opened.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»WIM_OPEN«


  MM_WOM_CLOSE

This message is sent to a window when a waveform output device is closed. The device handle is no longer valid once this message has been sent.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»WOM_CLOSE«


  MM_WOM_DONE

This message is sent to a window when the specified output buffer is being returned to the application. Buffers are returned to the application when they have been played, or as the result of a call to waveOutReset.

Parameters

DWORD dwParam1

Points to a WAVEHDR structure identifying the buffer. The WAVEHDR structure has the following form:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»WOM_DONE«


  MM_WOM_OPEN

This message is sent to a window when a waveform output device is opened.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»WOM_OPEN«


  MMIOM_CLOSE

This message is sent to an I/O procedure by mmioClose to request that a file be closed.

Parameters

LONG lParam1

Specifies options contained in the wFlags parameter of mmioClose.

LONG lParam2

Is not used.

Return Value

The return value is zero if the file is successfully closed. Otherwise, the return value specifies an error code.

See Also

»mmioClose«, »MMIOM_OPEN«


  MMIOM_OPEN

This message is sent to an I/O procedure by mmioOpen to request that a file be opened or deleted.

Parameters

LONG lParam1

Specifies a null-terminated string containing the name of the file to open.

LONG lParam2

Is not used.

Return Value

The return value is zero if the operation is successful. Otherwise, the return value specifies an error value. Possible error returns are:

Value	Meaning
MMIOM_CANNOTOPEN
	Specified file could not be opened.
MMIOM_OUTOFMEMORY
	Not enough memory to perform operation.
Comments

The dwFlags member of the MMIOINFO structure contains option flags passed to the mmioOpen function. The lDiskOffset member of the MMIOINFO structure is initialized to zero. If this value is incorrect, then the I/O procedure must correct it.

If the caller passed a MMIOINFO structure to mmioOpen, the return value will be returned in the wErrorRet member.

See Also

»mmioOpen«, »MMIOM_CLOSE«


  MMIOM_READ

This message is sent to an I/O procedure by mmioRead to request that a specified number of bytes be read from an open file.

Parameters

LONG lParam1

Points to the buffer to be filled with data read from the file.

LONG lParam2

Specifies the number of bytes to read from the file.

Return Value

The return value is the number of bytes actually read from the file. If no more bytes can be read, the return value is zero. If there is an error, the return value is -1.

Comments

The I/O procedure is responsible for updating the lDiskOffset member of the MMIOINFO structure to reflect the new file position after the read operation.

See Also

»mmioRead«, »MMIOM_WRITE«, »MMIOM_WRITEFLUSH«


  MMIOM_SEEK

This message is sent to an I/O procedure by mmioSeek to request that the current file position be moved.

Parameters

LONG lParam1

Specifies the new file position according to the option flag specified in lParam2.

LONG lParam2

Specifies how the file position is changed. Only one of the following flags can be specified:

Value	Meaning
SEEK_SET
	Move the file position to be lParam1 bytes from the beginning of the file.
SEEK_CUR
	Move the file position to be lParam1 bytes from the current position. lParam1 may be positive or negative.
SEEK_END
	Move the file position to be lParam1 bytes from the end of the file.
Return Value

The return value is the new file position. If there is an error, the return value is -1.

Comments

The I/O procedure is responsible for maintaining the current file position in the lDiskOffset member of the MMIOINFO structure.

See Also

»mmioSeek«


  MMIOM_WRITE

This message is sent to an I/O procedure by mmioWrite to request that data be written to an open file.

Parameters

LONG lParam1

Points to a buffer containing the data to write to the file.

LONG lParam2

Specifies the number of bytes to write to the file.

Return Value

The return value is the number of bytes actually written to the file. If there is an error, the return value is -1.

Comments

The I/O procedure is responsible for updating the lDiskOffset member of the MMIOINFO structure to reflect the new file position after the write operation.

See Also

»mmioWrite«, »MMIOM_READ«, »MMIOM_WRITEFLUSH«


  MMIOM_WRITEFLUSH

This message is sent to an I/O procedure by mmioWrite to request that data be written to an open file and then that any internal buffers used by the I/O procedure be flushed to disk.

Parameters

LONG lParam1

Points to a buffer containing the data to write to the file.

LONG lParam2

Specifies the number of bytes to write to the file.

Return Value

The return value is the number of bytes actually written to the file. If there is an error, the return value is -1.

Comments

The I/O procedure is responsible for updating the lDiskOffset member of the MMIOINFO structure to reflect the new file position after the write operation.

Note that this message is equivalent to the MMIOM_WRITE message except that it additionally requests that the I/O procedure flush its internal buffers, if any. Unless an I/O procedure performs internal buffering, this message can be handled exactly like the MMIOM_WRITE message.

See Also

»mmioWrite«, »mmioFlush«, »MMIOM_READ«, »MMIOM_WRITE«


  MOM_CLOSE

This message is sent to a MIDI output callback function when a MIDI output device is closed. The device handle is no longer valid once this message has been sent.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_MOM_CLOSE«


  MOM_DONE

This message is sent to a MIDI output callback function when the specified system-exclusive buffer has been played and is being returned to the application.

Parameters

DWORD dwParam1

Points to a MIDIHDR structure identifying the buffer. The MIDIHDR structure has the following form:

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_MOM_DONE«


  MOM_OPEN

This message is sent to a MIDI output callback function when a MIDI output device is opened.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_MOM_OPEN«


  SBM_ENABLE_ARROWS

SBM_ENABLE_ARROWS

wParam = (WPARAM) fuArrowFlags; /* scroll-bar arrow flags */

lParam = 0;                     /* not used, must be zero */

An application sends the SBM_ENABLE_ARROWS message to enable or disable one or both arrows of a scroll bar control.

Parameters

fuArrowFlags

Specifies whether the scroll bar arrows are enabled or disabled and indicates which arrows are enabled or disabled. This parameter can be one of the following values:

Value	Meaning
ESB_ENABLE_BOTH	Enables both arrows on a scroll bar.
ESB_DISABLE_LTUP	Disables the left arrow on a horizontal scroll bar or the up arrow of a vertical scroll bar.
ESB_DISABLE_RTDN	Disables the right arrow on a horizontal scroll bar or the down arrow of a vertical scroll bar.
ESB_DISABLE_BOTH	Disables both arrows on a scroll bar.
Return Value

If the message succeeds, the return value is TRUE; otherwise, it is FALSE.


  SBM_GETPOS

SBM_GETPOS

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the SBM_GETPOS message to retrieve the current position of the scroll box of a scroll bar control. The current position is a relative value that depends on the current scrolling range. For example, if the scrolling range is 0 through 100 and the scroll box is in the middle of the bar, the current position is 50.

Parameters

This message has no parameters.

Return Value

If the message succeeds, the return value is the current position of the scroll box in the scroll bar.

See Also

»SBM_GETRANGE«, »SBM_SETPOS«, »SBM_SETRANGE«, »SBM_SETRANGEREDRAW«


  SBM_GETRANGE

SBM_GETRANGE

wParam = (WPARAM) (LPINT) lpnMinPos; /* minimum position */

lParam = (LPARAM) (LPINT) lpnMaxPos; /* maximum position */

An application sends the SBM_GETRANGE message to a scroll bar control to retrieve the minimum and maximum position values for the control.

Parameters

lpnMinPos

Points to a value that receives the minimum scrolling position.

lpnfMaxPos

Points to a value that receives the maximum scrolling position.

Return Value

This message does not return a value.

See Also

»SBM_GETPOS«, »SBM_SETPOS«, »SBM_SETRANGE«, »SBM_SETRANGEREDRAW«


  SBM_SETPOS

SBM_SETPOS

wParam = (WPARAM) nPos;           /* new position of scroll box */

lParam = (LPARAM) (BOOL) fRedraw; /* redraw flag                */

An application sends the SBM_SETPOS message to a scroll bar control to set the position of the scroll box (thumb) and, if requested, redraw the scroll bar to reflect the new position of the scroll box.

Parameters

nPos

Specifies the new position of the scroll box. It must be within the scrolling range.

fRedraw

Specifies whether the scroll bar should be redrawn to reflect the new scroll box position. If this parameter is TRUE, the scroll bar is redrawn. If it is FALSE, the scroll bar is not redrawn.

Return Value

If the position of the scroll box changed, the return value is the previous position of the scroll box; otherwise, it is zero.

Comments

Setting the fRedraw parameter to FALSE is useful if the scroll bar control is redrawn by a subsequent call to another function.

See Also

»SBM_GETPOS«, »SBM_GETRANGE«, »SBM_SETRANGE«, »SBM_SETRANGEREDRAW«


  SBM_SETRANGE

SBM_SETRANGE

wParam = (WPARAM) nMinPos; /* minimum scrolling position */

lParam = (LPARAM) nMaxPos; /* maximum scrolling position */

An application sends the SBM_SETRANGE message to a scroll bar control to set the minimum and maximum position values for the control.

Parameters

nMinPos

Specifies the minimum scrolling position.

fMaxPos

Specifies the maximum scrolling position.

Return Value

The return value is always zero.

Comments

The default minimum and maximum position values are 0. The difference between the values specified by the nMinPos and nMaxPos parameters must not be greater than 32,767.

If the minimum and maximum position values are equal, the scroll bar control is hidden and, in effect, disabled.

See Also

»SBM_GETPOS«, »SBM_GETRANGE«, »SBM_SETPOS«, »SBM_SETRANGEREDRAW«


  SBM_SETRANGEREDRAW

SBM_SETRANGEREDRAW

wParam = (WPARAM) nMinPos; /* minimum scrolling position */

lParam = (LPARAM) nMaxPos  /* maximum scrolling position */

An application sends the SBM_SETRANGEREDRAW message to a scroll bar control to set the minimum and maximum position values and to redraw the control.

Parameters

nMinPos

Specifies the minimum scrolling position.

fMaxPos

Specifies the maximum scrolling position.

Return Value

If the position of the scroll box changed, the return value is the previous position of the scroll box; otherwise, it is zero.

Comments

The default minimum and maximum position values are 0. The difference between the values specified by the nMinPos and nMaxPos parameters must not be greater than 32,767.

If the minimum and maximum position values are equal, the scroll bar control is hidden and, in effect, disabled.

See Also

»SBM_GETPOS«, »SBM_GETRANGE«, »SBM_SETPOS«, »SBM_SETRANGE«


  STM_GETICON

STM_GETICON

wParam = 0; /* not used; must be zero */

lParam = 0; /* not used; must be zero */

An application sends the STM_GETICON message to retrieve the handle of the icon associated with an icon control.

Parameters

This message has no parameters.

Return Value

The return value is the handle of the icon, or zero if either the icon control has no associated icon or if an error occurred.

See Also

»STM_SETICON«


  STM_SETICON

STM_SETICON

wParam = (WPARAM) (HICON) hicon;    /* handle of icon         */

lParam = 0;                         /* not used, must be zero */

An application sends the STM_SETICON message to associate an icon with an icon control.

Parameters

hicon

Value of wParam. Identifies the icon to associate with the icon control.

Return Value

The return value is the handle of the icon previously associated with the icon control, or zero if an error occurs.

See Also

»LoadIcon«, »STM_GETICON«


  WIM_CLOSE

This message is sent to a waveform input callback function when a waveform input device is closed. The device handle is no longer valid once this message has been sent.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_WIM_CLOSE«


  WIM_DATA

This message is sent to a waveform input callback function when waveform data is present in the input buffer and the buffer is being returned to the application. The message can be sent either when the buffer is full, or after the waveInReset function is called.

Parameters

DWORD dwParam1

Points to a WAVEHDR structure identifying the buffer containing the waveform data. The WAVEHDR structure has the following form:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Currently unused.

Return Value

None.

Comments

The returned buffer may not be full. Use the dwBytesRecorded member of the WAVEHDR structure specified by dwParam1 to determine the number of bytes recorded into the returned buffer.

See Also

»MM_WIM_DATA«


  WIM_OPEN

This message is sent to a waveform input callback function when a waveform input device is opened.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_WIM_OPEN«


  WM_ACTIVATE

WM_ACTIVATE

fActive = LOWORD(wParam);           /* activation flag */

fMinimized = (BOOL) HIWORD(wParam); /* minimized flag  */

hwnd = (HWND) lParam;               /* window handle   */

The WM_ACTIVATE message is sent when a window is being activated or deactivated. This message is sent first to the window procedure of the top-level window being deactivated and then to the window procedure of the top-level window being activated.

Parameters

fActive

Value of the low-order word of wParam. Specifies whether the window is being activated or deactivated. This parameter can be one of the following values:

Value	Meaning
WA_ACTIVE	Activated by some method other than a mouse click (for example, by a call to the SetActiveWindow function or by use of the keyboard interface to select the window).
WA_CLICKACTIVE	Activated by a mouse click.
WA_INACTIVE	Deactivated.
fMinimized

Value of the high-order word of wParam. Specifies the minimized state of the window being activated or deactivated. A nonzero value indicates the window is minimized.

hwnd

Value of lParam. Identifies the window being activated or deactivated, depending on the value of the fActive parameter. If the value of fActive is WA_INACTIVE, hwnd is the handle of the window being activated. If the value of fActive is WA_ACTIVE or WA_CLICKACTIVE, hwnd is the handle of the window being deactivated. This handle can be NULL.

Return Value

If an application processes this message, it should return zero.

Default Action

If the window is being activated and is not minimized, the DefWindowProc function sets the keyboard focus to the window.

Comments

If the window is activated by a mouse click, it also receives a WM_MOUSEACTIVATE message.

See Also

»WM_MOUSEACTIVATE«, »WM_NCACTIVATE«


  WM_ACTIVATEAPP

WM_ACTIVATEAPP

fActive = (BOOL) wParam;        /* activation flag   */

dwThreadID = (DWORD) lParam:    /* thread identifier */

The WM_ACTIVATEAPP message is sent when a window belonging to a different application than the active window is about to be activated. The message is sent to the application whose window is being activated and to the application whose window is being deactivated.

Parameters

fActive

Value of wParam. Specifies whether the window is being activated or deactivated. This parameter is TRUE if the window is being activated; it is FALSE if the window is being deactivated.

dwThreadID

Value of lParam. Specifies a thread identifier. If the fActive parameter is TRUE, dwThreadID is the identifier of the thread that owns the window being deactivated. If fActive is FALSE, dwThreadID is the identifier of the thread that owns the window being activated.

Return Value

If an application processes this message, it should return zero.

See Also

»WM_ACTIVATE«


  WM_ASKCBFORMATNAME

WM_ASKCBFORMATNAME

cchName = (DWORD) wParam            /* size of buffer                */

lpszFormatName = (LPTSTR) lParam    /* buffer to receive format name */

The WM_ASKCBFORMATNAME message is sent to the clipboard owner by a clipboard viewer window to request the name of a CF_OWNERDISPLAY clipboard format.

Parameters

cchName

Value of wParam. Specifies the size, in characters, of the buffer pointed to by the lpszFormatName parameter.

lpszFormatName

Value of lParam. Points to the buffer that is to receive the clipboard format name.

Return Value

If an application processes this message, it should return zero.

Comments

In response to this message, the clipboard owner should copy the name of the owner-display format to the specified buffer, not exceeding the buffer size specified by the cchName parameter.

A clipboard viewer window sends this message to the clipboard owner to determine the name of the CF_OWNERDISPLAY format — for example, to initialize a menu listing available formats.


  WM_CANCELMODE

WM_CANCELMODE

The WM_CANCELMODE message is sent to the focus window when a dialog box or message box is displayed, enabling the focus window to cancel modes such as mouse capture.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function cancels internal processing of standard scroll bar input, cancels internal menu processing, and releases the mouse capture.

See Also

»DefWindowProc«, »ReleaseCapture«


  WM_CHANGECBCHAIN

WM_CHANGECBCHAIN

hwndRemove = (HWND) wParam;     /* handle of window being removed */

hwndNext = (HWND) lParam;       /* handle of next window in chain */

The WM_CHANGECBCHAIN message is sent to the first window in the clipboard viewer chain when a window is being removed from the chain.

Parameters

hwndRemove

Value of wParam. Identifies the window being removed from the clipboard viewer chain.

hwndNext

Value of lParam. Identifies the next window in the chain following the window being removed. This parameter is NULL if the window being removed is the last window in the chain.

Return Value

If an application processes this message, it should return zero.

Comments

Each clipboard viewer window saves the handle of the next window in the clipboard viewer chain. Initially, this handle is the return value of the SetClipboardViewer function.

When a clipboard viewer window receives the WM_CHANGECBCHAIN message, it should call the SendMessage function to pass the message to the next window in the chain, unless the next window is the window being removed. In this case, the clipboard viewer should save the handle specified by hwndNext as the next window in the chain.

See Also

»SendMessage«, »SetClipboardViewer«


  WM_CHAR

WM_CHAR

chCharCode = (TCHAR) wParam;    /* character code */

lKeyData = lParam;              /* key data       */

The WM_CHAR message is posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR contains the character code of the key that was pressed.

Parameters

chCharCode

Value of wParam. Specifies the character code of the key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is held down while the key is pressed; otherwise, the value is 0.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31	Specifies the transition state. The value is 1 if the key is being released, or it is 0 if the key is being pressed.
Return Value

An application should return zero if it processes this message.

Comments

Because there is not necessarily a one-to-one correspondence between keys pressed and character messages generated, the information in the high-order word of the lKeyData parameter is generally not useful to applications. The information in the high-order word applies only to the most recent WM_KEYDOWN message that precedes the posting of the WM_CHAR message.

For enhanced 101- and 102-key keyboards, extended keys are the right ALT and the right CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Some other keyboards may support the extended-key bit in the lKeyData parameter.

See Also

»TranslateMessage«, »WM_KEYDOWN«


  WM_CHARTOITEM

WM_CHARTOITEM

nKey = LOWORD(wParam);          /* key value          */

nCaretPos = HIWORD(wParam);     /* caret position     */

hwndListBox = (HWND) lParam;    /* handle of list box */

The WM_CHARTOITEM message is sent by a list box with the LBS_WANTKEYBOARDINPUT style to its owner in response to a WM_CHAR message.

Parameters

nKey

Value of the low-order word of wParam. Specifies the value of the key the user pressed.

nCaretPos

Value of the high-order word of wParam. Specifies the current position of the caret.

hwndListBox

Value of lParam. Identifies the list box.

Return Value

The return value specifies the action that the application performed in response to the message. A return value of −1 or −2 indicates that the application handled all aspects of selecting the item and requires no further action by the list box. A return value of 0 or greater specifies the zero-based index of an item in the list box and indicates that the list box should perform the default action for the keystroke on the given item.

Default Action

The DefWindowProc function returns −1.

Comments

Only owner-drawn list boxes that do not have the LBS_HASSTRINGS style can receive this message.

See Also

»DefWindowProc«, »WM_CHAR«, »WM_VKEYTOITEM«


  WM_CHILDACTIVATE

WM_CHILDACTIVATE

The WM_CHILDACTIVATE message is sent to a multiple document interface (MDI) child window when the user clicks the window's title bar or when the window is activated, moved, or sized.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

See Also

»MoveWindow«, »SetWindowPos«


  WM_CHOOSEFONT_GETLOGFONT

WM_CHOOSEFONT_GETLOGFONT

wParam = 0;                /* not used, must be zero            */

lParam = (LPLOGFONT) lplf; /* address of struct. with font data */

An application sends a WM_CHOOSEFONT_GETLOGFONT message to the Font dialog box created by the ChooseFont function to retrieve the current LOGFONT structure.

Parameters

lplf

Points to a LOGFONT structure that receives information about the current logical font. The LOGFONT structure has the following form:

typedef struct tagLOGFONT { /* lf */

   LONG lfHeight;

   LONG lfWidth;

   LONG lfEscapement;

   LONG lfOrientation;

   LONG lfWeight;

   BYTE lfItalic;

   BYTE lfUnderline;

   BYTE lfStrikeOut;

   BYTE lfCharSet;

   BYTE lfOutPrecision;

   BYTE lfClipPrecision;

   BYTE lfQuality;

   BYTE lfPitchAndFamily;

   CHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

Return Value

This message does not return a value.

Comments

An application uses this message to retrieve the LOGFONT structure while the Font dialog box is open. When the user closes the dialog box, the ChooseFont function receives information about the LOGFONT structure.

See Also

»ChooseFont«, »WM_GETFONT«, »LOGFONT«


  WM_CLEAR

WM_CLEAR

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a WM_CLEAR message to an edit control or combo box to delete (clear) the current selection, if any, from the edit control.

Parameters

This message has no parameters.

Return Value

This message does not return a value.

Comments

The deletion performed by the WM_CLEAR message can be undone by sending the edit control an EM_UNDO message.

To delete the current selection and place the deleted contents into the Clipboard, use the WM_CUT message.

When sent to a combo box, the WM_CLEAR message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

See Also

»EM_UNDO«, »WM_COPY«, »WM_CUT«, »WM_PASTE«


  WM_CLOSE

WM_CLOSE

The WM_CLOSE message is sent as a signal that a window or an application should terminate.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function calls the DestroyWindow function to destroy the window.

Comments

An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE message and calling the DestroyWindow function only if the user confirms the choice.

See Also

»DefWindowProc«, »DestroyWindow«


  WM_COMMAND

WM_COMMAND

wNotifyCode = HIWORD(wParam); /* notification code                        */

wID = LOWORD(wParam);         /* item, control, or accelerator identifier */

hwndCtl = (HWND) lParam;      /* handle of control                        */

The WM_COMMAND message is sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, or when an accelerator keystroke is translated.

Parameters

wNotifyCode

Value of the high-order word of wParam. Specifies the notification code if the message is from a control. If the message is from an accelerator, this parameter is 1. If the message is from a menu, this parameter is 0.

wID

Value of the low-order word of wParam. Specifies the identifier of the menu item, control, or accelerator.

hwndCtl

Value of lParam. Identifies the control sending the message if the message is from a control. Otherwise, this parameter is NULL.

Return Value

If an application processes this message, it should return zero.

Comments

Accelerator keystrokes that select items from the System menu are translated into WM_SYSCOMMAND messages.

If an accelerator keystroke occurs that corresponds to a menu item when the window that owns the menu is minimized, no WM_COMMAND message is sent. However, if an accelerator keystroke occurs that does not match any of the items in the window's menu or in the System menu, a WM_COMMAND message is sent, even if the window is minimized.

See Also

»WM_SYSCOMMAND«


  WM_COMPACTING

WM_COMPACTING

wCompactRatio = wParam; /* compacting ratio */

The WM_COMPACTING message is sent to all top-level windows when Windows detects more than 12.5 percent of system time over a 30- to 60-second interval is being spent compacting memory. This indicates that system memory is low.

Parameters

wCompactRatio

Value of wParam. Specifies the ratio of central processing unit (CPU) time currently spent by Windows compacting memory to CPU time currently spent by Windows performing other operations. For example, 0x8000 represents 50 percent of CPU time spent compacting memory.

Return Value

If an application processes this message, it should return zero.

Comments

When an application receives this message, it should free as much memory as possible, taking into account the current level of activity of the application and the total number of applications running with Windows.


  WM_COMPAREITEM

WM_COMPAREITEM

idCtl = wParam;                       /* control identifier   */

lpcis = (LPCOMPAREITEMSTRUCT) lParam; /* structure with items */

Windows sends the WM_COMPAREITEM message to determine the relative position of a new item in the sorted list of an owner-drawn combo box or list box. Whenever the application adds a new item, Windows sends this message to the owner of a combo box or list box created with the CBS_SORT or LBS_SORT style.

Parameters

idCtl

Value of wParam. Specifies the identifier of the control that sent the WM_COMPAREITEM message.

lpcis

Value of lParam. Points to a COMPAREITEMSTRUCT structure that contains the identifiers and application-supplied data for two items in the combo or list box. The COMPAREITEMSTRUCT structure has the following form:

typedef struct tagCOMPAREITEMSTRUCT { /* cis */

    UINT  CtlType;

    UINT  CtlID;

    HWND  hwndItem;

    UINT  itemID1;

    DWORD itemData1;

    UINT  itemID2;

    DWORD itemData2;

} COMPAREITEMSTRUCT;

Return Value

The return value indicates the relative position of the two items. It may be any of the following:

Value	Meaning
−1	Item 1 precedes item 2 in the sorted order.
0	Items 1 and 2 are equivalent in the sorted order.
1	Item 1 follows item 2 in the sorted order.
Comments

When the owner of an owner-drawn combo box or list box receives this message, the owner returns a value indicating which of the items specified by the COMPAREITEMSTRUCT structure will appear before the other. Typically, Windows sends this message several times until it determines the exact position for the new item.

See Also

»COMPAREITEMSTRUCT«


  WM_COPY

WM_COPY

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the WM_COPY message to an edit control or combo box to copy the current selection to the Clipboard in CF_TEXT format.

Parameters

This message has no parameters.

Return Value

This message does not return a value.

Comments

When sent to a combo box, the WM_COPY message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

See Also

»WM_CLEAR«, »WM_CUT«, »WM_PASTE«


  WM_COPYDATA

WM_COPYDATA

wParam = (WPARAM) (HWND) hwndFrom;       /* handle of sending window */

lParam = (LPARAM) (PCOPYDATASTRUCT) cds; /* structure with data      */

The WM_COPYDATA message is sent when an application passes data to another application.

Parameters

hwndData

Identifies the window passing the data.

cds

Points to a COPYDATASTRUCT structure that contains the data to be passed. The COPYDATASTRUCT has the following form:

typedef struct tagCOPYDATASTRUCT {  /* cds */

    DWORD dwData;

    DWORD cbData;

    PVOID lpData;

} COPYDATASTRUCT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If the receiving application processes this message, it should return TRUE; otherwise, it should return FALSE.

Comments

An application must use the SendMessage function to send this message, not the PostMessage function.

The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data.

While this message is being sent, the referenced data must not be changed by another thread of the sending process.

The receiving application should consider the data read-only. The cds parameter is valid only during the processing of the message. The receiving application should not free the memory referenced by the cds parameter. If the receiving application must access the data after SendMessage returns, it must copy the data into a local buffer.

See Also

»PostMessage«, »SendMessage«, »COPYDATASTRUCT«


  WM_CPL_LAUNCH

WM_CPL_LAUNCH

hwnd = (HWND) wParam;          /* handle of sending window */

lpszAppName = (LPSTR) lParam;  /* application-name string  */

An application sends the WM_CPL_LAUNCH message to Windows Control Panel to request that a Control Panel application be started.

Parameters

hwnd

Value of wParam. Specifies the handle of the window sending the message. The WM_CPL_LAUNCHED message is sent to this window.

lpszAppName

Value of lParam. Specifies a far pointer to a string containing the name of the Control Panel application to open.

Return Value

If the application starts, the return value is TRUE; otherwise, it is FALSE.

See Also

»WM_CPL_LAUNCHED«


  WM_CPL_LAUNCHED

WM_CPL_LAUNCHED

fAppStarted = (BOOL) wParam;

The WM_CPL_LAUNCHED message is sent when a Windows Control Panel application, started by the WM_CPL_LAUNCH message, has closed. The WM_CPL_LAUNCHED message is sent to the window identified by the wParam parameter of the WM_CPL_LAUNCH message that started the application.

Parameters

fAppStarted

Value of wParam. Specifies whether the application was started. If the application was started, this parameter is TRUE; otherwise, it is FALSE.

Return Value

The value returned by the application is ignored for this message.

See Also

»WM_CPL_LAUNCH«


  WM_CREATE

WM_CREATE

lpcs = (LPCREATESTRUCT) lParam; /* structure with creation data */

The WM_CREATE message is sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. The window procedure of the new window receives this message after the window is created, but before the window becomes visible. The message is sent before the CreateWindowEx or CreateWindow function returns.

Parameters

lParam

Value of lParam. Points to a CREATESTRUCT structure that contains information about the window being created. The members of the CREATESTRUCT structure are identical to the parameters of the CreateWindowEx function. The CREATESTRUCT structure has the following form:

typedef struct tagCREATESTRUCT { /* cs */

    LPVOID lpCreateParams;

    HANDLE hInstance;

    HMENU  hMenu;

    HWND   hwndParent;

    int    cy;

    int    cx;

    int    y;

    int    x;

    LONG   style;

    LPCSTR lpszName;

    LPCSTR lpszClass;

    DWORD  dwExStyle;

} CREATESTRUCT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return 0 to continue creation of the window. If the application returns −1, the window is destroyed and the CreateWindowEx or CreateWindow function returns a NULL handle.

See Also

»CreateWindow«, »CreateWindowEx«, »CREATESTRUCT«, »WM_NCCREATE«


  WM_CTLCOLORBTN

WM_CTLCOLORBTN

hdcButton = (HDC) wParam;   /* handle of button display context */

hwndButton = (HWND) lParam; /* handle of button                 */

The WM_CTLCOLORBTN message is sent to the parent window of a button when the button is about to be drawn. By responding to this message, the parent window can set a button's text and background colors.

Parameters

hdcButton

Value of wParam. Identifies the display context for the button.

hwndButton

Value of lParam. Identifies the button.

Return Value

If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the button.

Default Action

The DefWindowProc function selects the default system colors for the button.

Comments

The WM_CTLCOLORBTN message is never sent between threads. It is sent only within one thread.

The text color of a check box or radio button applies to the box or button, its check mark, and the text. The focus rectangle for these buttons remains the system default color (typically black). The text color of a group box applies to the text but not to the line that defines the box. The text color of a push button applies only to its focus rectangle; it does not affect the color of the text.

See Also

»DefWindowProc«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  WM_CTLCOLORDLG

WM_CTLCOLORDLG

hdcDlg = (HDC) wParam;   /* handle of dialog box display context */

hwndDlg = (HWND) lParam; /* handle of dialog box                 */

The WM_CTLCOLORDLG message is sent to a dialog box before Windows draws the dialog box. By responding to this message, the dialog box can set its text and background colors by using the given display device context handle.

Parameters

hdcDlg

Value of wParam. Identifies the device context for the dialog box.

hwndDlg

Value of lParam. Identifies the dialog box.

Return Value

If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the dialog box.

Default Action

The DefWindowProc function selects the default system colors for the dialog box.

Comments

The WM_CTLCOLORDLG message is never sent between threads. It is sent only within one thread.

Note that the WM_CTLCOLORDLG message is sent to the dialog itself; all of the other WM_CTLCOLOR* messages are sent to the owner of the control.

See Also

»DefWindowProc«, »WM_CTLCOLORBTN«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  WM_CTLCOLOREDIT

WM_CTLCOLOREDIT

hdcEdit = (HDC) wParam;   /* handle of display context */

hwndEdit = (HWND) lParam; /* handle of static control  */

The WM_CTLCOLOREDIT message is sent to the parent window of an edit control when the control is about to be drawn. By responding to this message, the parent window can use the given device context handle to set the text and background colors of the edit control.

Parameters

hdcEdit

Value of wParam. Identifies the device context for the edit control window.

hwndEdit

Value of lParam. Identifies the edit control.

Return Value

If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the edit control.

Default Action

The DefWindowProc function selects the default system colors for the edit control.

Comments

The WM_CTLCOLOREDIT message is never sent between threads, it is only sent within the same thread.

See Also

»DefWindowProc«, »WM_CTLCOLORBTN«, »WM_CTLCOLORDLG«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  WM_CTLCOLORLISTBOX

WM_CTLCOLORLISTBOX

hdcLB = (HDC) wParam;   /* handle of list box display context */

hwndLB = (HWND) lParam; /* handle of list box                 */

The WM_CTLCOLORLISTBOX message is sent to the parent window of a list box before Windows draws the list box. By responding to this message, the parent window can set the text and background colors of the list box by using the given display device context handle.

Parameters

hdcLB

Value of wParam. Identifies the device context for the list box.

hwndLB

Value of lParam. Identifies the list box.

Return Value

If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the list box.

Default Action

The DefWindowProc function selects the default system colors for the list box.

Comments

The WM_CTLCOLORLISTBOX message is never sent between threads. It is sent only within one thread.

See Also

»DefWindowProc«, »WM_CTLCOLORBTN«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  WM_CTLCOLORMSGBOX

WM_CTLCOLORMSGBOX

hdcMB = (HDC) wParam;   /* handle of message box display context */

hwndMB = (HWND) lParam; /* handle of message box                 */

The WM_CTLCOLORMSGBOX message is sent to the owner window of a message box before Windows draws the message box. By responding to this message, the owner window can set the text and background colors of the message box by using the given display device context handle.

Parameters

hdcMB

Value of wParam. Identifies the device context for the message box.

hwndMB

Value of lParam. Identifies the message box.

Return Value

If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the message box.

Default Action

The DefWindowProc function selects the default system colors for the message box.

Comments

The WM_CTLCOLORMSGBOX message is never sent between threads. It is sent only within one thread.

See Also

»DefWindowProc«, »WM_CTLCOLORBTN«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORSCROLLBAR«, »WM_CTLCOLORSTATIC«


  WM_CTLCOLORSCROLLBAR

WM_CTLCOLORSCROLLBAR

hdcSB  = (HDC) wParam;   /* handle of scroll bar display context */

hwndSB = (HWND) lParam;  /* handle of scroll bar                 */

The WM_CTLCOLORSCROLLBAR message is sent to the parent window of a scroll bar control when the control is about to be drawn. By responding to this message, the parent window can use the given display context handle to set the background color of the scroll bar control.

Parameters

hdcSB

Value of wParam. Identifies the display context for the scroll bar control.

hwndSB

Value of lParam. Identifies the scroll bar.

Return Value

If an application processes this message, it must return the handle of a brush. Windows uses the brush to paint the background of the scroll bar control.

Default Action

The DefWindowProc function selects the default system colors for the scroll bar control.

Comments

The WM_CTLCOLORSCROLLBAR message is never sent between threads; it is only sent within the same thread.

See Also

»DefWindowProc«, »WM_CTLCOLORBTN«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSTATIC«


  WM_CTLCOLORSTATIC

WM_CTLCOLORSTATIC

hdcStatic = (HDC) wParam;   /* handle of display context */

hwndStatic = (HWND) lParam; /* handle of static control  */

The WM_CTLCOLORSTATIC message is sent to the parent window of a static control when the control is about to be drawn. By responding to this message, the parent window can use the given device context (DC) handle to set the text and background colors of the static control.

Parameters

hdcStatic

Value of wParam. Identifies the DC for the static control window.

hwndStatic

Value of lParam. Identifies the static control.

Return Value

If an application processes this message, the return value is the handle of a brush that Windows uses to paint the background of the static control.

Default Action

The DefWindowProc function selects the default system colors for the static control.

Comments

The WM_CTLCOLORSCROLLBAR message is never sent between threads; it is sent only within the same thread.

See Also

»DefWindowProc«, »WM_CTLCOLORBTN«, »WM_CTLCOLORDLG«, »WM_CTLCOLOREDIT«, »WM_CTLCOLORLISTBOX«, »WM_CTLCOLORMSGBOX«, »WM_CTLCOLORSCROLLBAR«


  WM_CUT

WM_CUT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a WM_CUT message to an edit control or combo box to delete (cut) the current selection, if any, in the edit control and copy the deleted text to the Clipboard in CF_TEXT format.

Parameters

This message has no parameters.

Return Value

This message does not return a value.

Comments

The deletion performed by the WM_CUT message can be undone by sending the edit control an EM_UNDO message.

To delete the current selection without placing the deleted text onto the Clipboard, use the WM_CLEAR message.

When sent to a combo box, the WM_CUT message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

See Also

»WM_CLEAR«, »WM_COPY«, »WM_PASTE«


  WM_DDE_ACK

WM_DDE_ACK

/* Response to WM_DDE_INITIATE 	*/

wParam = (WPARAM) hwnd;	/* handle of posting application 	*/

lParam = MAKELPARAM(aApp, aTopic)	/* application and topic atoms 	*/

/* Response to WM_DDE_EXECUTE 	*/

wParam = (WPARAM) hwnd;	/* handle of posting application 	*/

lParam = (LPARAM) lPackedVal;	/* packed status flags and data handle	*/

/* Response to all other messages 	*/

wParam = (WPARAM) hwnd;	/* handle of posting application 	*/

lParam = (LPARAM) lPackedVal;	/* packed status flags and item 	*/

The WM_DDE_ACK message notifies a dynamic data exchange (DDE) application of the receipt and processing of a WM_DDE_INITIATE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_POKE message, and in some cases, of a WM_DDE_REQUEST message.

Parameters

When responding to WM_DDE_INITIATE:

hwnd

Value of wParam. Identifies the server window posting the message.

aApp

Value of the low-order word of lParam. Contains an atom that identifies the replying application.

aTopic

Value of the high-order word of lParam. Contains an atom that identifies the topic for which a conversation is being established.

When responding to WM_DDE_EXECUTE:

hwnd

Value of wParam. Identifies the server window posting the message.

lPackedVal

Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The Low component is wStatus. The  High component is the same hCommands that was received in the WM_DDE_EXECUTE message.

Parameter	Description
wStatus	Specifies a DDEACK structure containing a series of flags that indicate the status of the response. The DDEACK structure has the following form:
typedef struct { /* ddeack */

    unsigned short bAppReturnCode:8,

    reserved:6,

    fBusy:1,

    fAck:1;

} DDEACK;

	For a full description of this structure, see Chapter 3, "Structures"
hCommands	Identifies a global memory object containing the command string.
When replying to all other messages:

hwnd

Value of wParam. Identifies the client or server window posting the message.

lPackedVal

Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The Low component is wStatus. The  High component is aItem.

Parameter	Description
wStatus	Specifies a DDEACK structure containing a series of flags that indicate the status of the response. The DDEACK structure has the following form:
typedef struct { /* ddeack */

    unsigned short bAppReturnCode:8,

    reserved:6,

    fBusy:1,

    fAck:1;

} DDEACK;

	For a full description of this structure, see Chapter 3, "Structures"
aItem	Contains a global atom that identifies the name of the data item for which the response is sent.
Comments

Posting

Except in response to the WM_DDE_INITIATE message, the application posts the WM_DDE_ACK message by calling the PostMessage function, not the SendMessage function. When responding to WM_DDE_INITIATE, the application sends the WM_DDE_ACK message by calling SendMessage. In this case, neither the application-name atom nor the topic-name atom should be NULL (even if the WM_DDE_INITIATE message specified NULL atoms.

When acknowledging any message with an accompanying aItem atom, the application posting WM_DDE_ACK can either reuse the aItem atom that accompanied the original message, or it can delete it and create a new one.

When acknowledging WM_DDE_EXECUTE, the application that posts WM_DDE_ACK should reuse the hCommands object that accompanied the original WM_DDE_EXECUTE message.

All posted WM_DDE_ACK messages must create or reuse the lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function.

If an application has initiated the termination of a conversation by posting WM_DDE_TERMINATE and is awaiting confirmation, the waiting application should not acknowledge (positively or negatively) any subsequent messages sent by the other application. The waiting application should delete any atoms or shared memory objects received in these intervening messages. Memory objects should not be freed if the fRelease flag is set to FALSE in WM_DDE_POKE, and WM_DDE_DATA messages.

Receiving

The application that receives a WM_DDE_ACK message should delete all atoms accompanying the message. If the application receives a WM_DDE_ACK in response to a message with an accompanying hData object, and the object was sent with the fRelease flags set to FALSE, the application is responsible for deleteing the hData object.

If the application receives a negative WM_DDE_ACK message posted in reply to a WM_DDE_ADVISE message, the application should delete the hOptions object posted with the original WM_DDE_ADVISE message. If the application receives a negative WM_DDE_ACK message posted in reply to a WM_DDE_DATA, WM_DDE_POKE, or WM_DDE_EXECUTE message, the application should delete the hCommands object posted with the original WM_DDE_DATA, WM_DDE_POKE, or WM_DDE_EXECUTE message.

The application that receives a posted WM_DDE_ACK message must free the lPackedVal parameter by using the FreeDDElParam function.

See Also

»FreeDDElParam«, »PackDDElParam«, »PostMessage«, »ReuseDDElParam«, »UnpackDDElParam«, »WM_DDE_ADVISE«, »WM_DDE_DATA«, »WM_DDE_EXECUTE«, »WM_DDE_INITIATE«, »WM_DDE_POKE«, »WM_DDE_REQUEST«, »WM_DDE_TERMINATE«, »WM_DDE_UNADVISE«


  WM_DDE_ADVISE

WM_DDE_ADVISE

wParam = (WPARAM) hwnd;        /* handle of posting application  */

lParam = (LPARAM) lPackedVal;  /* packed DDEADVISE and item atom */

A dynamic data exchange (DDE) client application posts the WM_DDE_ADVISE message to a DDE server application to request the server to supply an update for a data item whenever the item changes.

Parameters

hwnd

Value of wParam. Identifies the client window posting the message.

lPackedVal

Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The Low component is hOptions. The  High component is aItem.

Parameter	Description
hOptions	Identifies a global memory object containing a DDEADVISE structure that specifies how the data is to be sent. The DDEADVISE structure has the following form:
typedef struct { /* ddeadv */

    unsigned short reserved:14,

        fDeferUpd:1,

        fAckReq:1;

    short cfFormat;

} DDEADVISE;

	For a full description of this structure, see Chapter 3, "Structures"
aItem	Contains an atom that identifies the data item requested.
Comments

If a client application supports more than one clipboard format for a single topic and item, it can post multiple WM_DDE_ADVISE messages for the topic and item, specifying a different clipboard format with each message. Note that a server can support multiple formats only for hot links, not warm links.

Posting

The client application posts the WM_DDE_ADVISE message by calling the PostMessage function, not the SendMessage function.

The client application allocates hOptions by calling the GlobalAlloc function with the GMEM_DDESHARE option. It allocates aItem by calling the GlobalAddAtom function.

The client application must create or reuse the WM_DDE_ADVISE lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with hOptions supplied as the Low component and aItem supplied as the High component.

If the receiving (server) application responds with a negative WM_DDE_ACK message, the posting (client) application must delete the hOptions object.

The fRelease flag is not used in WM_DDE_ADVISE messages, but their data freeing behavior is similar to that of WM_DDE_DATA and WM_DDE_POKE messages where fRelease is TRUE.

Receiving

The server application posts the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the application can reuse the aItem atom or delete it and create a new one. If the WM_DDE_ACK message is positive, the application should delete the hOptions object; otherwise, the application should not delete the object.

The server must create or reuse the WM_DDE_ACK lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with wStatus supplied as the Low component and aItem supplied as the High component.

See Also

»FreeDDElParam«, »GlobalAddAtom«, »GlobalAlloc«, »PackDDElParam«, »PostMessage«, »ReuseDDElParam«, »SendMessage«, »UnpackDDElParam«, »WM_DDE_DATA«, »WM_DDE_REQUEST«


  WM_DDE_DATA

WM_DDE_DATA

wParam = (WPARAM) hwnd;         /* handle of posting application */

lParam = (LPARAM) lPackedVal;   /* packed DDEDATA and item atom  */

A dynamic data exchange (DDE) server application posts a WM_DDE_DATA message to a DDE client application to pass a data item to the client or to notify the client of the availability of a data item.

Parameters

hwnd

Value of wParam. Identifies the server window posting the message.

lPackedVal

Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The Low component is hData or NULL. The  High component is aItem.

Parameter	Meaning
hData	Identifies a global memory object containing a DDEDATA structure with the data and additional information. The handle should be set to NULL if the server is notifying the client that the data-item value has changed during a warm link. A warm link is established by the client sending a WM_DDE_ADVISE message with the fDeferUpd bit set. The DDEDATA structure has the following form:
typedef struct { /* ddedat */

    unsigned short unused:12,

        fResponse:1,

        fRelease:1,

        reserved:1,

        fAckReq:1;

    short cfFormat;

    BYTE  Value[1];

} DDEDATA;

	For a full description of this structure, see Chapter 3, "Structures"
aItem	Contains an atom that identifies the data item for which the data or notification is sent.
Comments

Posting

The server application posts the WM_DDE_DATA message by calling the PostMessage function, not the SendMessage function.

The server application allocates hData by calling the GlobalAlloc function with the GMEM_DDESHARE option. It allocates aItem by calling the GlobalAddAtom function.

The server must create or reuse the WM_DDE_DATA lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with hData supplied as the Low component and aItem supplied as the High component.

If the receiving (client) application responds with a negative WM_DDE_ACK message, the posting (server) application must delete the hData object; otherwise, the client must delete the hData object after extracting its contents by calling the UnpackDDElParam function.

If the server application sets the fRelease member of the DDEDATA structure to FALSE, the server is responsible for deleting hData upon receiving either a positive or negative acknowledgement.

The server application should not set both the fAckReq and fRelease members of the DDEDATA structure to FALSE. If both members are set to FALSE, it is impossible for the server to determine when to delete hData.

Receiving

If fAckReq is TRUE, the client application should post the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the client can either reuse the aItem atom, or it can delete it and create a new one.

The client must create or reuse the WM_DDE_ACK lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with wStatus supplied as the Low component and aItem supplied as the High component.

If fAckReq is FALSE, the client application should delete the aItem atom.

If the posting (server) application specified hData as NULL, the receiving (client) application can request the server to send the actual data by posting a WM_DDE_REQUEST message.

After processing a WM_DDE_DATA message in which hData is not NULL, the client should free hData by calling the FreeDDElParam function, unless one of the following conditions is true:

•	The fRelease member is FALSE.

•	The fRelease member is TRUE, but the client application responds with a negative WM_DDE_ACK message.

See Also

»FreeDDElParam«, »GlobalAddAtom«, »GlobalAlloc«, »PostMessage«, »ReuseDDElParam«, »SendMessage«, »WM_DDE_ACK«, »WM_DDE_ADVISE«, »WM_DDE_POKE«, »WM_DDE_REQUEST«


  WM_DDE_EXECUTE

WM_DDE_EXECUTE

wParam = (WPARAM) hwnd;        /* handle of posting application	*/

lParam = (LPARAM) hCommands;   /* handle to global object 	*/

A dynamic data exchange (DDE) client application posts a WM_DDE_EXECUTE message to a DDE server application to send a string to the server to be processed as a series of commands. The server application is expected to post a WM_DDE_ACK message in response.

Parameters

hwnd

Value of wParam. Identifies the client window posting the message.

hCommands

Value of lParam. Contains a global memory object which references an ANSI or UNICODE command string depending on the types of windows involved in the conversation.

Comments

The command string is a null-terminated string consisting of one or more opcode strings enclosed in single brackets ([ ]).

Each opcode string has the following syntax, where the parameters list is optional:

          opcode parameters

The opcode is any application-defined single token. It cannot include spaces, commas, parentheses, brackets, or quotation marks.

The parameters list can contain any application-defined value or values. Multiple parameters are separated by commas, and the entire parameter list is enclosed in parentheses. Parameters cannot include commas or parentheses except inside a quoted string. If a bracket or parenthesis character is to appear in a quoted string, it need not be doubled, as was the case under the old rules.

Following are some valid command strings:

[connect][download(query1,results.txt)][disconnect]

[query("sales per employee for each district")]

[open("sample.xlm")][run("r1c1")]

[quote_case("This is a "" character")]

[bracket_or_paren_case("()s or []s should be no problem.")]

Note that, under old rules, parentheses and brackets had to be doubled, as follows:

[bracket_or_paren_case("(())s or [[]]s should be no problem.")]

Servers should be able to parse commands in either form.

UNICODE execute strings should always and only be used when both the client and server window handles cause the IsWindowUnicode function to return TRUE.

Posting

The client application posts the WM_DDE_EXECUTE message by calling the PostMessage function, not the SendMessage function.

The client application allocates hCommands by calling the GlobalAlloc function with the GMEM_DDESHARE option.

When processing the WM_DDE_ACK message that the server posts in reply to a WM_DDE_EXECUTE message, the client application must delete the hCommands object sent back in the WM_DDE_ACK message.

Receiving

The server application posts the WM_DDE_ACK message to respond positively or negatively. The server should reuse the hCommands object.

Unless specified otherwise by a sub-protocol, the server should not post the WM_DDE_ACK message until all the actions specified by the execute command string are completed. The one exception to this rule is when an execute command string causes the server to terminate the conversation.

See Also

»GlobalAlloc«, »PackDDElParam«, »PostMessage«, »ReuseDDElParam«, »SendMessage«, »UnpackDDElParam«, »WM_DDE_ACK«


  WM_DDE_INITIATE

WM_DDE_INITIATE

wParam = (WPARAM) hwnd;             /* handle of posting appl. */

lParam = MAKELPARAM(aApp, aTopic);  /* appl. and topic atoms   */

A dynamic data exchange (DDE) client application sends a WM_DDE_INITIATE message to initiate a conversation with a server application responding to the specified application and topic names. Upon receiving this message, all server applications with names that match the specified application and that support the specified topic are expected to acknowledge it. (For more information, see the WM_DDE_ACK message.)

Parameters

hwnd

Value of wParam. Identifies the client window sending the message.

aApp

Value of the low-order word of lParam. Contains an atom that identifies the application with which a conversation is requested. The application name cannot contain slashes (/) or backslashes (\). These characters are reserved for network implementations. If aApp is NULL, a conversation with all applications is requested.

aTopic

Value of the high-order word of lParam. Contains an atom that identifies the topic for which a conversation is requested. If the topic is NULL, conversations for all available topics are requested.

Comments

If aApp is NULL, any server application can respond. If aTopic is NULL, any topic is valid. Upon receiving a WM_DDE_INITIATE request with the aTopic parameter set to NULL, a server must send a WM_DDE_ACK message for each of the topics it supports.

Sending

The client application sends the WM_DDE_INITIATE message by calling the SendMessage function, not the PostMessage function. The client broadcasts the message to all top-level windows by setting the first parameter of SendMessage to −1.

If the client application has already obtained the window handle of the desired server, it can send WM_DDE_INITIATE directly to the server window by passing the server's window handle as the first parameter of SendMessage.

The client application allocates aApp and aTopic by calling GlobalAddAtom.

When SendMessage returns, the client application must delete the aApp and aTopic atoms.

Receiving

To complete the initiation of a conversation, the server application must respond with one or more WM_DDE_ACK messages, where each message is for a separate topic. When sending WM_DDE_ACK message, the server should create new aApp and aTopic atoms; it should not reuse the atoms sent with the WM_DDE_INITIATE message.

See Also

»GlobalAddAtom«, »GlobalAlloc«, »PostMessage«, »SendMessage«, »WM_DDE_ACK«


  WM_DDE_POKE

WM_DDE_POKE

wParam = (WPARAM) hwnd;        /* handle of posting application  */

lParam = (LPARAM) lPackedVal;  /* packed DDEPOKE and item atom   */

A dynamic data exchange (DDE) client application posts a WM_DDE_POKE message to a DDE server application. A client uses this message to request the server to accept an unsolicited data item. The server is expected to reply with a WM_DDE_ACK message indicating whether it accepted the data item.

Parameters

hwnd

Value of wParam. Identifies the client window posting the message.

lPackedVal

Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The Low component is hData. The  High component is aItem.

Parameter	Description
hData	Identifies a global memory object containing a DDEPOKE structure with the data and additional information. The DDEPOKE structure has the following form:
typedef struct { /* ddepok */

    unsigned short unused:13,

        fRelease:1,

        fReserved:2;

    short cfFormat;

    BYTE  Value[1];

} DDEPOKE;

	For a full description of this structure, see Chapter 3, "Structures"
aItem	Contains a global atom that identifies the data item for which the data or notification is being sent.
Comments

Posting

The client application posts the WM_DDE_POKE message by using the PostMessage function.

The client application must allocate memory for the hData object by using the GlobalAlloc function with the GMEM_DDESHARE option. The client application must delete the hData object if either of the following conditions is true:

•	The server application responds with a negative WM_DDE_ACK message.

•	The fRelease member is FALSE, but the server application responds with either a positive or negative WM_DDE_ACK.

The client application must create the aItem atom by using the GlobalAddAtom function.

The client application must create or reuse the WM_DDE_POKE lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with hData supplied as the Low component and aItem supplied as the High component.

Receiving

The server application should post the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the server can either reuse the aItem atom, or it can delete it and create a new one.

The server must create or reuse the WM_DDE_ACK lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with wStatus supplied as the Low component and aItem supplied as the High component.

To free the hData object, the server should call the GlobalFree function.

To free the lPackedVal object, the server should call the FreeDDElParam function.

See Also

»FreeDDElParam«, »GlobalAddAtom«, »GlobalAlloc«, »PackDDElParam«, »PostMessage«, »ReuseDDElParam«, »SendMessage«, »UnpackDDElParam«, »WM_DDE_ACK«


  WM_DDE_REQUEST

WM_DDE_REQUEST

wParam = (WPARAM) hwnd;        /* handle of posting application  */

lParam = (LPARAM) lParam;      /* holds cfFormat and aItem       */

A dynamic data exchange (DDE) client application posts a WM_DDE_REQUEST message to a DDE server application to request the value of a data item.

Parameters

hwnd

Value of wParam. Identifies the client window sending the message.

lParam

Holds the cfFormat and aItem parameters.

Parameter	Description
cfFormat	This is the LOWORD of lParam. Specifies a standard or registered clipboard format.
aItem	This is the HIWORD of lParam. Contains an atom that identifies the data item requested from the server.
Comments

Posting

The client application posts the WM_DDE_REQUEST message by calling the PostMessage function, not the SendMessage function.

The client application allocates aItem by calling the GlobalAddAtom function.

Receiving

If the receiving (server) application can satisfy the request, it responds with a WM_DDE_DATA message containing the requested data. Otherwise, it responds with a negative WM_DDE_ACK message.

When responding with either a WM_DDE_DATA or WM_DDE_ACK message, the server application can either reuse the aItem atom or it can delete the atom and create a new one.

See Also

»GlobalAddAtom«, »PackDDElParam«, »PostMessage«, »ReuseDDElParam«, »SendMessage«, »UnpackDDElParam«, »WM_DDE_ACK«, »WM_DDE_DATA«


  WM_DDE_TERMINATE

WM_DDE_TERMINATE

wParam = (WPARAM) hwnd; /* handle of posting window */

lParam = 0;             /* not used, must be zero   */

A dynamic data exchange (DDE) application (client or server) posts a WM_DDE_TERMINATE message to terminate a conversation.

Parameters

hwnd

Value of wParam. Identifies the client or server window posting the message.

Comments

Posting

The client or server application posts the WM_DDE_TERMINATE message by calling the PostMessage function, not the SendMessage function.

While waiting for confirmation of the termination, the posting application should not post any other messages to the receiving application. If the sending application receives messages (other than WM_DDE_TERMINATE) from the receiving application, it should delete any atoms or shared memory objects accompanying the messages, except hData objects associated with WM_DDE_POKE or WM_DDE_DATA messages that do not have the fRelease flag set.

Receiving

The client or server application should respond by posting a WM_DDE_TERMINATE message.

See Also

»PostMessage«, »SendMessage«, »WM_DDE_DATA«, »WM_DDE_POKE«


  WM_DDE_UNADVISE

WM_DDE_UNADVISE

wParam = (WPARAM) hwnd;        /* handle of posting application  */

lParam = (LPARAM) lParam;      /* format and item atom           */

A dynamic data exchange (DDE) client application posts a WM_DDE_UNADVISE message to inform a DDE server application that the specified item or a particular clipboard format for the item should no longer be updated. This terminates the warm or hot link for the specified item.

Parameters

hwnd

Value of wParam. Identifies the client window sending the message.

lParam

Holds the cfFormat and aItem parameters.

Parameter	Description
cfFormat	This is the LOWORD of lParam. Specifies the clipboard format of the item for which the update request is being retracted. If cfFormat is NULL, all active WM_DDE_ADVISE conversations for the item are to be terminated.
aItem	This is the HIWORD of lParam. Contains a global atom that identifies the item for which the update request is being retracted. When aItem is NULL, all active WM_DDE_ADVISE links associated with the conversation are to be terminated.
Comments

Posting

The client application posts the WM_DDE_UNADVISE message by calling the PostMessage function, not the SendMessage function.

The client application allocates aItem by calling the GlobalAddAtom function.

Receiving

The server application posts the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the server can either reuse the  aItem atom or it can delete the atom and create a new one.

See Also

»GlobalAddAtom«, »PackDDElParam«, »PostMessage«, »ReuseDDElParam«, »SendMessage«, »UnpackDDElParam«, »WM_DDE_ACK«, »WM_DDE_ADVISE«


  WM_DEADCHAR

WM_DEADCHAR

chCharCode = (TCHAR) wParam;    /* character code */

lKeyData = lParam;              /* key data       */

The WM_DEADCHAR message is posted to the window with the keyboard focus when a WM_KEYUP message is translated by the TranslateMessage function. WM_DEADCHAR specifies a character code generated by a dead key. A dead key is a key that generates a character, such as the umlaut (double-dot), that is combined with another character to form a composite character. For example, the umlaut-O character (Ö) is generated by typing the dead key for the umlaut character, and then typing the O key.

Parameters

chCharCode

Value of wParam. Specifies the character code generated by the dead key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is held down while the key is pressed; otherwise, the value is 0.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31	Specifies the transition state. The value is 1 if the key is being released, or it is 0 if the key is being pressed.
Return Value

An application should return zero if it processes this message.

Comments

The WM_DEADCHAR message typically is used by applications to give the user feedback about each key pressed. For example, an application can display the accent in the current character position without moving the caret.

Because there is not necessarily a one-to-one correspondence between keys pressed and character messages generated, the information in the high-order word of the lKeyData parameter is generally not useful to applications. The information in the high-order word applies only to the most recent WM_KEYDOWN message that precedes the posting of the WM_DEADCHAR message.

For enhanced 101- and 102-key keyboards, extended keys are the right ALT and the right CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Some other keyboards may support the extended-key bit in the lKeyData parameter.

See Also

»TranslateMessage«, »WM_KEYDOWN«, »WM_SYSDEADCHAR«


  WM_DELETEITEM

WM_DELETEITEM

idCtl = wParam;                      /* control identifier        */

lpdis = (LPDELETEITEMSTRUCT) lParam; /* structure with item info. */

The WM_DELETEITEM message is sent to the owner of an owner-drawn list box or combo box when the list box or combo box is destroyed or when items are removed by the LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT message.

Parameters

idCtl

Value of wParam. Specifies the identifier of the control that sent the WM_DELETEITEM message.

lpdis

Value of lParam. Points to a DELETEITEMSTRUCT structure that contains information about the item deleted from a list box. The DELETEITEMSTRUCT structure has the following form:

typedef struct tagDELETEITEMSTRUCT { /* ditms */

    UINT CtlType;

    UINT CtlID;

    UINT itemID;

    HWND hwndItem;

    UINT itemData;

} DELETEITEMSTRUCT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

An application should return TRUE if it processes this message.

See Also

»CB_DELETESTRING«, »CB_RESETCONTENT«, »LB_DELETESTRING«, »LB_RESETCONTENT«


  WM_DESTROY

WM_DESTROY

The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.

This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

Comments

If the window being destroyed is part of the clipboard viewer chain (set by calling the SetClipboardViewer function), the window must remove itself from the chain by processing the ChangeClipboardChain function before returning from the WM_DESTROY message.

See Also

»ChangeClipboardChain«, »DestroyWindow«, »PostQuitMessage«, »SetClipboardViewer«, »WM_CLOSE«


  WM_DESTROYCLIPBOARD

WM_DESTROYCLIPBOARD

The WM_DESTROYCLIPBOARD message is sent to the clipboard owner when the clipboard is emptied by a call to the EmptyClipboard function.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

See Also

»EmptyClipboard«


  WM_DEVMODECHANGE

WM_DEVMODECHANGE

lpszDev = (LPCTSTR) lParam; /* address of device name */

The WM_DEVMODECHANGE message is sent to all top-level windows whenever the user changes device-mode settings.

Parameters

lpszDev

Value of lParam. Points to the device name specified in the WIN.INI file.

Return Value

An application should return zero if it processes this message.

Comments

Calls to functions that change the WIN.INI file may be mapped to the registry instead. This mapping occurs when WIN.INI and the section being changed are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Description\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

The change in the storage location has no effect on the behavior of this message.

See Also

»WM_WININICHANGE«


  WM_DRAWCLIPBOARD

WM_DRAWCLIPBOARD

The WM_DRAWCLIPBOARD message is sent to the first window in the clipboard viewer chain when the contents of the clipboard change. This enables a clipboard viewer window to display the new contents of the clipboard.

Parameters

This message has no parameters.

Comments

Only clipboard viewer windows receive this message. These are windows that have been added to the clipboard viewer chain by using the SetClipboardViewer function.

Each window that receives the WM_DRAWCLIPBOARD message must call the SendMessage function to pass the message on to the next window in the clipboard viewer chain. The handle of the next window in the chain is returned by the SetClipboardViewer function, and may change in response to a WM_CHANGECBCHAIN message.

See Also

»SendMessage«, »SetClipboardViewer«, »WM_CHANGECBCHAIN«


  WM_DRAWITEM

WM_DRAWITEM

idCtl = (UINT) wParam;             /* control identifier       */

lpdis = (LPDRAWITEMSTRUCT) lParam; /* item-drawing information */

The WM_DRAWITEM message is sent to the owner window of an owner-drawn button, combo box, list box, or menu when a visual aspect of the button, combo box, list box, or menu has changed.

Parameters

idCtl

Value of wParam. Specifies the identifier of the control that sent the WM_DRAWITEM message. If the message was sent by a menu, this parameter is zero.

lpdis

Value of lParam. Points to a DRAWITEMSTRUCT structure containing information about the item to be drawn and the type of drawing required. The DRAWITEMSTRUCT structure has the following form:

typedef struct tagDRAWITEMSTRUCT {  /* dis */

    UINT  CtlType;

    UINT  CtlID;

    UINT  itemID;

    UINT  itemAction;

    UINT  itemState;

    HWND  hwndItem;

    HDC   hDC;

    RECT  rcItem;

    DWORD itemData;

} DRAWITEMSTRUCT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return TRUE.

Default Action

The DefWindowProc function draws the focus rectangle for an owner-drawn list box item.

Comments

The itemAction member of the DRAWITEMSTRUCT structure specifies the drawing operation that an application should perform.

Before returning from processing this message, an application should ensure that the device context identified by the hDC member of the DRAWITEMSTRUCT structure is in the default state.

See Also

»DefWindowProc«


  WM_DROPFILES

WM_DROPFILES

hDrop = (HANDLE) wParam;  /* handle of internal drop structure */

The WM_DROPFILES message is sent when the user releases the left mouse button while the cursor is in the window of an application that has registered itself as a recipient of dropped files.

Parameters

hDrop

Value of wParam. Identifies an internal structure describing the dropped files. This handle is used by the DragFinish, DragQueryFile, and DragQueryPoint functions to retrieve information about the dropped files.

Return Value

An application should return zero if it processes this message.

See Also

»DragAcceptFiles«, »DragFinish«, »DragQueryFile«, »DragQueryPoint«


  WM_ENABLE

WM_ENABLE

fEnabled = (BOOL) wParam;   /* enabled/disabled flag */

The WM_ENABLE message is sent when an application changes the enabled state of a window. It is sent to the window whose enabled state is changing. This message is sent before the EnableWindow function returns, but after the enabled state (WS_DISABLE style bit) of the window has changed.

Parameters

fEnabled

Value of wParam. Specifies whether the window has been enabled or disabled. This parameter is TRUE if the window has been enabled or FALSE if the window has been disabled.

Return Value

If an application processes this message, it should return zero.

See Also

»EnableWindow«


  WM_ENDSESSION

WM_ENDSESSION

fEndSession = (BOOL) wParam;    /* end-session flag */

The WM_ENDSESSION message is sent to an application after Windows processes the results of the WM_QUERYENDSESSION message. The WM_ENDSESSION message informs the application whether the Windows session is ending.

Parameters

fEndSession

Value of wParam. Specifies whether the session is being ended. If the session is being ended, this parameter is TRUE; otherwise, it is FALSE.

Return Value

If an application processes this message, it should return zero.

Comments

If the fEndSession parameter is TRUE, the Windows session can end any time after all applications have returned from processing this message. Therefore, an application should perform all tasks required for termination before returning from this message.

The application need not call the DestroyWindow or PostQuitMessage function when the session is ending.

See Also

»DestroyWindow«, »PostQuitMessage«, »WM_QUERYENDSESSION«


  WM_ENTERIDLE

WM_ENTERIDLE

fuSource = wParam;    /* idle-source flag                     */

hwnd = (HWND) lParam; /* handle of dialog box or owner window */

The WM_ENTERIDLE message informs an application's main window procedure that a modal dialog box or menu is entering an idle state. A modal dialog box or menu enters an idle state when no messages are waiting in its queue after it has processed one or more previous messages.

Parameters

fuSource

Value of wParam. Specifies whether the message is the result of a dialog box or a menu being displayed. This parameter can be one of the following values:

Value	Meaning
MSGF_DIALOGBOX	The system is idle because a dialog box is displayed.
MSGF_MENU	The system is idle because a menu is displayed.
hwnd

Value of lParam. Contains the handle of the dialog box (if fuSource is MSGF_DIALOGBOX) or of the window containing the displayed menu (if fuSource is MSGF_MENU).

Return Value

An application should return zero if it processes this message.

Comments

The DefWindowProc function returns zero.


  WM_ENTERMENULOOP

WM_ENTERMENULOOP

wParam = (BOOL) fIsTrackPopupMenu /* flags a popup menu     */

lParam = 0 ;                      /* not used; must be zero */

The WM_ENTERMENULOOP message informs an application's main window procedure that a menu modal loop has been entered.

Parameters

fIsTrackPopupMenu

Specifies whether the menu involved is a popup menu. Has a value of TRUE if it is a popup, FALSE if it isn't.

Return Value

An application should return zero if it processes this message.

Comments

The DefWindowProc function returns zero.

See Also

»WM_EXITMENULOOP«


  WM_EXITMENULOOP

WM_EXITLOOP

wParam = (BOOL) fIsTrackPopupMenu /* flags a popup menu     */

lParam = 0 ;                      /* not used; must be zero */

The WM_ENTERMENULOOP message informs an application's main window procedure that a menu modal loop has been exited.

Parameters

fIsTrackPopupMenu

Specifies whether the menu involved is a popup menu. Has a value of TRUE if it is a popup, FALSE if it isn't.

Return Value

An application should return zero if it processes this message.

Comments

The DefWindowProc function returns zero.

See Also

»WM_ENTERMENULOOP«


  WM_ERASEBKGND

WM_ERASEBKGND

hdc = (HDC) wParam; /* device-context handle */

An application sends the WM_ERASEBKGND message when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.

Parameters

hdc

Value of wParam. Identifies the device context.

Return Value

An application should return nonzero if it erases the background; otherwise, it should return zero.

Comments

The DefWindowProc function erases the background by using the class background brush specified by the hbrbackground member of the WNDCLASS structure. If hbrbackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.

An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.)

See Also

»BeginPaint«, »WM_ICONERASEBKGND«


  WM_FONTCHANGE

WM_FONTCHANGE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the WM_FONTCHANGE message to all top-level windows in the system after changing the pool of font resources.

Parameters

This message has no parameters.

Comments

An application that adds or removes fonts from the system (for example, by using the AddFontResource or RemoveFontResource function) should send this message to all top-level windows.

To send the WM_FONTCHANGE message to all top-level windows, an application can call the SendMessage function with the hwnd parameter set to HWND_BROADCAST.

See Also

»AddFontResource«, »RemoveFontResource«, »SendMessage«


  WM_GETDLGCODE

WM_GETDLGCODE

The WM_GETDLGCODE message is sent to the dialog box procedure associated with a control. Normally, Windows handles all arrow-key and TAB-key input to the control. By responding to the WM_GETDLGCODE message, an application can take control of a particular type of input and process the input itself.

Parameters

This message has no parameters.

Return Value

The return value is one or more of the following values, indicating which type of input the application processes.

Value	Meaning
DLGC_BUTTON	Button
DLGC_DEFPUSHBUTTON	Default push button
DLGC_HASSETSEL	EM_SETSEL messages
DLGC_RADIOBUTTON	Radio button
DLGC_STATIC	Static control
DLGC_UNDEFPUSHBUTTON	Non-default push button
DLGC_WANTALLKEYS	All keyboard input
DLGC_WANTARROWS	Direction keys
DLGC_WANTCHARS	WM_CHAR messages
DLGC_WANTMESSAGE	All keyboard input (the application passes this message on to a control)
DLGC_WANTTAB	TAB key
Default Action

The DefWindowProc function returns zero.

Comments

Although the DefWindowProc function always returns zero in response to the WM_GETDLGCODE message, the window functions for the predefined control classes return a code appropriate for each class.

The WM_GETDLGCODE message and the returned values are useful only with user-defined dialog controls or standard controls modified by subclassing.

See Also

»DefWindowProc«, »EM_SETSEL«, »WM_CHAR«


  WM_GETFONT

WM_GETFONT

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a WM_GETFONT message to a control to retrieve the font with which the control is currently drawing its text.

Parameters

This message has no parameters.

Return Value

The return value is the handle of the font used by the control or NULL if the control is using the system font.

See Also

»WM_SETFONT«


  WM_GETHOTKEY

WM_GETHOTKEY

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a WM_GETHOTKEY message to determine the hot key associated with a window.

Parameters

This message has no parameters.

Return Value

The return value is the virtual-key code of the hot key, or NULL if no hot key is associated with the window.

See Also

»WM_SETHOTKEY«


  WM_GETMINMAXINFO

WM_GETMINMAXINFO

lpmmi = (LPMINMAXINFO) lParam; /* address of structure */

The WM_GETMINMAXINFO message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.

Parameters

lpmmi

Value of lParam. Points to a MINMAXINFO structure that contains the default maximized position and dimensions, and the default minimum and maximum tracking sizes. An application can override the defaults by setting the members of this structure. The MINMAXINFO structure has the following form:

typedef struct tagMINMAXINFO {  /* mmi */

    POINT ptReserved;

    POINT ptMaxSize;

    POINT ptMaxPosition;

    POINT ptMinTrackSize;

    POINT ptMaxTrackSize;

} MINMAXINFO;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

The maximum tracking size is the largest window size that can be produced by using the borders to size the window. The minimum tracking size is the smallest window size that can be produced by using the borders to size the window.

See Also

»MoveWindow«, »SetWindowPos«, »MINMAXINFO«


  WM_GETTEXT

WM_GETTEXT

wParam = (WPARAM) cchTextMax;   /* number of characters to copy */

lParam = (LPARAM) lpszText;     /* address of buffer for text   */

An application sends a WM_GETTEXT message to copy the text that corresponds to a window into a buffer provided by the caller.

Parameters

cchTextMax

Value of wParam. Specifies the maximum number of characters to be copied, including the terminating null character.

lpszText

Value of lParam. Points to the buffer that is to receive the text.

Return Value

The return value is the number of characters copied.

Default Action

The DefWindowProc function copies the text associated with the window into the specified buffer and returns the number of characters copied.

Comments

For an edit control, the text to be copied is the contents of the edit control. For a combo box, the text is the contents of the edit control (or static-text) portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title. To copy the text of an item in a list box, an application can use the LB_GETTEXT message.

When the WM_GETTEXT message is sent to a static control with the SS_ICON style, the handle of the icon will be returned in the first four bytes of the buffer pointed to by lpszText. This is true only if the WM_SETTEXT message has been used to set the icon.

See Also

»DefWindowProc«, »GetWindowText«, »GetWindowTextLength«, »LB_GETTEXT«, »WM_GETTEXTLENGTH«, »WM_SETTEXT«


  WM_GETTEXTLENGTH

WM_GETTEXTLENGTH

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a WM_GETTEXTLENGTH message to determine the length, in characters, of the text associated with a window. The length does not include the terminating null character.

Parameters

This message has no parameters.

Return Value

The return value is the length, in characters, of the text.

Default Action

The DefWindowProc function returns the length, in characters, of the text.

Comments

For an edit control, the text to be copied is the contents of the edit control. For a combo box, the text is the contents of the edit control (or static-text) portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title. To determine the length of an item in a list box, an application can use the LB_GETTEXTLEN message.

See Also

»DefWindowProc«, »GetWindowText«, »GetWindowTextLength«, »LB_GETTEXTLEN«, »WM_GETTEXT«


  WM_HOTKEY

WM_HOTKEY

idHotKey = (int) wParam;    /* identifier of hot-key */

The WM_HOTKEY message is posted when the user presses a hot key. The message is placed at the top of the message queue associated with the thread that registered the hot key.

Parameters

idHotKey

Value of wParam. Specifies the identifier of the hot key that generated the message. If the message was generated by a system-defined hot key, the idHotKey parameter will be one of the following values:

Value	Meaning
IDHOT_SNAPDESKTOP	The "snap desktop" hot key was pressed.
IDHOT_SNAPWINDOW	The "snap window" hot key was pressed.
See Also

»RegisterHotKey«, »WM_GETHOTKEY«, »WM_SETHOTKEY«


  WM_HSCROLL

WM_HSCROLL

nScrollCode = (int) LOWORD(wParam); /* scroll bar value     */

nPos = (int) HIWORD(wParam);        /* scroll box position  */

hwndScrollBar = (HWND) lParam;      /* handle of scroll bar */

The WM_HSCROLL message is sent to a window when a scroll event occurs in the window's standard horizontal scroll bar. This message is also sent to the owner of a horizontal scroll bar control when a scroll event occurs in the control.

Parameters

nScrollCode

Value of the low-order word of wParam. Specifies a scroll bar value that indicates the user's scrolling request. This parameter can be one of the following values:

Value	Meaning
SB_BOTTOM	Scroll to lower right.
SB_ENDSCROLL	End scroll.
SB_LINEDOWN	Scroll one line down.
SB_LINEUP	Scroll one line up.
SB_PAGEDOWN	Scroll one page down.
SB_PAGEUP	Scroll one page up.
SB_THUMBPOSITION	Scroll to absolute position. The current position is specified by the nPos parameter.
SB_THUMBTRACK	Drag scroll box (thumb) to specified position. The current position is specified by the nPos parameter.
SB_TOP	Scroll to upper left.
nPos

Value of the high-order word of wParam. Specifies the current position of the scroll box if the nScrollCode parameter is SB_THUMBPOSITION or SB_THUMBTRACK; otherwise, nPos is not used.

hwndScrollBar

Value of lParam. Identifies the control if WM_HSCROLL is sent by a scroll bar control. If WM_HSCROLL is sent by a window's standard scroll bar, hwndScrollBar is not used.

Return Value

If an application processes this message, it should return zero.

Comments

The SB_THUMBTRACK notification code is typically used by applications that provide feedback as the user drags the scroll box.

If an application scrolls the contents of the window, it must also reset the position of the scroll box by using the SetScrollPos function.

See Also

»SetScrollPos«, »WM_VSCROLL«


  WM_HSCROLLCLIPBOARD

WM_HSCROLLCLIPBOARD

hwndViewer = (HWND) wParam;         /* handle of clipboard viewer */

nScrollCode = (int) LOWORD(lParam); /* scroll bar code            */

nPos = (int) HIWORD(lParam);        /* scroll box position        */

The WM_HSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and an event occurs in the clipboard viewer's horizontal scroll bar. The owner should scroll the clipboard image and update the scroll bar values.

Parameters

hwndViewer

Value of wParam. Identifies the clipboard viewer window.

nScrollCode

Value of the low-order word of lParam. Specifies a scroll bar event. This parameter can be one of the following values:

Value	Meaning
SB_BOTTOM	Scroll to lower right.
SB_ENDSCROLL	End scroll.
SB_LINEDOWN	Scroll one line down.
SB_LINEUP	Scroll one line up.
SB_PAGEDOWN	Scroll one page down.
SB_PAGEUP	Scroll one page up.
SB_THUMBPOSITION	Scroll to absolute position. The current position is specified by the nPos parameter.
SB_TOP	Scroll to upper left.
nPos

Value of the high-order word of lParam. Specifies the current position of the scroll box if the nScrollCode parameter is SB_THUMBPOSITION; otherwise, the nPos parameter is not used.

Return Value

If an application processes this message, it should return zero.

Comments

The clipboard owner can use the ScrollWindow function to scroll the image in the clipboard viewer window and invalidate the appropriate region.

See Also

»ScrollWindow«


  WM_ICONERASEBKGND

WM_ICONERASEBKGND

hdc = (HDC) wParam; /* handle of device context */

The WM_ICONERASEBKGND message is sent to a minimized window when the background of the icon must be filled before painting the icon. A window receives this message only if a class icon is defined for the window; otherwise, WM_ERASEBKGND is sent.

Parameters

hdc

Value of wParam. Identifies the device context of the icon.

Return Value

An application should return nonzero if it processes this message.

Comments

The DefWindowProc function fills the icon background with the class background brush of the parent window.

See Also

»DefWindowProc«, »WM_ERASEBKGND«


  WM_INITDIALOG

WM_INITDIALOG

hwndFocus = (HWND) wParam; /* handle of control to receive focus */

lInitParam = lParam;       /* initialization parameter           */

The WM_INITDIALOG message is sent to the dialog box procedure immediately before a dialog box is displayed. Dialog box procedures typically use this message to initialize controls and carry out any other initialization tasks that affect the appearance of the dialog box.

Parameters

hwndFocus

Value of wParam. Identifies the control to receive the default keyboard focus. Windows assigns the default keyboard focus only if the dialog box procedure returns TRUE.

lInitParam

Value of lParam. Specifies additional initialization data. This data is passed to Windows as the lParamInit parameter in a call to the CreateDialogIndirectParam, CreateDialogParam, DialogBoxIndirectParam, or DialogBoxParam function used to create the dialog box. This parameter is zero if any other dialog box creation function is used.

Return Value

The dialog box procedure should return TRUE to direct Windows to set the keyboard focus to the control given by hwndFocus. Otherwise, it should return FALSE to prevent Windows from setting the default keyboard focus.

Comments

The control to receive the default keyboard focus is always the first control in the dialog box that is visible, not disabled, and has the WS_TABSTOP style. When the dialog box procedure returns TRUE, Windows checks the control to ensure that the procedure has not disabled it. If it has been disabled, Windows sets the keyboard focus to the next control that is visible, not disabled, and has the WS_TABSTOP.

An application can return FALSE only if it has set the keyboard focus to one of the controls of the dialog box.

See Also

»CreateDialogIndirectParam«, »CreateDialogParam«, »DialogBoxIndirectParam«, »DialogBoxParam«, »SetFocus«


  WM_INITMENU

WM_INITMENU

hmenuInit = (HMENU) wParam; /* handle of menu to initialize */

The WM_INITMENU message is sent when a menu is about to become active. It occurs when the user clicks an item on the menu bar or presses a menu key. This allows the application to modify the menu before it is displayed.

Parameters

hmenuInit

Value of wParam. Identifies the menu to be initialized.

Return Value

If an application processes this message, it should return zero.

Comments

A WM_INITMENU message is sent only when a menu is first accessed; only one WM_INITMENU message is generated for each access. For example, moving the mouse across several menu items while holding down the button does not generate new messages. WM_INITMENU does not provide information about menu items.

See Also

»WM_INITMENUPOPUP«


  WM_INITMENUPOPUP

WM_INITMENUPOPUP

hmenuPopup = (HMENU) wParam;         /* handle of pop-up menu */

uPos = (UINT) LOWORD(lParam);        /* pop-up item position  */

fSystemMenu = (BOOL) HIWORD(lParam); /* System menu flag      */

The WM_INITMENUPOPUP message is sent when a pop-up menu is about to become active. This allows an application to modify the pop-up menu before it is displayed, without changing the entire menu.

Parameters

hmenuPopup

Value of wParam. Identifies the pop-up menu.

uPos

Value of the low-order word of lParam. Specifies the zero-based relative position of the menu item that invokes the pop-up menu.

fSystemMenu

Value of the high-order word of lParam. Specifies whether the pop-up menu is the System menu. If the pop-up menu is the System menu (also known as Control menu), this parameter is TRUE; otherwise, it is FALSE.

Return Value

If an application processes this message, it should return zero.

See Also

»WM_INITMENU«


  WM_KEYDOWN

WM_KEYDOWN

nVirtKey = (int) wParam;    /* virtual-key code */

lKeyData = lParam;          /* key data         */

The WM_KEYDOWN message is posted to the window with the keyboard focus when a nonsystem key is pressed. A nonsystem key is a key that is pressed when the ALT key is not pressed.

Parameters

nVirtKey

Value of wParam. Specifies the virtual-key code of the nonsystem key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is always 0 for a WM_KEYDOWN message.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31	Specifies the transition state. The value is always 0 for a WM_KEYDOWN message.
Return Value

An application should return zero if it processes this message.

Default Action

If the F10 key is pressed, the DefWindowProc function sets an internal flag. When DefWindowProc receives the WM_KEYUP message, the function checks whether the internal flag is set and, if so, sends a WM_SYSCOMMAND message to the top-level window. The wParam parameter of the message is set to SC_KEYMENU.

Comments

Because of the autorepeat feature, more than one WM_KEYDOWN message may be posted before a WM_KEYUP message is posted. The previous key state (bit 30) can be used to determine whether the WM_KEYDOWN message indicates the first down transition or a repeated down transition.

For enhanced 101- and 102-key keyboards, extended keys are the right ALT and CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Other keyboards may support the extended-key bit in the lKeyData parameter.

See Also

»DefWindowProc«, »WM_CHAR«, »WM_KEYUP«, »WM_SYSCOMMAND«


  WM_KEYUP

WM_KEYUP

nVirtKey = (int) wParam;    /* virtual-key code */

lKeyData = lParam;          /* key data         */

The WM_KEYUP message is posted to the window with the keyboard focus when a nonsystem key is released. A nonsystem key is a key that is pressed when the ALT key is not pressed, or a keyboard key that is pressed when a window has the keyboard focus.

Parameters

nVirtKey

Value of wParam. Specifies the virtual-key code of the nonsystem key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key. The repeat count is always one for a WM_KEYUP message.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is always 0 for a WM_KEYUP message.
30	Specifies the previous key state. The value is always 1 for a WM_KEYUP message.
31	Specifies the transition state. The value is always 1 for a WM_KEYUP message.
Return Value

An application should return zero if it processes this message.

Default Action

The DefWindowProc function sends a WM_SYSCOMMAND message to the top-level window if the F10 key or the ALT key was released. The wParam parameter of the message is set to SC_KEYMENU.

Comments

For enhanced 101- and 102-key keyboards, extended keys are the right ALT and CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Other keyboards may support the extended-key bit in the lKeyData parameter.

See Also

»DefWindowProc«, »WM_KEYDOWN«, »WM_SYSCOMMAND«


  WM_KILLFOCUS

WM_KILLFOCUS

hwndGetFocus = (HWND) wParam; /* handle of window receiving focus */

The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus.

Parameters

hwndGetFocus

Value of wParam. Identifies the window that receives the keyboard focus (may be NULL).

Return Value

An application should return zero if it processes this message.

Comments

If an application is displaying a caret, the caret should be destroyed at this point.

See Also

»SetFocus«, »WM_SETFOCUS«


  WM_LBUTTONDBLCLK

WM_LBUTTONDBLCLK

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_LBUTTONDBLCLK message is posted when the user double-clicks the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_MBUTTON	Set if the middle mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which Windows generates whenever the user presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mouse button actually generates four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP again.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »GetDoubleClickTime«, »SetCapture«, »SetDoubleClickTime«, »WM_LBUTTONDOWN«, »WM_LBUTTONUP«


  WM_LBUTTONDOWN

WM_LBUTTONDOWN

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_LBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_MBUTTON	Set if the middle mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«, »WM_LBUTTONDBLCLK«, »WM_LBUTTONUP«


  WM_LBUTTONUP

WM_LBUTTONUP

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_LBUTTONUP message is posted when the user releases the left mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_MBUTTON	Set if the middle mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«, »WM_LBUTTONDBLCLK«, »WM_LBUTTONDOWN«


  WM_MBUTTONDBLCLK

WM_MBUTTONDBLCLK

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_MBUTTONDBLCLK message is posted when the user double-clicks the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_MBUTTON	Set if the middle mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

Only windows that have the CS_DBLCLKS style can receive WM_MBUTTONDBLCLK messages, which Windows generates whenever the user presses, releases, and again presses the middle mouse button within the system's double-click time limit. Double-clicking the middle mouse button actually generates four messages: WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MBUTTONDBLCLK, and WM_MBUTTONUP again.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »GetDoubleClickTime«, »SetCapture«, »SetDoubleClickTime«, »WM_MBUTTONDOWN«, »WM_MBUTTONUP«


  WM_MBUTTONDOWN

WM_MBUTTONDOWN

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_MBUTTONDOWN message is posted when the user presses the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«, »WM_MBUTTONDBLCLK«, »WM_MBUTTONUP«


  WM_MBUTTONUP

WM_MBUTTONUP

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_MBUTTONUP message is posted when the user releases the middle mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«, »WM_MBUTTONDBLCLK«, »WM_MBUTTONDOWN«


  WM_MDIACTIVATE

WM_MDIACTIVATE

/* Message sent to MDI client	*/

wParam = (WPARAM) (HWND) hwndChildAct; 	/* child to activate       	*/

lParam = 0;                            	/* not used, must be zero  	*/

/* Message received by MDI child	*/

hwndChildDeact = (HWND) wParam;        	/* child being deactivated 	*/

hwndChildAct = (HWND) lParam;          	/* child being activated   	*/

An application sends the WM_MDIACTIVATE message to a multiple document interface (MDI) client window to instruct the client window to activate a different MDI child window. As the client window processes this message, it sends WM_MDIACTIVATE to the child window being deactivated and to the child window being activated.

Parameters

In messages sent to an MDI client window:

hwndChildAct

Value of wParam. Identifies the MDI child window to be activated.

In messages received by an MDI child window:

hwndChildDeact

Value of wParam. Identifies the MDI child window being deactivated.

hwndChildAct

Value of lParam. Identifies the MDI child window being activated.

Return Value

If an application sends this message to an MDI client window, the return value is zero. An MDI child window should return zero if it processes this message.

Comments

An MDI child window is activated independently of the MDI frame window. When the frame window becomes active, the child window last activated by using the WM_MDIACTIVATE message receives the WM_NCACTIVATE message to draw an active window frame and title bar; the child window does not receive another WM_MDIACTIVATE message.

See Also

»WM_MDIGETACTIVE«, »WM_MDINEXT«, »WM_NCACTIVATE«


  WM_MDICASCADE

WM_MDICASCADE

wParam = (WPARAM) (UINT) fuCascade;  /* cascade flag           */

lParam = 0;                          /* not used, must be zero */

An application sends the WM_MDICASCADE message to a multiple document interface (MDI) client window to arrange all its child windows in a cascade format.

Parameters

fuCascade

Value of wParam. Specifies a cascade flag. The only flag currently available, MDITILE_SKIPDISABLED, prevents disabled MDI child windows from being cascaded.

Return Value

If the message succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»WM_MDIICONARRANGE«, »WM_MDITILE«


  WM_MDICREATE

WM_MDICREATE

wParam = 0;                                   /* not used, must be zero */

lParam = (LPARAM) (LPMDICREATESTRUCT) lpmdic; /* creation data          */

An application sends the WM_MDICREATE message to a multiple document interface (MDI) client window to create an MDI child window.

Parameters

lpmdic

Points to an MDICREATESTRUCT structure containing information that Windows uses to create the MDI child window. The MDICREATESTRUCT structure has the following form:

typedef struct tagMDICREATESTRUCT { /* mdic */

    LPCTSTR szClass;

    LPCTSTR szTitle;

    HANDLE  hOwner;

    int     x;

    int     y;

    int     cx;

    int     cy;

    DWORD   style;

    LPARAM  lParam;

} MDICREATESTRUCT;

Return Value

For a full description of this structure, see Chapter 3, »Structures«.

If the message succeeds, the return value is the handle of the new child window; otherwise, it is NULL.

Comments

The MDI child window is created with the style bits WS_CHILD, WS_CLIPSIBLINGS, WS_CLIPCHILDREN, WS_SYSMENU, WS_CAPTION, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX, plus additional style bits specified in the MDICREATESTRUCT structure to which the lpmdic parameter points. Windows adds the title of the new child window to the Window menu of the frame window. An application should use this message to create all child windows of the client window.

If an MDI client window receives any message that changes the activation of its child windows while the active child window is maximized, Windows restores the active child window and maximizes the newly activated child window.

When an MDI child window is created, Windows sends the WM_CREATE message to the window. The lParam parameter of the WM_CREATE message contains a pointer to a CREATESTRUCT structure. The lpCreateParams member of this structure contains a pointer to the MDICREATESTRUCT structure passed with the WM_MDICREATE message that created the MDI child window.

An application should not send a second WM_MDICREATE message while a WM_MDICREATE message is still being processed. For example, it should not send a WM_MDICREATE message while an MDI child window is processing its WM_MDICREATE message.

See Also

»CreateMDIWindow«, »WM_CREATE«, »WM_MDIDESTROY«


  WM_MDIDESTROY

WM_MDIDESTROY

wParam = (WPARAM) (HWND) hwndChild; /* handle of child to close   */

lParam = 0;                         /* not used, must be zero     */

An application sends the WM_MDIDESTROY message to a multiple document interface (MDI) client window to close an MDI child window.

Parameters

hwndChild

Value of wParam. Identifies the MDI child window to be closed.

Return Value

This message always returns zero.

Comments

This message removes the title of the MDI child window from the MDI frame window and deactivates the child window. An application should use this message to close all MDI child windows.

If an MDI client window receives a message that changes the activation of its child windows and the active MDI child window is maximized, Windows restores the active child window and maximizes the newly activated child window.

See Also

»WM_MDICREATE«


  WM_MDIGETACTIVE

WM_MDIGETACTIVE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the WM_MDIGETACTIVE message to a multiple document interface (MDI) client window to retrieve the handle of the active MDI child window.

Parameters

This message has no parameters.

Return Value

The return value is the handle of the active MDI child window.

Comments

In Windows version 3.x, the return value includes a flag indicating whether the MDI child window is maximized. In the Win32 application programming interface (API), return values do not include this flag. To determine whether the MDI child window is maximized, use the GetWindowLong function and a Boolean test, as follows:

fMaximized = GetWindowLong(hwndMdiChild, GWL_STYLE) & WS_MAXIMIZE;

See Also

»GetWindowLong«


  WM_MDIICONARRANGE

WM_MDIICONARRANGE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the WM_MDIICONARRANGE message to a multiple document interface (MDI) client window to arrange all minimized MDI child windows. It does not affect child windows that are not minimized.

Parameters

This message has no parameters.

See Also

»WM_MDICASCADE«, »WM_MDITILE«


  WM_MDIMAXIMIZE

WM_MDIMAXIMIZE

wParam = (WPARAM) (HWND) hwndMax; /* handle of child to maximize */

lParam = 0;                       /* not used, must be zero      */

An application sends the WM_MDIMAXIMIZE message to a multiple document interface (MDI) client window to maximize an MDI child window. Windows resizes the child window to make its client area fill the client window. Windows places the child window's System menu icon in the rightmost position of the frame window's menu bar, and places the child window's restore icon in the leftmost position. Windows also appends the title bar text of the child window to that of the frame window.

Parameters

hwndMax

Value of wParam. Identifies the MDI child window to be maximized.

Return Value

The return value is always zero.

Comments

If an MDI client window receives any message that changes the activation of its child windows while the currently active MDI child window is maximized, Windows restores the active child window and maximizes the newly activated child window.

See Also

»WM_MDIRESTORE«


  WM_MDINEXT

WM_MDINEXT

wParam = (WPARAM) (HWND) hwndChild; /* handle of child        */

lParam = (LPARAM) fNext;            /* next or previous child */

An application sends the WM_MDINEXT message to a multiple document interface (MDI) client window to activate the next or previous child window.

Parameters

hwndChild

Value of wParam. Identifies the MDI child window. Windows activates the child window that is immediately before or after the given child window, depending on the value of the fNext parameter. If the hwndChild parameter is NULL, Windows activates the child window that is immediately before or after the currently active child window.

fNext

Value of lParam. If this parameter is zero, Windows activates the next MDI child window and places the child window identified by the hwndChild parameter behind all other child windows. If this parameter is nonzero, Windows activates the previous child window, placing it in front of the child window identified by hwndChild.

Return Value

The return value is always zero.

Comments

If an MDI client window receives any message that changes the activation of its child windows while the active MDI child window is maximized, Windows restores the active child window and maximizes the newly activated child window.

See Also

»WM_MDIACTIVATE«, »WM_MDIGETACTIVE«


  WM_MDIREFRESHMENU

WM_MDIREFRESHMENU

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the WM_MDIREFRESHMENU message to a multiple document interface (MDI) client window to refresh the Window menu of the MDI frame window.

Parameters

This message has no parameters.

Return Value

If the message succeeds, the return value is the handle of the frame window menu; otherwise, it is NULL.

Comments

After sending this message, an application must call the DrawMenuBar function to update the menu bar.

See Also

»DrawMenuBar«, »WM_MDISETMENU«


  WM_MDIRESTORE

WM_MDIRESTORE

wParam = (WPARAM) (HWND) hwndRes; /* handle of child to restore */

lParam = 0;                       /* not used, must be zero     */

An application sends the WM_MDIRESTORE message to a multiple document interface (MDI) client window to restore an MDI child window from maximized or minimized size.

Parameters

hwndRes

Value of wParam. Identifies the MDI child window to be restored.

Return Value

The return value is always zero.

See Also

»WM_MDIMAXIMIZE«


  WM_MDISETMENU

WM_MDISETMENU

wParam = (WPARAM) (HMENU) hmenuFrame;  /* handle of frame menu  */

lParam = (LPARAM) (HMENU) hmenuWindow; /* handle of Window menu */

An application sends the WM_MDISETMENU message to a multiple document interface (MDI) client window to replace the entire menu of an MDI frame window, to replace the Window menu of the frame window, or both.

Parameters

hmenuFrame

Value of wParam. Identifies the new frame window menu. If this parameter is NULL, the frame window menu is not changed.

hmenuWindow

Value of lParam. Identifies the new Window menu. If this parameter is NULL, the Window menu is not changed.

Return Value

If the message succeeds, the return value is the handle of the old frame window menu; otherwise, it is zero.

Comments

After sending this message, an application must call the DrawMenuBar function to update the menu bar.

If this message replaces the Window menu, the MDI child window menu items are removed from the previous Window menu and added to the new Window menu.

If an MDI child window is maximized and this message replaces the MDI frame window menu, the System menu icon and restore icon are removed from the previous frame window menu and added to the new frame window menu.

See Also

»DrawMenuBar«, »WM_MDIREFRESHMENU«


  WM_MDITILE

WM_MDITILE

wParam = (WPARAM) (UINT) fuTile; /* tiling flag            */

lParam = 0;                      /* not used, must be zero */

An application sends the WM_MDITILE message to a multiple document interface (MDI) client window to arrange all of its MDI child windows in a tile format.

Parameters

fuTile

Specifies a tiling flag. This parameter can be one of the following values:

Value	Description
MDITILE_HORIZONTAL	Tiles MDI child windows so that they are wide rather than tall.
MDITILE_SKIPDISABLED	Prevents disabled MDI child windows from being tiled.
MDITILE_VERTICAL	Tiles MDI child windows so that they are tall rather than wide.
Return Value

If the message succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»WM_MDICASCADE«, »WM_MDIICONARRANGE«


  WM_MEASUREITEM

WM_MEASUREITEM

idCtl = (UINT) wParam;                /* control identifier    */

lpmis = (LPMEASUREITEMSTRUCT) lParam; /* item-size information */

The WM_MEASUREITEM message is sent to the owner window of an owner-drawn button, combo box, list box, or menu item when the control or menu is created.

Parameters

idCtl

Value of wParam. Contains the value of the CtlID member of the MEASUREITEMSTRUCT structure pointed to by lpmis. This value identifies the control that sent the WM_MEASUREITEM message.

If the value is zero, the message was sent by a menu.

If the value is non-zero, the message was sent by a combo box or by a list box.

If the value is non-zero, and the value of the itemID member of the MEASUREITEMSTRUCT pointed to by lpmis is (UINT) −1, the message was sent by a combo edit field.

lpmis

Value of lParam. Points to a MEASUREITEMSTRUCT structure that contains the dimensions of the owner-drawn control or menu item. The MEASUREITEMSTRUCT structure has the following form:

typedef struct tagMEASUREITEMSTRUCT {   /* mis */

    UINT  CtlType;

    UINT  CtlID;

    UINT  itemID;

    UINT  itemWidth;

    UINT  itemHeight;

    DWORD itemData;

} MEASUREITEMSTRUCT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return TRUE.

Comments

When the owner window receives the WM_MEASUREITEM message, the owner fills in the MEASUREITEMSTRUCT structure pointed to by the lParam parameter of the messages and returns; this informs Windows of the dimensions of the control. If a list box or combo box is created with the LBS_OWNERDRAWVARIABLE or CBS_OWNERDRAWVARIABLE style, this message is sent to the owner for each item in the control; otherwise, this message is sent once.

Windows sends the WM_MEASUREITEM message to the owner window of combo boxes and list boxes created with the OWNERDRAWFIXED style before sending the WM_INITDIALOG message. As a result, when the owner receives this message, Windows has not yet determined the height and width of the font used in the control; function calls and calculations requiring these values should occur in the main function of the application or library.

See Also

»WM_INITDIALOG«


  WM_MENUCHAR

WM_MENUCHAR

chUser = (char) LOWORD(wParam); /* ASCII character */

fuFlag = (UINT) HIWORD(wParam); /* menu flag       */

hmenu = (HMENU) lParam;         /* handle of menu  */

The WM_MENUCHAR message is sent when a menu is active and the user presses a key that does not correspond to any mnemonic or accelerator key. This message is sent to the window that owns the menu.

Parameters

chUser

Value of the low-order word of wParam. Specifies the ASCII character that corresponds to the key the user pressed.

fuFlag

Value of the high-order word of wParam. Specifies the type of the active menu. This parameter can be one of the following values:

Value	Meaning
MF_POPUP	Pop-up menu
MF_SYSMENU	System menu
hmenu

Value of lParam. Identifies the active menu.

Return Value

An application that processes this message should return one of the following values in the high-order word of the return value:

Value	Meaning
0	Informs Windows that it should discard the character the user pressed and create a short beep on the system speaker.
1	Informs Windows that it should close the active menu.
2	Informs Windows that the low-order word of the return value specifies the zero-based relative position of a menu item. This item is selected by Windows.
Comments

The low-order word is ignored if the high-order word contains 0 or 1. An application should process this message when an accelerator is used to select a menu item that displays a bitmap.


  WM_MENUSELECT

WM_MENUSELECT

uItem = (UINT) LOWORD(wParam);   /* menu item or pop-up menu index */

fuFlags = (UINT) HIWORD(wParam); /* menu flags                     */

hmenu = (HMENU) lParam;          /* handle of menu clicked on      */

The WM_MENUSELECT message is sent to a menu's owner window when the user selects a menu item.

Parameters

uItem

Value of the low-order word of wParam. If the selected item is a command item, this parameter contains the identifier of the menu item. If the selected item invokes a pop-up menu, this parameter contains the menu index of the pop-up menu in the main menu, and the hMenu parameter then contains the handle of the main (clicked-on) menu; use the GetSubMenu function to get the menu handle of the pop-up menu.

fuFlags

Value of the high-order word of wParam. Specifies one or more menu flags. This parameter can be a combination of the following values:

Value	Description
MF_BITMAP	Item displays a bitmap.
MF_CHECKED	Item is checked.
MF_DISABLED	Item is disabled.
MF_GRAYED	Item is grayed.
MF_MOUSESELECT	Item is selected with the mouse.
MF_OWNERDRAW	Item is an owner-drawn item.
MF_POPUP	Item invokes a pop-up menu.
MF_SYSMENU	Item is contained in the System menu (also known as Control menu). The hmenu parameter identifies the System menu associated with the message.
hmenu

Value of lParam. Identifies the menu that was clicked on.

Return Value

If an application processes this message, it should return zero.

Comments

If the fuFlags parameter contains 0xFFFF and the hmenu parameter contains NULL, Windows has closed the menu because the user pressed the ESC key or clicked outside the menu.

DO NOT use the value −1 for fuFlags. That is because fuFlags is specified as (UINT) HIWORD(wParam). If HIWORD(wParam) were 0xFFFF, fuFlags (because of the UINT cast) would be 0x0000FFFF, not −1.


  WM_MOUSEACTIVATE

WM_MOUSEACTIVATE

hwndTopLevel = (HWND) wParam;       /* handle of top-level parent */

nHittest = (INT) LOWORD(lParam);    /* hit-test code              */

uMsg =  (UINT) HIGHWORD(lParam);    /* mouse message              */

The WM_MOUSEACTIVATE message is sent when the cursor is in an inactive window and the user presses a mouse button. The parent window receives this message only if the child window passes it to the DefWindowProc function.

Parameters

hwndTopLevel

Value of wParam. Identifies the top-level parent window of the window being activated.

nHittest

Value of the low-order word of lParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

uMsg

Value of the high-order word of lParam. Specifies the identifier of the mouse message generated when the user pressed a mouse button. The mouse message is either discarded or posted to the window, depending on the return value.

Return Value

The return value specifies whether the window should be activated and whether the identifier of the mouse message should be discarded. It must be one of the following values:

Value	Meaning
MA_ACTIVATE	Activate the window, and do not discard the mouse message.
MA_NOACTIVATE	Do not activate the window, and do not discard the mouse message.
MA_ACTIVATEANDEAT	Activate the window, and discard the mouse message.
MA_NOACTIVATEANDEAT	Do not activate the window, but discard the mouse message.
Default Action

The DefWindowProc function passes the message to a child window's parent window before any processing occurs. The parent window determines whether to activate the child window. If it activates the child window, the parent window should return TRUE to prevent the system from processing the message further.

See Also

»DefWindowProc«, »WM_NCHITTEST«


  WM_MOUSEMOVE

WM_MOUSEMOVE

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_MOUSEMOVE message is posted to a window when the cursor moves. If the mouse is not captured, the message is posted to the window that contains the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_MBUTTON	Set if the middle mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Comments

The MAKEPOINTS macro can be used to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«


  WM_MOVE

WM_MOVE

xPos = (int) LOWORD(lParam);    /* horizontal position */

yPos = (int) HIWORD(lParam);    /* vertical position   */

The WM_MOVE message is sent after a window has been moved.

Parameters

xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the upper-left corner of the client area of the window.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the upper-left corner of the client area of the window.

Return Value

If an application processes this message, it should return zero.

Comments

The xPos and yPos parameters are given in screen coordinates for overlapped and pop-up windows and in parent-client coordinates for child windows.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»POINTS«


  WM_NCACTIVATE

WM_NCACTIVATE

fActive = (BOOL) wParam;

The WM_NCACTIVATE message is sent to a window when its nonclient area needs to be changed to indicate an active or inactive state.

Parameters

fActive

Value of wParam. Specifies when a title bar or icon needs to be changed to indicate an active or inactive state. If an active title bar or icon is to be drawn, the fActive parameter is TRUE . It is FALSE for an inactive title bar or icon.

Return Value

When the fActive parameter is FALSE, an application should return TRUE to indicate that Windows should proceed with the default processing, or it should return FALSE to prevent the title bar or icon from being deactivated. When fActive is TRUE, the return value is ignored.

Default Action

The DefWindowProc function draws the title bar or icon title in its active colors when the fActive parameter is TRUE and in its inactive colors when fActive is FALSE.

See Also

»DefWindowProc«


  WM_NCCALCSIZE

WM_NCCALCSIZE

fCalcValidRects = (BOOL) wParam;        /* valid area flag */

lpncsp = (LPNCCALCSIZE_PARAMS) lParam;  /* address of data */

The WM_NCCALCSIZE message is sent when the size and position of a window's client area must be calculated. By processing this message, an application can control the contents of the window's client area when the size or position of the window changes.

Parameters

fCalcValidRects

Value of wParam. Specifies whether the application should indicate which part of the client area contains valid information. Windows will copy the valid information to the specified area within the new client area. If this parameter is TRUE, the application should specify which part of the client area is valid.

lpncsp

Value of lParam. Points to an NCCALCSIZE_PARAMS structure that contains information an application can use to calculate the new size and position of the client rectangle. The NCCALCSIZE_PARAMS structure has the following form:

typedef struct tagNCCALCSIZE_PARAMS { /* nccp */

    RECT       rgrc[3];

    PWINDOWPOS lppos;

} NCCALCSIZE_PARAMS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If the fCalcValidRects parameter is FALSE, the application should return zero. If fCalcValidRects is TRUE, the application can return zero or a valid combination of the following values:

Value	Meaning
WVR_ALIGNTOP, WVR_ALIGNLEFT, WVR_ALIGNBOTTOM, WVR_ALIGNRIGHT
	These values, used in combination, specify that the client area of the window is to be preserved and aligned appropriately relative to the new position of the window. For example, to align the client area to the lower-left corner, return the WVR_ALIGNLEFT and WVR_ALIGNTOP values.
WVR_HREDRAW, WVR_VREDRAW
	These values, used in combination with any other values, cause the window to be completely redrawn if the client rectangle changes size horizontally or vertically. These values are similar to the CS_HREDRAW and CS_VREDRAW class styles.
WVR_REDRAW
	This value causes the entire window to be redrawn. It is a combination of WVR_HREDRAW and WVR_VREDRAW values.
WVR_VALIDRECTS
	This value indicates that, upon return from WM_NCCALCSIZE, the rectangles specified by the rgrc[1] and rgrc[2] members of the NCCALCSIZE_PARAMS structure contain valid source and destination area rectangles, respectively. Windows combines these rectangles to calculate the area of the window to be preserved. Windows copies any part of the window image that is within the source rectangle and clips the image to the destination rectangle. Both rectangles are in parent-relative or screen-relative coordinates.
	This return value allows an application to implement more elaborate client-area preservation strategies, such as centering or preserving a subset of the client area.
If fCalcValidRects is TRUE and an application returns zero, the old client area is preserved and is aligned with the upper-left corner of the new client area.

Default Action

The window may be redrawn, depending on whether the CS_HREDRAW or CS_VREDRAW class style is specified. This is the default, backward-compatible processing of this message by the DefWindowProc function (in addition to the usual client rectangle calculation described in the preceding table).

See Also

»DefWindowProc«, »MoveWindow«, »SetWindowPos«, »NCCALCSIZE_PARAMS«, »RECT«


  WM_NCCREATE

WM_NCCREATE

lpcs = (LPCREATESTRUCT) lParam; /* initialization data */

The WM_NCCREATE message is sent prior to the WM_CREATE message when a window is first created.

Parameters

lpcs

Value of wParam. Points to the CREATESTRUCT structure for the window. The CREATESTRUCT structure has the following form:

typedef struct tagCREATESTRUCT { /* cs */

    LPVOID lpCreateParams;

    HANDLE hInstance;

    HMENU  hMenu;

    HWND   hwndParent;

    int    cy;

    int    cx;

    int    y;

    int    x;

    LONG   style;

    LPCSTR lpszName;

    LPCSTR lpszClass;

    DWORD  dwExStyle;

} CREATESTRUCT;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle.

Default Action

The DefWindowProc function returns TRUE.

See Also

»CreateWindow«, »CreateWindowEx«, »DefWindowProc«, »CREATESTRUCT«, »WM_CREATE«


  WM_NCDESTROY

WM_NCDESTROY

The WM_NCDESTROY message informs a window that its nonclient area is being destroyed. The DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY message. WM_DESTROY is used to free the allocated memory object associated with the window.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

Comments

This message frees any memory internally allocated for the window.

See Also

»DestroyWindow«, »WM_DESTROY«, »WM_NCCREATE«


  WM_NCHITTEST

WM_NCHITTEST

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper left corner of the screen.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper left corner of the screen.

Return Value

The return value of the DefWindowProc function is one of the following values, indicating the position of the cursor hot spot:

Value	Location of hot spot
HTBORDER	In the border of a window that does not have a sizing border
HTBOTTOM	In the lower horizontal border of a window
HTBOTTOMLEFT	In the lower left corner of a window border
HTBOTTOMRIGHT	In the lower right corner of a window border
HTCAPTION	In a title bar
HTCLIENT	In a client area
HTERROR	On the screen background or on a dividing line between windows (same as HTNOWHERE, except that the DefWindowProc function produces a system beep to indicate an error)
HTGROWBOX	In a size box (same as HTSIZE)
HTHSCROLL	In a horizontal scroll bar
HTLEFT	In the left border of a window
HTMENU	In a menu
HTNOWHERE	On the screen background or on a dividing line between windows
HTREDUCE	In a Minimize button
HTRIGHT	In the right border of a window
HTSIZE	In a size box (same as HTGROWBOX)
HTSYSMENU	In a System menu or in a Close button in a child window
HTTOP	In the upper horizontal border of a window
HTTOPLEFT	In the upper left corner of a window border
HTTOPRIGHT	In the upper right corner of a window border
HTTRANSPARENT	In a window currently covered by another window
HTVSCROLL	In the vertical scroll bar
HTZOOM	In a Maximize button
Comments

The MAKEPOINTS macro can be used to convert the lParam parameter to a POINTS structure.

See Also

»DefWindowProc«, »GetCapture«


  WM_NCLBUTTONDBLCLK

WM_NCLBUTTONDBLCLK

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCLBUTTONDBLCLK message is posted when the user double-clicks the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function tests the given point to find out the location of the cursor and carries out the appropriate action. If appropriate, DefWindowProc sends the WM_SYSCOMMAND message to the window.

Comments

A window need not have the CS_DBLCLKS style to receive WM_NCLBUTTONDBLCLK messages.

Windows generates a WM_NCLBUTTONDBLCLK message when the user presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mouse button actually generates four messages: WM_NCLBUTTONDOWN, WM_NCLBUTTONUP, WM_NCLBUTTONDBLCLK, and WM_NCLBUTTONUP again.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCLBUTTONDOWN«, »WM_NCLBUTTONUP«, »WM_SYSCOMMAND«


  WM_NCLBUTTONDOWN

WM_NCLBUTTONDOWN

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCLBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function tests the given point to find out the location of the cursor and carries out the appropriate action. If appropriate, DefWindowProc sends the WM_SYSCOMMAND message to the window.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCLBUTTONDBLCLK«, »WM_NCLBUTTONUP«, »WM_SYSCOMMAND«


  WM_NCLBUTTONUP

WM_NCLBUTTONUP

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* mouse-cursor coordinates */

The WM_NCLBUTTONUP message is posted when the user releases the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function tests the given point to find out the location of the cursor and carries out the appropriate action. If appropriate, DefWindowProc sends the WM_SYSCOMMAND message to the window.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCLBUTTONDBLCLK«, »WM_NCLBUTTONDOWN«, »WM_SYSCOMMAND«


  WM_NCMBUTTONDBLCLK

WM_NCMBUTTONDBLCLK

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCMBUTTONDBLCLK message is posted when the user double-clicks the middle mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

A window need not have the CS_DBLCLKS style to receive WM_NCMBUTTONDBLCLK messages.

Windows generates a WM_NCMBUTTONDBLCLK message when the user presses, releases, and again presses the middle mouse button within the system's double-click time limit. Double-clicking the middle mouse button actually generates four messages: WM_NCMBUTTONDOWN, WM_NCMBUTTONUP, WM_NCMBUTTONDBLCLK, and WM_NCMBUTTONUP again.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCMBUTTONDOWN«, »WM_NCMBUTTONUP«, »WM_SYSCOMMAND«


  WM_NCMBUTTONDOWN

WM_NCMBUTTONDOWN

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCMBUTTONDOWN message is posted when the user presses the middle mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCMBUTTONDBLCLK«, »WM_NCMBUTTONUP«, »WM_SYSCOMMAND«


  WM_NCMBUTTONUP

WM_NCMBUTTONUP

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCMBUTTONUP message is posted when the user releases the middle mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCMBUTTONDBLCLK«, »WM_NCMBUTTONDOWN«, »WM_SYSCOMMAND«


  WM_NCMOUSEMOVE

WM_NCMOUSEMOVE

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCMOUSEMOVE message is posted to a window when the cursor is moved within the nonclient area of the window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

The MAKEPOINTS macro can be used to convert the lParam parameter to a POINTS structure.

See Also

»DefWindowProc«, »WM_NCHITTEST«


  WM_NCPAINT

WM_NCPAINT

hrgn = (HRGN) wParam;   /* update-region handle */

An application sends the WM_NCPAINT message to a window when its frame must be painted.

Parameters

hrgn

Value of wParam. Identifies the update region of the window. The update region is clipped to the window frame.

Return Value

An application should return zero if it processes this message.

Comments

The DefWindowProc function paints the window frame.

Comments

An application can intercept this message and paint its own custom window frame. The clipping region for a window is always rectangular, even if the shape of the frame is altered.

See Also

»DefWindowProc«, »GetWindowDC«, »WM_PAINT«


  WM_NCRBUTTONDBLCLK

WM_NCRBUTTONDBLCLK

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCRBUTTONDBLCLK message is posted when the user double-clicks the right mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

A window need not have the CS_DBLCLKS style to receive WM_NCRBUTTONDBLCLK messages.

Windows generates a WM_NCRBUTTONDBLCLK message when the user presses, releases, and again presses the right mouse button within the system's double-click time limit. Double-clicking the right mouse button actually generates four messages: WM_NCRBUTTONDOWN, WM_NCRBUTTONUP, WM_NCRBUTTONDBLCLK, and WM_NCRBUTTONUP again.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCRBUTTONDOWN«, »WM_NCRBUTTONUP«, »WM_SYSCOMMAND«


  WM_NCRBUTTONDOWN

WM_NCRBUTTONDOWN

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCRBUTTONDOWN message is posted when the user presses the right mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCRBUTTONDBLCLK«, »WM_NCRBUTTONUP«, »WM_SYSCOMMAND«


  WM_NCRBUTTONUP

WM_NCRBUTTONUP

nHittest = (INT) wParam;    /* hit-test code            */

pts = MAKEPOINTS(lParam);   /* position of cursor       */

The WM_NCRBUTTONUP message is posted when the user releases the right mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.

Parameters

nHittest

Value of wParam. Specifies the hit-test code returned by the DefWindowProc function as a result of processing the WM_NCHITTEST message. For more information, see the description of the WM_NCHITTEST message.

pts

Value of lParam. Specifies a POINTS structure that contains the x- and y-coordinates of the cursor. The coordinates are relative to the upper-left corner of the screen. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

If it is appropriate to do so, the system sends the WM_SYSCOMMAND message to the window.

See Also

»DefWindowProc«, »WM_NCHITTEST«, »WM_NCRBUTTONDBLCLK«, »WM_NCRBUTTONDOWN«, »WM_SYSCOMMAND«


  WM_NEXTDLGCTL

WM_NEXTDLGCTL

wCtlFocus = wParam;              /* identifies control for focus */

fHandle = (BOOL) LOWORD(lParam); /* wParam handle flag           */

The WM_NEXTDLGCTL message is sent to a dialog box procedure to set the keyboard focus to a different control in the dialog box.

Parameters

wCtlFocus

Value of wParam. If the fHandle parameter is TRUE, the wCtlFocus parameter identifies the control that receives the focus. If fHandle is FALSE, wCtlFocus is a flag that indicates whether the next or previous control with the WS_TABSTOP style receives the focus. If wCtlFocus is zero, the next control receives the focus; otherwise, the previous control with the WS_TABSTOP style receives the focus.

fHandle

Value of lParam. Contains a flag that indicates how Windows uses the wCtlFocus parameter. If the fHandle parameter is TRUE, wCtlFocus is a handle associated with the control that receives the focus; otherwise, wCtlFocus is a flag that indicates whether the next or previous control with the WS_TABSTOP style receives the focus.

Return Value

An application should return zero if it processes this message.

Comments

The effect of this message differs from that of the SetFocus function because WM_NEXTDLGCTL modifies the border around the control.

Do not use the SendMessage function to send a WM_NEXTDLGCTL message if your application will concurrently process other messages that set the focus. Use the PostMessage function instead.

See Also

»PostMessage«, »SendMessage«, »SetFocus«


  WM_PAINT

WM_PAINT

An application sends the WM_PAINT message when Windows or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function.

Parameters

This message has no parameters.

Return Value

An application should return zero if it processes this message.

Comments

The DefWindowProc function validates the update region. The function may also send the WM_NCPAINT message to the window procedure if the window frame must be painted and send the WM_ERASEBKGND message if the window background must be erased.

The system sends this message when there are no other messages in the application's message queue. DispatchMessage determines where to send the message; GetMessage determines which message to dispatch. GetMessage returns the WM_PAINT message when there are no other messages in the application's message queue, and DispatchMessage sends the message to the appropriate window procedure.

A window may receive internal paint messages as a result of calling RedrawWindow with the RDW_INTERNALPAINT flag set. In this case, the window may not have an update region. An application should call the GetUpdateRect function to determine whether the window has an update region. If GetUpdateRect returns zero, the application should not call the BeginPaint and EndPaint functions.

An application must check for any necessary internal painting by looking at its internal data structures for each WM_PAINT message, because a WM_PAINT message may have been caused by both a non-NULL update region and a call to RedrawWindow with the RDW_INTERNALPAINT flag set.

Windows sends an internal WM_PAINT message only once. After an internal WM_PAINT message is returned from the GetMessage or PeekMessage function or is sent to a window by UpdateWindow, Windows does not post or send further WM_PAINT messages until the window is invalidated or until RedrawWindow is called again with the RDW_INTERNALPAINT flag set.

See Also

»BeginPaint«, »DispatchMessage«, »EndPaint«, »GetMessage«, »PeekMessage«, »RedrawWindow«, »UpdateWindow«, »WM_ERASEBKGND«, »WM_NCPAINT«


  WM_PAINTCLIPBOARD

WM_PAINTCLIPBOARD

hwndViewer = (HWND) wParam;     /* handle of clipboard viewer   */

hglbPs = (HGLOBAL) lParam;      /* handle of PAINTSTRUCT object */

The WM_HSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and the clipboard viewer's client area needs repainting.

Parameters

hwndViewer

Value of wParam. Identifies the clipboard viewer window.

hglbPs

Value of lParam. Identifies a global DDESHARE object that contains a PAINTSTRUCT structure. The structure defines the part of the client area to paint. The PAINTSTRUCT structure has the following form:

typedef struct tagPAINTSTRUCT { /* ps */

    HDC  hdc;

    BOOL fErase;

    RECT rcPaint;

    BOOL fRestore;

    BOOL fIncUpdate;

    BYTE rgbReserved[32];

} PAINTSTRUCT;

For more information about the PaintStruct structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Comments

To determine whether the entire client area or just a portion of it needs repainting, the clipboard owner must compare the dimensions of the drawing area given in the rcpaint member of the PAINTSTRUCT structure to the dimensions given in the most recent WM_SIZECLIPBOARD message.

The clipboard owner must use the GlobalLock function to lock the memory that contains the PAINTSTRUCT structure. Before returning, the clipboard owner must unlock that memory by using the GlobalUnlock function.

See Also

»GlobalLock«, »GlobalUnlock«, »WM_SIZECLIPBOARD«


  WM_PAINTICON

WM_PAINTICON

The WM_PAINTICON message is sent to a minimized window when the icon is to be painted. A window receives this message only if a class icon is defined for the window. Otherwise, WM_PAINT is sent instead.

Parameters

This message has no parameters.

Return Value

An application should return zero if it processes this message.

Comments

The DefWindowProc function draws the class icon.

For compatibility with Windows 3.x, the wParam parameter is TRUE. However, this value has no significance.

See Also

»DefWindowProc«, »WM_ICONERASEBKGND«, »WM_PAINT«


  WM_PALETTECHANGED

WM_PALETTECHANGED

hwndPalChg = (HWND) wParam; /* handle of window that changed palette */

The WM_PALETTECHANGED message is sent to all top-level and overlapped windows after the window with the keyboard focus has realized its logical palette, thereby changing the system palette. This message enables a window without the keyboard focus that uses a color palette to realize its logical palette and update its client area.

Parameters

hwndPalChg

Value of wParam. Identifies the window that caused the system palette to change.

Comments

This message must be sent to all top-level and overlapped windows, including the one that changed the system palette. If any child windows use a color palette, this message must be passed on to them as well.

To avoid creating an infinite loop, a window that receives this message must not realize its palette, unless it determines that wParam does not contain its own window handle.

See Also

»WM_PALETTEISCHANGING«, »WM_QUERYNEWPALETTE«


  WM_PALETTEISCHANGING

WM_PALETTEISCHANGING

hwndRealize = (HWND) wParam; /* window to realize palette */

The WM_PALETTEISCHANGING message informs applications that an application is going to realize its logical palette.

Parameters

hwndRealize

Value of wParam. Identifies the window that is going to realize its logical palette.

Return Value

If an application processes this message, it should return zero.

Comments

The application changing its palette does not wait for acknowledgment of this message before changing the palette and sending the WM_PALETTECHANGED message. As a result, the palette may already be changed by the time an application receives this message.

If the application either ignores or fails to process this message and a second application realizes its palette while the first is using palette indices, there is a strong possibility that the user will see unexpected colors during subsequent drawing operations.

See Also

»WM_PALETTECHANGED«, »WM_QUERYNEWPALETTE«


  WM_PARENTNOTIFY

WM_PARENTNOTIFY

fwEvent = LOWORD(wParam);  /* event flags                         */

idChild = HIWORD(wParam);  /* identifier of child window          */

lValue = lParam;           /* child handle, or cursor coordinates */

The WM_PARENTNOTIFY message is sent to the parent of a child window when the child window is created or destroyed or when the user clicks a mouse button while the cursor is over the child window. When the child window is being created, the system sends WM_PARENTNOTIFY just before the CreateWindow or CreateWindowEx function that creates the window returns. When the child window is being destroyed, Windows sends the message before any processing to destroy the window takes place.

Parameters

fwEvent

Value of the low-order word of wParam. Specifies the event for which the parent is being notified. This parameter can be one of the following values:

Value	Meaning
WM_CREATE	The child window is being created.
WM_DESTROY	The child window is being destroyed.
WM_LBUTTONDOWN	The user has placed the cursor over the child window and has clicked the left mouse button.
WM_MBUTTONDOWN	The user has placed the cursor over the child window and has clicked the middle mouse button.
WM_RBUTTONDOWN	The user has placed the cursor over the child window and has clicked the right mouse button.
idChild

Value of the high-order word of wParam. If the fwEvent parameter is the WM_CREATE or WM_DESTROY value, idChild specifies the identifier of the child window. Otherwise, idChild is undefined.

lValue

Contains the handle of the child window, if the fwEvent parameter is the WM_CREATE or WM_DESTROY value; otherwise, lValue contains the x- and y-coordinates of the cursor. The x-coordinate is in the low-order word and the y-coordinate is in the high-order word.

Return Value

If an application processes this message, it should return zero.

Comments

This message is also sent to all ancestor windows of the child window, including the top-level window.

All child windows, except those that have the WS_EX_NOPARENTNOTIFY extended window style, send this message to their parent windows. By default, child windows in a dialog box have the WS_EX_NOPARENTNOTIFY style, unless the CreateWindowEx function is called to create the child window without this style.

See Also

»CreateWindow«, »CreateWindowEx«, »WM_CREATE«, »WM_DESTROY«, »WM_LBUTTONDOWN«, »WM_MBUTTONDOWN«, »WM_RBUTTONDOWN«


  WM_PASTE

WM_PASTE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends a WM_PASTE message to an edit control or combo box to copy the current contents of the Clipboard to the edit control at the current caret position. Data is inserted only if the Clipboard contains data in CF_TEXT format.

Parameters

This message has no parameters.

Return Value

This message does not return a value.

Comments

When sent to a combo box, the WM_PASTE message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

See Also

»WM_CLEAR«, »WM_COPY«, »WM_CUT«


  WM_POWER

WM_POWER

fwPowerEvt = wParam;    /* power-event notification message */

The WM_POWER message is sent when the system, typically a battery-powered personal computer, is about to enter the suspended mode.

Parameters

fwPowerEvt

Value of wParam. Specifies a power-event notification message. This parameter can be one of the following values:

Value	Meaning
PWR_SUSPENDREQUEST	Indicates that the system is about to enter the suspended mode.
PWR_SUSPENDRESUME	Indicates that the system is resuming operation after having entered the suspended mode normally — that is, the system sent a PWR_SUSPENDREQUEST notification message to the application before the system was suspended. An application should perform any necessary recovery actions.
PWR_CRITICALRESUME	Indicates that the system is resuming operation after entering the suspended mode without first sending a PWR_SUSPENDREQUEST notification message to the application. An application should perform any necessary recovery actions.
Return Value

The value an application should return depends on the value of the wParam parameter. If wParam is PWR_SUSPENDREQUEST, the return value is PWR_FAIL to prevent the system from entering the suspended state; otherwise, it is PWR_OK. If wParam is PWR_SUSPENDRESUME or PWR_CRITICALRESUME, the return value is zero.

Comments

This message is sent only to an application that is running on a system that conforms to the advanced power management (APM) basic input/output system (BIOS) specification. The message is sent by the power-management driver to each window returned by the EnumWindows function.

The suspended mode is the state in which the greatest amount of power savings occurs, but all operational data and parameters are preserved. Random-access memory (RAM) contents are preserved, but many devices are likely to be turned off.

See Also

»EnumWindows«


  WM_QUERYDRAGICON

WM_QUERYDRAGICON

The WM_QUERYDRAGICON message is sent to a minimized (iconic) window which is about to be dragged by the user but which does not have an icon defined for its class. An application can return the handle of an icon or cursor. The system displays this cursor or icon while the user drags the icon.

Parameters

This message has no parameters.

Return Value

An application should return the handle of a cursor or icon that Windows is to display while the user drags the icon. The cursor or icon must be compatible with the display driver's resolution. If the application returns NULL, the system displays the default cursor.

Default Action

The DefWindowProc function returns the handle of the default cursor.

Comments

When the user drags the icon of a window without a class icon, Windows replaces the icon with a default cursor. If the application requires a different cursor to be displayed during dragging, it must return the handle of the cursor or icon compatible with the display driver's resolution. If an application returns the handle of a color cursor or icon, the system converts the cursor or icon to black and white. The application can call the LoadCursor or LoadIcon function to load a cursor or icon from the resources in its executable file and to retrieve this handle.

See Also

»DefWindowProc«, »LoadCursor«, »LoadIcon«


  WM_QUERYENDSESSION

WM_QUERYENDSESSION

nSource = (UINT) wParam;    /* source of end-session request */

The WM_QUERYENDSESSION message is sent when the user chooses to end the Windows session or when an application calls the ExitWindows function. If any application returns zero, the Windows session is not ended. Windows stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.

After processing this message, Windows sends the WM_ENDSESSION message with the wParam parameter set to the results of the WM_QUERYENDSESSION message.

Parameters

nSource

Value of wParam. Specifies the source of the request to end the Windows session. This parameter is zero if the request occurred because the user clicked the Logoff or Shutdown button in the Windows NT Security dialog box. This parameter is nonzero if the user clicked the End Task button in the Task List dialog box.

Return Value

If an application can terminate conveniently, it should return TRUE; otherwise, it should return FALSE.

Default Action

The DefWindowProc function returns TRUE.

See Also

»DefWindowProc«, »ExitWindows«, »WM_ENDSESSION«


  WM_QUERYNEWPALETTE

WM_QUERYNEWPALETTE

The WM_QUERYNEWPALETTE message informs a window that it is about to receive the keyboard focus, giving the window the opportunity to realize its logical palette when it receives the focus.

Parameters

This message has no parameters.

Return Value

If the window realizes its logical palette, it must return TRUE; otherwise, it must return FALSE.

See Also

»WM_PALETTECHANGED«, »WM_PALETTEISCHANGING«


  WM_QUERYOPEN

WM_QUERYOPEN

The WM_QUERYOPEN message is sent to an icon when the user requests that the window be restored to its previous size and position.

Parameters

This message has no parameters.

Return Value

If the icon can be opened, an application that processes this message should return TRUE; otherwise, it should return FALSE to prevent the icon from being opened.

Default Action

The DefWindowProc function returns TRUE.

Comments

While processing this message, the application should not perform any action that would cause an activation or focus change (for example, creating a dialog box).

See Also

»DefWindowProc«


  WM_QUEUESYNC

WM_QUEUESYNC

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

The WM_QUEUESYNC message is sent by a computer-based training (CBT) application to separate user-input messages from other messages sent through the WH_JOURNALPLAYBACK hook procedure.

Parameters

This message has no parameters.

Return Value

A CBT application should return zero if it processes this message.

Comments

Whenever a CBT application uses the WH_JOURNALPLAYBACK hook procedure, the first and last messages are WM_QUEUESYNC. This allows the CBT application to intercept and examine user-initiated messages without doing so for events that it sends.

If an application specifies a NULL window handle, the message is posted to the message queue of the active window.


  WM_QUIT

WM_QUIT

nExitCode = (int) wParam;   /* exit code */

The WM_QUIT message indicates a request to terminate an application and is generated when the application calls the PostQuitMessage function. It causes the GetMessage function to return zero.

Parameters

nExitCode

Value of wParam. Specifies the exit code given in the PostQuitMessage function.

Return Value

This message does not have a return value, because it causes the message loop to terminate before the message is sent to the application's window procedure.

See Also

»GetMessage«, »PostQuitMessage«


  WM_RBUTTONDBLCLK

WM_RBUTTONDBLCLK

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_RBUTTONDBLCLK message is posted when the user double-clicks the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_MBUTTON	Set if the middle mouse button is down
MK_RBUTTON	Set if the right mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

Only windows that have the CS_DBLCLKS style can receive WM_RBUTTONDBLCLK messages, which Windows generates whenever the user presses, releases, and again presses the right mouse button within the system's double-click time limit. Double-clicking the right mouse button actually generates four messages: WM_RBUTTONDOWN, WM_RBUTTONUP, WM_RBUTTONDBLCLK, and WM_RBUTTONUP again.

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »GetDoubleClickTime«, »SetCapture«, »SetDoubleClickTime«, »WM_RBUTTONDOWN«, »WM_RBUTTONUP«


  WM_RBUTTONDOWN

WM_RBUTTONDOWN

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_RBUTTONDOWN message is posted when the user presses the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_MBUTTON	Set if the middle mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«, »WM_RBUTTONDBLCLK«, »WM_RBUTTONUP«


  WM_RBUTTONUP

WM_RBUTTONUP

fwKeys = wParam;        /* key flags                     */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_RBUTTONUP message is posted when the user releases the right mouse button while the cursor is in the client area of a window. If the mouse is not captured, the message is posted to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.

Parameters

fwKeys

Value of wParam. Indicates whether various virtual keys are down. This parameter can be any combination of the following values:

Value	Description
MK_CONTROL	Set if the CTRL key is down
MK_LBUTTON	Set if the left mouse button is down
MK_MBUTTON	Set if the middle mouse button is down
MK_SHIFT	Set if the SHIFT key is down
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

An application can use the MAKEPOINTS macro to convert the lParam parameter to a POINTS structure.

See Also

»GetCapture«, »SetCapture«, »WM_RBUTTONDBLCLK«, »WM_RBUTTONDOWN«


  WM_RENDERALLFORMATS

WM_RENDERALLFORMATS

The WM_RENDERALLFORMATS message is sent to the clipboard owner before it is destroyed, if the clipboard owner has delayed rendering one or more clipboard formats. For the contents of the clipboard to remain available to other applications, the clipboard owner must render data in all the formats it is capable of generating, and place the data on the clipboard by calling the SetClipboardData function.

Parameters

This message has no parameters.

Return Value

If an application processes this message, it should return zero.

Comments

When responding to a WM_RENDERFORMAT or WM_RENDERALLFORMATS message, the clipboard owner must not open the clipboard before calling SetClipboardData.

When the application returns, the system removes any unrendered formats from the list of available clipboard formats. For information about delayed rendering, see the SetClipboardData function.

See Also

»SetClipboardData«, »WM_RENDERFORMAT«


  WM_RENDERFORMAT

WM_RENDERFORMAT

uFormat = (UINT) wParam;    /* clipboard format */

The WM_RENDERFORMAT message is sent to the clipboard owner if it has delayed rendering a specific clipboard format, and if an application has requested data in that format. The clipboard owner must render data in the specified format and place it on the clipboard by calling the SetClipboardData function.

Parameters

uFormat

Specifies the clipboard format to be rendered.

Return Value

If an application processes this message, it should return zero.

Comments

When responding to a WM_RENDERFORMAT or WM_RENDERALLFORMATS message, the clipboard owner must not open the clipboard before calling SetClipboardData.

See Also

»SetClipboardData«, »WM_RENDERALLFORMATS«


  WM_SETCURSOR

WM_SETCURSOR

hwnd = (HWND) wParam;       /* handle of window with cursor */

nHittest = LOWORD(lParam);  /* hit-test code                */

wMouseMsg = HIWORD(lParam); /* mouse-message identifier     */

The WM_SETCURSOR message is sent to a window if the mouse causes the cursor to move within a window and mouse input is not captured.

Parameters

hwnd

Value of wParam. Identifies the window that contains the cursor.

nHittest

Value of the low-order word of lParam. Specifies the hit-test code.

wMouseMsg

Value of the high-order word of lParam. Specifies the identifier of the mouse message.

Default Action

The DefWindowProc function passes the WM_SETCURSOR message to a parent window before processing. If the parent window returns TRUE, further processing is halted. Passing the message to a window's parent window gives the parent window control over the cursor's setting in a child window. The DefWindowProc function also uses this message to set the cursor to an arrow if it is not in the client area, or to the registered class cursor if it is in the client area. If the low-order word of the lParam parameter is HTERROR and the high-order word of lParam specifies that one of the mouse buttons is pressed, DefWindowProc calls the MessageBeep function.

Comments

The high-order word of lParam is zero when the window enters menu mode.

See Also

»DefWindowProc«, »MessageBeep«


  WM_SETFOCUS

WM_SETFOCUS

hwndLoseFocus = (HWND) wParam; /* handle of window losing focus */

The WM_SETFOCUS message is sent to a window after it has gained the keyboard focus.

Parameters

hwndLoseFocus

Value of wParam. Identifies the window that has lost the keyboard focus (may be NULL).

Return Value

An application should return zero if it processes this message.

Comments

To display a caret, an application should call the appropriate caret functions when it receives the WM_SETFOCUS message.

See Also

»SetFocus«, »WM_KILLFOCUS«


  WM_SETFONT

WM_SETFONT

wParam = (WPARAM) hfont;            /* handle of font */

lParam = MAKELPARAM(fRedraw, 0);    /* redraw flag    */

An application sends a WM_SETFONT message to specify the font that a control is to use when drawing text.

Parameters

hfont

Value of wParam. Identifies the font. If this parameter is NULL, the control uses the default system font to draw text.

fRedraw

Value of lParam. Specifies whether the control should be redrawn immediately upon setting the font. Setting the fRedraw parameter to TRUE causes the control to redraw itself.

Return Value

This message does not return a value.

Comments

The WM_SETFONT message applies to all controls, not just those in dialog boxes.

The best time for the owner of a dialog box control to set the font of the control is when it receives the WM_INITDIALOG message. The application should call the DeleteObject function to delete the font when it is no longer needed; for example, after it destroys the control.

The size of the control does not change as a result of receiving this message. To avoid clipping text that does not fit within the boundaries of the control, the application should correct the size of the control window before it sets the font.

When a dialog box uses the DS_SETFONT style to set the text in its controls, Windows sends the WM_SETFONT message to the dialog box procedure before it creates the controls. An application can create a dialog box that contains the DS_SETFONT style by calling any of the following functions:

•	CreateDialogIndirect

•	CreateDialogIndirectParam

•	DialogBoxIndirect

•	DialogBoxIndirectParam

See Also

»CreateDialogIndirect«, »CreateDialogIndirectParam«, »DeleteObject«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »WM_INITDIALOG«, »WM_SETFONT«, »DLGTEMPLATE«


  WM_SETHOTKEY

WM_SETHOTKEY

wParam = (WPARAM) vkey;     /* virtual-key code of hot key */

lParam = 0;                 /* not used, must be zero      */

An application sends a WM_SETHOTKEY message to a window to associate a hot key with the window. When the user presses the hot key, the system activates the window.

Parameters

vkey

Value of wParam. Specifies the virtual-key code of the hot key to associate with the window. Setting this parameter to NULL removes the hot key associated with a window.

Return Value

The return value is one of the following:

Value	Meaning
2	The function is successful, but another window already has the same hot key.
1	The function is successful and no other window has the same hot key.
0	The function is unsuccessful — the window is invalid.
−1	The function is unsuccessful — the hot key is invalid.
Comments

A hot key cannot be associated with a child window.

VK_ESCAPE, VK_SPACE, and VK_TAB are invalid hot keys.

When the user presses the hot key, the system generates a WM_SYSCOMMAND message with wParam equal to SC_HOTKEY.

A window can only have one hot key. If the window already has a hot key associated with it, the new hot key replaces the old one. If more than one window has the same hot key, the window that is activated by the hot key is random.

See Also

»RegisterHotKey«, »WM_GETHOTKEY«, »WM_SYSCOMMAND«


  WM_SETREDRAW

WM_SETREDRAW

wParam = (WPARAM) fRedraw;  /* state of redraw flag   */

lParam = 0;                 /* not used, must be zero */

An application sends the WM_SETREDRAW message to a window to allow changes in that window to be redrawn or to prevent changes in that window from being redrawn.

Parameters

fRedraw

Value of wParam. Specifies the state of the redraw flag. If this parameter is TRUE, the redraw flag is set. If the parameter is FALSE, the flag is cleared.

Return Value

An application should return zero if it processes this message.

Comments

This message sets or clears the redraw flag. If the redraw flag is cleared, the contents of the given window is not updated after each change, and the window is not repainted until the redraw flag is set. For example, an application that must add several items to a list box can clear the redraw flag, add the items, and then set the redraw flag. Finally, the application can call the InvalidateRect function to cause the list box to be repainted.

See Also

»InvalidateRect«


  WM_SETTEXT

WM_SETTEXT

wParam = 0;                     /* not used, must be zero        */

lParam = (LPARAM)(LPCTSTR)lpsz; /* address of window-text string */

An application sends a WM_SETTEXT message to set the text of a window.

Parameters

lpsz

Value of wParam. Points to a null-terminated string that is the window text.

Return Value

The return value is TRUE if the text is set. It is LB_ERRSPACE (for a list box) or CB_ERRSPACE (for a combo box) if insufficient space is available to set the text in the edit control. It is CB_ERR if this message is sent to a combo box without an edit control.

Default Action

The DefWindowProc function sets and displays the window text.

Comments

For an edit control, the text is the contents of the edit control. For a combo box, the text is the contents of the edit-control portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title.

This message does not change the current selection in the list box of a combo box. An application should use the CB_SELECTSTRING message to select the item in a list box that matches the text in the edit control.

See Also

»DefWindowProc«, »CB_SELECTSTRING«, »WM_GETTEXT«


  WM_SHOWWINDOW

WM_SHOWWINDOW

fShow = (BOOL) wParam;      /* show/hide flag */

fnStatus = (int) lParam;    /* status flag    */

The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown.

Parameters

fShow

Value of wParam. Specifies whether a window is being shown. It is TRUE if the window is being shown or FALSE if the window is being hidden.

fnStatus

Value of lParam. Specifies the status of the window being shown. The fnStatus parameter is zero if the message is sent because of a call to the ShowWindow function; otherwise, fnStatus is one of the following values:

Value	Meaning
SW_PARENTCLOSING	Window's owner window is being minimized.
SW_PARENTOPENING	Window's owner window is being restored.
Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function hides or shows the window, as specified by the message.

Comments

If a window has the WS_VISIBLE style when it is created, the window receives this message after it is created, but before it is displayed. A window also receives this message when its visibility state is changed by the ShowWindow or ShowOwnedPopups function.

The WM_SHOWWINDOW message is not sent under the following circumstances:

•	When a top-level, overlapped window is created with the WS_MAXIMIZE or WS_MINIMIZE style.

•	When the SW_SHOWNORMAL flag is specified in the call to the ShowWindow function.

See Also

»DefWindowProc«, »ShowOwnedPopups«, »ShowWindow«


  WM_SIZE

WM_SIZE

fwSizeType = wParam;      /* resizing flag                     */

nWidth = LOWORD(lParam);  /* width of client area              */

nHeight = HIWORD(lParam); /* height of client area             */

The WM_SIZE message is sent to a window after its size has changed.

Parameters

fwSizeType

Value of wParam. Specifies the type of resizing requested. This parameter can be one of the following values:

Value	Meaning
SIZE_MAXIMIZED	Window has been maximized.
SIZE_MINIMIZED	Window has been minimized.
SIZE_RESTORED	Window has been resized, but neither the SIZE_MINIMIZED nor SIZE_MAXIMIZED value applies.
SIZE_MAXHIDE	Message is sent to all pop-up windows when some other window is maximized.
SIZE_MAXSHOW	Message is sent to all pop-up windows when some other window has been restored to its former size.
nWidth

Value of the low-order word of lParam. Specifies the new width of the client area.

nHeight

Value of the high-order word of lParam. Specifies the new height of the client area.

Return Value

If an application processes this message, it should return zero.

Comments

If the SetScrollPos or MoveWindow function is called for a child window as a result of the WM_SIZE message, the bRedraw parameter should be nonzero to cause the window to be repainted.

Note that the nWidth and nHeight parameters are limited to one word. Although a window can be created with a dword height or width that is a doubleword, the WM_SIZE message cannot use values of that size.

See Also

»MoveWindow«, »SetScrollPos«


  WM_SIZECLIPBOARD

WM_SIZECLIPBOARD

hwndViewer = (HWND) wParam;  /* handle of clipboard viewer */

hglbRc = (HGLOBAL) lParam;   /* handle of RECT object      */

The WM_SIZECLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and the clipboard viewer's client area has changed size.

Parameters

hwndViewer

Value of wParam. Identifies the clipboard viewer window.

hglbRc

Value of lParam. Identifies a global memory object that contains a RECT structure. The structure specifies the new dimensions of the clipboard viewer's client area. The RECT structure has the following form:

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

For a full description of this structure, see Chapter 3, "Structures.."

Comments

When the clipboard viewer window is about to be destroyed or resized, a WM_SIZECLIPBOARD message is sent with a null rectangle (0, 0, 0, 0) as the new size. This permits the clipboard owner to free its display resources.

The clipboard owner must use the GlobalLock function to lock the memory object that contains the RECT structure. Before returning, the clipboard owner must unlock the object by using the GlobalUnlock function.

See Also

»GlobalLock«, »GlobalUnlock«


  WM_SPOOLERSTATUS

WM_SPOOLERSTATUS

fwJobStatus = wParam;       /* job-status flag          */

cJobsLeft = LOWORD(lParam); /* number of jobs remaining */

The WM_SPOOLERSTATUS message is sent from Windows Print Manager whenever a job is added to or removed from the Print Manager queue.

Parameters

fwJobStatus

Value of wParam. Specifies the SP_JOBSTATUS flag.

cJobsLeft

Value of the low-order word of lParam. Specifies the number of jobs remaining in the Print Manager queue.

Return Value

An application should return zero if it processes this message.

Comments

This message is for informational purposes only.


  WM_SYSCHAR

WM_SYSCHAR

chCharCode = (TCHAR) wParam;   /* character code */

lKeyData = lParam;             /* key data       */

The WM_SYSCHAR message is posted to the window with the keyboard focus when a WM_SYSKEYDOWN message is translated by the TranslateMessage function. It specifies the character code of a system character key — that is, a character key that is pressed while the ALT key is down.

Parameters

chCharCode

Value of wParam. Specifies the character code of the System-menu key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Meaning
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is held down while the key is pressed; otherwise, the value is 0.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31	Specifies the transition state. The value is 1 if the key is being released, or it is 0 if the key is being pressed.
Return Value

An application should return zero if it processes this message.

Comments

When the context code is zero, the message can be passed to the TranslateAccelerator function, which will handle it as though it were a standard key message instead of a system character-key message. This allows accelerator keys to be used with the active window even if the active window does not have the keyboard focus.

For enhanced 101- and 102-key keyboards, extended keys are the right ALT and CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; the PRINT SCRN key; the BREAK key; the NUMLOCK key; and the divide (/) and ENTER keys in the numeric keypad. Other keyboards may support the extended-key bit in the lKeyData parameter.

See Also

»TranslateAccelerator«, »TranslateMessage«, »WM_SYSKEYDOWN«


  WM_SYSCOLORCHANGE

WM_SYSCOLORCHANGE

The WM_SYSCOLORCHANGE message is sent to all top-level windows when a change is made to a system color setting.

Parameters

This message has no parameters.

Comments

Windows sends a WM_PAINT message to any window that is affected by a system color change.

Applications that have brushes using the existing system colors should delete those brushes and recreate them using the new system colors.

See Also

»WM_PAINT«


  WM_SYSCOMMAND

WM_SYSCOMMAND

uCmdType = wParam;      /* command value                 */

xPos = LOWORD(lParam);  /* horizontal position of cursor */

yPos = HIWORD(lParam);  /* vertical position of cursor   */

The WM_SYSCOMMAND message is sent when the user chooses a command from the System menu (also known as Control menu) or when the user chooses the Maximize button or Minimize button.

Parameters

uCmdType

Value of wParam. Specifies the type of system command requested. This parameter can be one of the following values:

Value	Meaning
SC_CLOSE	Closes the window.
SC_HOTKEY	Activates the window associated with the application-specified hot key. The low-order word of lParam identifies the window to activate.
SC_HSCROLL	Scrolls horizontally.
SC_KEYMENU	Retrieves a menu through a keystroke.
SC_MAXIMIZE (or SC_ZOOM)	Maximizes the window.
SC_MINIMIZE (or SC_ICON)	Minimizes the window.
SC_MOUSEMENU	Retrieves a menu through a mouse click.
SC_MOVE	Moves the window.
SC_NEXTWINDOW	Moves to the next window.
SC_PREVWINDOW	Moves to the previous window.
SC_RESTORE	Restores the window to its normal position and size.
SC_SCREENSAVE	Executes the screen saver application specified in the [boot] section of the SYSTEM.INI file.
SC_SIZE	Sizes the window.
SC_TASKLIST	Executes or activates Windows Task Manager.
SC_VSCROLL	Scrolls vertically.
xPos

Value of the low-order word of lParam. Specifies the x-coordinate of the cursor, in screen coordinates, if a System menu command is chosen with the mouse. Otherwise, this parameter is not used.

yPos

Value of the high-order word of lParam. Specifies the y-coordinate of the cursor, in screen coordinates, if a System menu command is chosen with the mouse. Otherwise, this parameter is not used.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function carries out the System menu request for the predefined actions specified in the preceding table.

Comments

In WM_SYSCOMMAND messages, the four low-order bits of the uCmdType parameter are used internally by Windows. To obtain the correct result when testing the value of uCmdType, an application must combine the value 0xFFF0 with the uCmdType value by using the bitwise AND operator.

The menu items in a System menu can be modified by using the GetSystemMenu, AppendMenu, InsertMenu, and ModifyMenu functions. Applications that modify the System menu must process WM_SYSCOMMAND messages.

An application can carry out any system command at any time by passing a WM_SYSCOMMAND message to the DefWindowProc function. Any WM_SYSCOMMAND messages not handled by the application must be passed to DefWindowProc. Any command values added by an application must be processed by the application and cannot be passed to DefWindowProc.

Accelerator keys that are defined to choose items from the System menu are translated into WM_SYSCOMMAND messages; all other accelerator keystrokes are translated into WM_COMMAND messages.

See Also

»AppendMenu«, »DefWindowProc«, »GetSystemMenu«, »InsertMenu«, »ModifyMenu«, »WM_COMMAND«


  WM_SYSDEADCHAR

WM_SYSDEADCHAR

chCharCode = (TCHAR) wParam;    /* character code */

lKeyData = lParam;              /* key data       */

The WM_SYSDEADCHAR message is sent to the window with the keyboard focus when a WM_SYSKEYDOWN message is translated by the TranslateMessage function. WM_SYSDEADCHAR specifies the character code of a system dead key — that is, a dead key that is pressed while holding down the ALT key.

Parameters

chCharCode

Value of wParam. Specifies the character code generated by the system dead key — that is, a dead key that is pressed while holding down the ALT key.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is held down while the key is pressed; otherwise, the value is 0.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31	Specifies the transition state. The value is 1 if the key is being released, or it is 0 if the key is being pressed.
Return Value

An application should return zero if it processes this message.

See Also

»TranslateMessage«, »WM_DEADCHAR«, »WM_SYSKEYDOWN«


  WM_SYSKEYDOWN

WM_SYSKEYDOWN

nVirtKey = (int) wParam;    /* virtual-key code */

lKeyData = lParam;          /* key data         */

The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when the user holds down the ALT key and then presses another key. It also occurs when no window currently has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the active window. The window that receives the message can distinguish between these two contexts by checking the context code in the lKeyData parameter.

Parameters

nVirtKey

Value of wParam. Specifies the virtual-key code of the key being pressed.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is down while the key is pressed; it is 0 if the WM_SYSKEYDOWN message is posted to the active window because no window has the keyboard focus.
30	Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
31	Specifies the transition state. The value is always 0 for a WM_SYSKEYDOWN message.
Return Value

An application should return zero if it processes this message.

Default Action

The DefWindowProc function examines the given key and generates a WM_SYSCOMMAND message if the key is either TAB or ENTER.

Comments

When the context code is zero, the message can be passed to the TranslateAccelerator function, which will handle it as though it were a normal key message instead of a system character-key message. This allows accelerator keys to be used with the active window even if the active window does not have the keyboard focus.

Because of automatic repeat, more than one WM_SYSKEYDOWN message may occur before a WM_SYSKEYUP message is sent. The previous key state (bit 30) can be used to determine whether the WM_SYSKEYDOWN message indicates the first down transition or a repeated down transition.

For enhanced 101- and 102-key keyboards, enhanced keys are the right ALT and CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Other keyboards may support the extended-key bit in the lParam parameter.

See Also

»DefWindowProc«, »TranslateAccelerator«, »WM_SYSCOMMAND«, »WM_SYSKEYUP«


  WM_SYSKEYUP

WM_SYSKEYUP

nVirtKey = (int) wParam;    /* virtual-key code */

lKeyData = lParam;          /* key data         */

The WM_SYSKEYUP message is posted to the window with the keyboard focus when the user releases a key that was pressed while the ALT key was held down. It also occurs when no window currently has the keyboard focus; in this case, the WM_SYSKEYUP message is sent to the active window. The window that receives the message can distinguish between these two contexts by checking the context code in the lKeyData parameter.

Parameters

nVirtKey

Value of wParam. Specifies the virtual-key code of the key being released.

lKeyData

Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table:

Value	Description
0−15	Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key. The repeat count is always one for a WM_SYSKEYUP message.
16−23	Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24	Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if it is an extended key; otherwise, it is 0.
25−28	Reserved.
29	Specifies the context code. The value is 1 if the ALT key is down while the key is released; it is 0 if the WM_SYSKEYDOWN message is posted to the active window because no window has the keyboard focus.
30	Specifies the previous key state. The value is always 1 for a WM_SYSKEYUP message.
31	Specifies the transition state. The value is always 1 for a WM_SYSKEYUP message.
Return Value

An application should return zero if it processes this message.

Default Action

The DefWindowProc function sends a WM_SYSCOMMAND message to the top-level window if the F10 key or the ALT key was released. The wParam parameter of the message is set to SC_KEYMENU.

Comments

When the context code is zero, the message can be passed to the TranslateAccelerator function, which will handle it as though it were a normal key message instead of a system character-key message. This allows accelerator keys to be used with the active window even if the active window does not have the keyboard focus.

For enhanced 101- and 102-key keyboards, extended keys are the right ALT and CTRL keys on the main section of the keyboard; the INS, DEL, HOME, END, PAGE UP, PAGE DOWN and arrow keys in the clusters to the left of the numeric keypad; and the divide (/) and ENTER keys in the numeric keypad. Other keyboards may support the extended-key bit in the lKeyData parameter.

For non-USA enhanced 102-key keyboards, the right ALT key is handled as a CTRL+ALT key. The following shows the sequence of messages that result when the user presses and releases this key:

WM_KEYDOWN	VK_CONTROL
WM_KEYDOWN	VK_MENU
WM_KEYUP	VK_CONTROL
WM_SYSKEYUP	VK_MENU
See Also

»DefWindowProc«, »TranslateAccelerator«, »WM_SYSCOMMAND«, »WM_SYSKEYDOWN«


  WM_TIMECHANGE

WM_TIMECHANGE

wParam = 0; /* not used, must be zero */

lParam = 0; /* not used, must be zero */

An application sends the WM_TIMECHANGE message to all top-level windows after changing the system time.

Parameters

This message has no parameters.

Return Value

An application should return zero if it processes this message.

Comments

An application that changes the system time should send this message to all top-level windows. To send the WM_TIMECHANGE message to all top-level windows, an application can use the SendMessage function with the hwnd parameter set to HWND_TOPMOST.

See Also

»SendMessage«


  WM_TIMER

WM_TIMER

wTimerID = wParam;            /* timer identifier          */

tmprc = (TIMERPROC *) lParam; /* address of timer callback */

The WM_TIMER message is posted to the installing thread's message queue or sent to the appropriate TimerProc callback function after each interval specified in the SetTimer function used to install a timer.

Parameters

wTimerID

Value of wParam. Specifies the timer identifier.

tmprc

Value of lParam. Points to an application-defined callback function that was passed to the SetTimer function when the timer was installed. If the tmprc parameter is not NULL, Windows passes the WM_TIMER message to the specified callback function rather than posting the message to the thread's message queue.

Return Value

An application should return zero if it processes this message.

Comments

The DispatchMessage function forwards this message when no other messages are in the thread's message queue.

See Also

»DispatchMessage«, »SetTimer«, »TimerProc«


  WM_UNDO

WM_UNDO

An application sends a WM_UNDO message to an edit control to undo the last operation. When this message is sent to an edit control, the previously deleted text is restored or the previously added text is deleted.

Parameters

This message has no parameters.

Return Value

If the message succeeds, the return value is TRUE; otherwise, it is FALSE.

See Also

»WM_CLEAR«, »WM_COPY«, »WM_CUT«, »WM_PASTE«


  WM_USER

WM_USER

The WM_USER constant is used by applications to help define private messages.

Comments

The WM_USER constant is used to distinguish between message values that are reserved for use by Windows and values that can be used by an application to send messages within a private window class. There are five ranges of message numbers:

Range	Meaning
0 through WM_USER − 1	Messages reserved for use by Windows
WM_USER through 0x7FFF	Integer messages for use by private window classes
0x8000 through 0xBFFF	Messages reserved for future use by Windows
0xC000 through 0xFFFF	String messages for use by applications
Greater than 0xFFFF	Reserved by Windows for future use
Message numbers in the first range (0 through WM_USER − 1) are defined by Windows. Values in this range that are not explicitly defined are reserved for future use by Windows.

Message numbers in the second range (WM_USER through 0x7FFF) can be defined and used by an application to send messages within a private window class. These values cannot be used to define messages that are meaningful throughout an application, because some predefined window classes already define values in this range. For example, predefined control classes such as BUTTON, EDIT, LISTBOX, and COMBOBOX may use these values. Messages in this range should not be sent to other applications unless the applications have been designed to exchange messages and to attach the same meaning to the message numbers.

Message numbers in the third range (0x8000 through 0xBFFF) are reserved for future use by Windows.

Message numbers in the fourth range (0xC000 through 0xFFFF) are defined at run time when an application calls the RegisterWindowMessage function to retrieve a message number for a string. All applications that register the same string can use the associated message number for exchanging messages. The actual message number, however, is not a constant and cannot be assumed to be the same in different Windows sessions.

Message numbers in the fifth range (greater than 0xFFFF) are reserved for future use by Windows.

See Also

»RegisterWindowMessage«


  WM_VKEYTOITEM

WM_VKEYTOITEM

vkey = LOWORD(wParam);      /* virtual-key code   */

nCaretPos = HIWORD(wParam); /* caret position     */

hwndLB = lParam;            /* handle of list box */

The WM_VKEYTOITEM message is sent by a list box with the LBS_WANTKEYBOARDINPUT style to its owner in response to a WM_KEYDOWN message.

Parameters

vkey

Value of the low-order word of wParam. Specifies the virtual-key code of the key the user pressed.

nCaretPos

Value of the high-order word of wParam. Specifies the current position of the caret.

hwndLB

Value of lParam. Identifies the list box.

Return Value

The return value specifies the action that the application performed in response to the message. A return value of −2 indicates that the application handled all aspects of selecting the item and requires no further action by the list box. A return value of −1 indicates that the list box should perform the default action in response to the keystroke. A return value of 0 or greater specifies the index of an item in the list box and indicates that the list box should perform the default action for the keystroke on the given item.

Default Action

The DefWindowProc function returns −1.

See Also

»DefWindowProc«, »WM_CHARTOITEM«, »WM_KEYDOWN«


  WM_VSCROLL

WM_VSCROLL

nScrollCode = (int) LOWORD(wParam); /* scroll bar value     */

nPos = (int) HIWORD(wParam);        /* scroll box position  */

hwndScrollBar = (HWND) lParam;      /* handle of scroll bar */

The WM_VSCROLL message is sent to a window when a scroll event occurs in the window's standard vertical scroll bar. This message is also sent to the owner of a vertical scroll bar control when a scroll event occurs in the control.

Parameters

nScrollCode

Value of the low-order word of wParam. Specifies a scroll bar value that indicates the user's scrolling request. This parameter can be one of the following values:

Value	Meaning
SB_BOTTOM	Scroll to lower right.
SB_ENDSCROLL	End scroll.
SB_LINEDOWN	Scroll one line down.
SB_LINEUP	Scroll one line up.
SB_PAGEDOWN	Scroll one page down.
SB_PAGEUP	Scroll one page up.
SB_THUMBPOSITION	Scroll to absolute position. The current position is specified by the nPos parameter.
SB_TOP	Scroll to upper left.
nPos

Value of the high-order word of wParam. Specifies the current position of the scroll box if the nScrollCode parameter is SB_THUMBPOSITION or SB_THUMBTRACK; otherwise, nPos is not used.

hwndScrollBar

Value of lParam. Identifies the control if WM_VSCROLL is sent by a scroll bar control. If WM_VSCROLL is sent by a window's standard scroll bar, hwndScrollBar is not used.

Return Value

If an application processes this message, it should return zero.

Comments

The SB_THUMBTRACK notification code is typically used by applications that provide feedback as the user drags the scroll box.

If an application scrolls the contents of the window, it must also reset the position of the scroll box by using the SetScrollPos function.

See Also

»SetScrollPos«, »WM_HSCROLL«


  WM_VSCROLLCLIPBOARD

WM_VSCROLLCLIPBOARD

hwndViewer = (HWND) wParam;         /* handle of clipboard viewer */

nScrollCode = (int) LOWORD(lParam); /* scroll bar code            */

nPos = (int) HIWORD(lParam);        /* scroll box position        */

The WM_VSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and an event occurs in the clipboard viewer's vertical scroll bar. The owner should scroll the clipboard image and update the scroll bar values.

Parameters

hwndViewer

Value of wParam. Identifies the clipboard viewer window.

nScrollCode

Value of the low-order word of lParam. Specifies a scroll bar event. This parameter can be one of the following values:

Value	Meaning
SB_BOTTOM	Scroll to lower right.
SB_ENDSCROLL	End scroll.
SB_LINEDOWN	Scroll one line down.
SB_LINEUP	Scroll one line up.
SB_PAGEDOWN	Scroll one page down.
SB_PAGEUP	Scroll one page up.
SB_THUMBPOSITION	Scroll to absolute position. The current position is specified by the nPos parameter.
SB_TOP	Scroll to upper left.
nPos

Value of the high-order word of lParam. Specifies the current position of the scroll box if the nScrlCode parameter is SB_THUMBPOSITION; otherwise, the nPos parameter is not used.

Return Value

If an application processes this message, it should return zero.

Comments

The clipboard owner can use the ScrollWindow function to scroll the image in the clipboard viewer window and invalidate the appropriate region.

See Also

»ScrollWindow«


  WM_WINDOWPOSCHANGED

WM_WINDOWPOSCHANGED

lpwp = (LPWINDOWPOS) lParam; /* points to size and position data */

The WM_WINDOWPOSCHANGED message is sent to a window whose size, position, or place in the Z order has changed as a result of a call to SetWindowPos or another window-management function.

Parameters

lpwp

Value of lParam. Points to a WINDOWPOS structure that contains information about the window's new size and position. The WINDOWPOS structure has the following form:

typedef struct tagWINDOWPOS { /* wp */

    HWND hwnd;

    HWND hwndInsertAfter;

    int  x;

    int  y;

    int  cx;

    int  cy;

    UINT flags;

} WINDOWPOS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Default Action

The DefWindowProc function sends the WM_SIZE and WM_MOVE messages to the window.

Comments

The WM_SIZE and WM_MOVE messages are not sent if an application handles the WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient to perform any move or size change processing during the WM_WINDOWPOSCHANGED message without calling DefWindowProc.

See Also

»DefWindowProc«, »EndDeferWindowPos«, »SetWindowPos«, »WINDOWPOS«, »WM_MOVE«, »WM_SIZE«, »WM_WINDOWPOSCHANGING«


  WM_WINDOWPOSCHANGING

WM_WINDOWPOSCHANGING

lpwp = (LPWINDOWPOS) lParam; /* points to size and position data */

The WM_WINDOWPOSCHANGING message is sent to a window whose size, position, or place in the Z order is about to change as a result of a call to SetWindowPos or another window-management function.

Parameters

lpwp

Value of lParam. Points to a WINDOWPOS structure that contains information about the window's new size and position. The WINDOWPOS structure has the following form:

typedef struct tagWINDOWPOS { /* wp */

    HWND hwnd;

    HWND hwndInsertAfter;

    int  x;

    int  y;

    int  cx;

    int  cy;

    UINT flags;

} WINDOWPOS;

For a full description of this structure, see Chapter 3, »Structures«.

Return Value

If an application processes this message, it should return zero.

Default Action

For a window with the WS_OVERLAPPED or WS_THICKFRAME style, the DefWindowProc function sends the WM_GETMINMAXINFO message to the window. This is done to validate the new size and position of the window and to enforce the CS_BYTEALIGNCLIENT and CS_BYTEALIGN client styles. An application can override this by not passing the WM_WINDOWPOSCHANGING message to the DefWindowProc function.

Comments

While this message is being processed, modifying any of the values in the WINDOWPOS structure affects the window's new size, position, or place in the Z order. An application can prevent changes to the window by setting or clearing the appropriate bits in the flags member of the WINDOWPOS structure.

See Also

»DefWindowProc«, »EndDeferWindowPos«, »SetWindowPos«, »WINDOWPOS«, »WM_GETMINMAXINFO«, »WM_MOVE«, »WM_SIZE«, »WM_WINDOWPOSCHANGED«


  WM_WININICHANGE

WM_WININICHANGE

wParam = 0;                             /* not used, must be zero */

lParam = (LPARAM) (LPCTSTR) pszSection; /* section-name string    */

An application sends the WM_WININICHANGE message to all top-level windows after making a change to the WIN.INI file. The SystemParametersInfo function sends the WM_WININICHANGE message after an application uses the function to change a setting in WIN.INI.

Parameters

pszSection

Value of lParam. Points to a string containing the name of the section that has changed. The string does not include the square brackets that enclose the section name.

Return Value

An application should return zero if it processes this message.

Comments

To send the WM_WININICHANGE message to all top-level windows, an application can use the SendMessage function with the hwnd parameter set to HWND_BROADCAST.

Some applications send this message with lParam set to NULL. If an application receives this message with an lParam value of NULL, it should check all sections in WIN.INI that affect the application.

Calls to functions that change WIN.INI may be mapped to the registry instead. This mapping occurs when WIN.INI and the section being changed are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
        Windows NT\CurrentVersion\IniFileMapping

The change in the storage location has no effect on the behavior of this message.

See Also

»SendMessage«, »SystemParametersInfo«, »WM_DEVMODECHANGE«


  WOM_CLOSE

This message is sent to a waveform output callback function when a waveform output device is closed. The device handle is no longer valid once this message has been sent.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_WOM_CLOSE«


  WOM_DONE

This message is sent to a waveform output callback function when the specified output buffer is being returned to the application. Buffers are returned to the application when they have been played, or as the result of a call to waveOutReset.

Parameters

DWORD dwParam1

Points to a WAVEHDR structure identifying the buffer. The WAVEHDR structure has the following form:

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

For a full description of this structure, see Chapter 3, »Structures«.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_WOM_DONE«


  WOM_OPEN

This message is sent to a waveform output callback function when a waveform output device is opened.

Parameters

DWORD dwParam1

Currently unused.

DWORD dwParam2

Currently unused.

Return Value

None.

See Also

»MM_WOM_OPEN«


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Structures
  Chapter 3  Structures


  ABC

typedef struct _ABC { /* abc */

    int     abcA;

    UINT    abcB;

    int     abcC;

} ABC;

The ABC structure contains the width of a character in a TrueType® font.

Members

abcA

Specifies the "A" spacing of the character. The "A" spacing is the distance to add to the current position before drawing the character glyph.

abcB

Specifies the "B" spacing of the character. The "B" spacing is the width of the drawn portion of the character glyph.

abcC

Specifies the "C" spacing of the character. The "C" spacing is the distance to add to the current position to provide white space to the right of the character glyph.

Comments

The total width of a character is the summation of the "A," "B," and "C" spaces. Either the "A" or the "C" space can be negative to indicate underhangs or overhangs.

See Also

»GetCharABCWidths«


  ABCFLOAT

typedef struct _ABCFLOAT { /* abcf */

    FLOAT   abcfA;

    FLOAT   abcfB;

    FLOAT   abcfC;

} ABCFLOAT;

The ABCFLOAT structure contains the A, B, and C widths of a font character.

Members

abcfA

Specifies the "A" spacing of the character. The "A" spacing is the distance to add to the current position before drawing the character glyph.

abcfB

Specifies the "B" spacing of the character. The "B" spacing is the width of the drawn portion of the character glyph.

abcfC

Specifies the "C" spacing of the character. The "C" spacing is the distance to add to the current position to provide white space to the right of the character glyph.

Comments

The A, B, and C widths are measured along the base line of the font.

The character increment (total width) of a character is the sum of the "A," "B," and "C" spaces. Either the "A" or the "C" space can be negative to indicate underhangs or overhangs.

See Also

»GetCharABCWidthsFloat«


  ACCEL

typedef struct tagACCEL { /* accl */

    BYTE   fVirt;

    WORD   key;

    WORD   cmd;

} ACCEL;

The ACCEL structure defines an accelerator key used in an accelerator table.

Members

fVirt

Specifies the accelerator flags. This member can be a combination of the following values:

Value	Meaning
FALT	The ALT key must be held down when the accelerator key is pressed.
FCONTROL	The CTRL key must be held down when the accelerator key is pressed.
FNOINVERT	Specifies that no top-level menu item is highlighted when the accelerator is used. If this flag is not specified, a top-level menu item will be highlighted, if possible, when the accelerator is used.
FSHIFT	The SHIFT key must be held down when the accelerator key is pressed.
FVIRTKEY	The key member specifies a virtual-key code. If this flag is not specified, key is assumed to specify an ASCII character code.
key

Specifies the accelerator key. This member can be either a virtual-key code or an ASCII character code.

cmd

Specifies the accelerator identifier. This value is placed in the low-order word of the wParam parameter of the WM_COMMAND or WM_SYSCOMMAND message when the accelerator is pressed.

See Also

»WM_COMMAND«, »WM_SYSCOMMAND«


  ACCESS_ALLOWED_ACE

typedef struct _ACCESS_ALLOWED_ACE { /* aaace */

    ACE_HEADER Header;

    ACCESS_MASK Mask;

    DWORD SidStart;

} ACCESS_ALLOWED_ACE;

The ACCESS_ALLOWED_ACE structure defines an access-control entry (ACE) for the discretionary access-control list (ACL) that controls access to an object. An access-allowed ACE allows access to an object for a specific subject identified by a security identifier (SID).

Members

Header

Specifies an ACE_HEADER structure.

Mask

Specifies an ACCESS_MASK structure that specifies the access rights granted by this ACE.

SidStart

Specifies an SID. The access rights specified by the Mask member are granted to any subject possessing an enabled SID matching this field.

Comments

ACE structures must be aligned on doubleword boundaries. All Windows memory-management functions return doubleword-aligned handles to memory.

See Also

»AddAccessAllowedAce«, »AddAce«, »GetAce«, »ACCESS_DENIED_ACE«, »ACCESS_MASK«, »ACE_HEADER«, »ACL«, »SID«, »SYSTEM_ALARM_ACE«, »SYSTEM_AUDIT_ACE«


  ACCESS_DENIED_ACE

typedef struct _ACCESS_DENIED_ACE { /* adace */

    ACE_HEADER  Header;

    ACCESS_MASK Mask;

    DWORD       SidStart;

} ACCESS_DENIED_ACE;

The ACCESS_DENIED_ACE structure defines an access-control entry (ACE) for the discretionary access-control list (ACL) controlling access to an object. An access-denied ACE denies access to an object for a specific subject identified by a security identifier (SID).

Members

Header

Specifies an ACE_HEADER structure.

Mask

Specifies an ACCESS_MASK structure specifying the access rights explicitly denied by this ACE.

SidStart

Specifies an SID. The access rights specified by the Mask member are denied to any subject possessing an enabled SID matching this field.

Comments

ACE structures must be aligned on doubleword boundaries. All Windows memory-management functions return doubleword-aligned handles to memory.

See Also

»AddAccessDeniedAce«, »ACCESS_ALLOWED_ACE«, »ACCESS_MASK«, »ACE_HEADER«, »ACL«, »SID«, »SYSTEM_ALARM_ACE«, »SYSTEM_AUDIT_ACE«


  ACCESS_MASK

typedef DWORD ACCESS_MASK;

The ACCESS_MASK structure is one doubleword value containing standard, specific, and generic rights. These rights are used in access-control entries (ACEs) and are the primary means of specifying the requested or granted access to an object.

The bits in this value are allocated as follows:

Bits	Meaning
0 through 15	Specific rights. Contain the access mask specific to the object type associated with the mask.
16 through 23	Standard rights. Contains the object's standard access rights and can be a combination of the following predefined flags:
Bit	Flag	Meaning
16	DELETE	Delete access
17	READ_CONTROL	Read access to the owner, group, and discretionary access-control list (ACL) of the security descriptor
18	WRITE_DAC	Write access to the discretionary access-control list (ACL)
19	WRITE_OWNER	Write access to owner
20	SYNCHRONIZE	Synchronize access
24	Access system security (ACCESS_SYSTEM_SECURITY). This flag is not a typical access type. It is used to indicate access to a system ACL. This type of access requires the calling process to have a specific privilege.
25	Maximum allowed (MAXIMUM_ALLOWED)
26 through 27	Reserved
28	Generic all (GENERIC_ALL)
29	Generic execute (GENERIC_EXECUTE)
30	Generic write (GENERIC_WRITE)
31	Generic read (GENERIC_READ)
The following constants represent the specific and standard access rights:

#define SPECIFIC_RIGHTS_ALL           0x0000FFFF

#define STANDARD_RIGHTS_REQUIRED      0x000F0000

#define STANDARD_RIGHTS_ALL           0x001F0000

See Also

»GENERIC_MAPPING«


  ACE

An ACE is an access-control entry (ACE) in an access-control list (ACL).

Following are the currently defined ACE types:

ACE type	Structure	ACL Type
Access allowed	ACCESS_ALLOWED_ACE	Discretionary
Access denied	ACCESS_DENIED_ACE	Discretionary
System alarm	SYSTEM_ALARM_ACE	System
System audit	SYSTEM_AUDIT_ACE	System
System-alarm ACEs are not supported in the current version of Windows NT.

Comments

An ACL contains a list of ACEs. An ACE defines access to an object for a specific user or group or defines the types of access that generate system-administration messages or alarms for a specific user or group. The user or group is identified by a security identifier (SID).

Each ACE starts with an ACE_HEADER structure. The format of the data following the header varies according to the ACE type specified in the header.

See Also

»AddAce«, »ACCESS_ALLOWED_ACE«, »ACCESS_DENIED_ACE«, »ACL«, »SYSTEM_ALARM_ACE«, »SYSTEM_AUDIT_ACE«


  ACE_HEADER

typedef struct _ACE_HEADER { /* acehdr */

    BYTE AceType;

    BYTE AceFlags;

    WORD AceSize;

} ACE_HEADER;

The ACE_HEADER structure describes the type and size of an access-control entry (ACE).

Members

AceType

Specifies the ACE type. This member can be one of the following values:

Value	ACE type
ACCESS_ALLOWED_ACE_TYPE	Access-allowed (defined by the ACCESS_ALLOWED_ACE structure)
ACCESS_DENIED_ACE_TYPE	Access-denied (defined by the ACCESS_DENIED_ACE structure)
SYSTEM_AUDIT_ACE_TYPE	System-audit (defined by the SYSTEM_AUDIT_ACE structure)
System-alarm ACEs are not supported in the current version of Windows NT. Applications cannot use the SYSTEM_ALARM_ACE_TYPE value or SYSTEM_ALARM_ACE structure.

AceFlags

Specifies a set of ACE type-specific control flags. This member can be a combination of the following values:

Value	Meaning
CONTAINER_INHERIT_ACE
	The ACE is inherited by container objects, such as directories.
INHERIT_ONLY_ACE
	The ACE does not apply to the container object, but to objects contained by it.
NO_PROPAGATE_INHERIT_ACE
	The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
	The ACE is inherited by noncontainer objects, such as files created within the container object to which the ACE is assigned.
FAILED_ACCESS_ACE_FLAG
	Used with system-audit and system-alarm ACEs to indicate a message is generated for failed access attempts.
SUCCESSFUL_ACCESS_ACE_FLAG
	Used with system-audit and system-alarm ACEs to indicate a message is generated for successful access attempts.
AceSize

Specifies the size, in bytes, of the ACE.

Comments

An ACE defines access to an object for a specific user or group or defines the types of access that generate system-administration messages or alarms for a specific user or group. The user or group is identified by a security identifier (SID).

See Also

»ACCESS_ALLOWED_ACE«, »ACCESS_DENIED_ACE«, »ACL«, »SYSTEM_ALARM_ACE«, »SYSTEM_AUDIT_ACE«


  ACL

typedef struct _ACL { /* acl */

    BYTE AclRevision;

    BYTE Sbz1;

    WORD AclSize;

    WORD AceCount;

    WORD Sbz2;

} ACL;

The ACL structure is the header of an access-control list (ACL). A complete ACL consists of an ACL structure followed by an ordered list of zero or more access-control entries (ACEs).

Members

AclRevision

Specifies the ACL's revision level. This value should be ACL_REVISION. All ACEs in an ACL must be at the same revision level.

Sbz1

Specifies a zero byte of padding that aligns the AclRevision member on a 16-bit boundary.

AclSize

Specifies the size, in bytes, of the ACL. This value includes both the ACL structure and all the ACEs.

AceCount

Specifies the number of ACEs stored in the ACL.

Sbz2

Specifies two zero bytes of padding that align the ACL structure on a 32-bit boundary.

Comments

An ACL includes a sequential list of zero or more ACEs. The individual ACEs in an ACL are numbered from 0 to n, where n+1 is the number of ACEs in the ACL. When editing an ACL, an application refers to an ACE within the ACL by its index.

There are two types of ACL: discretionary and system.

A discretionary ACL is controlled by the owner of an object or anyone granted WRITE_DAC access to the object. It specifies the access particular users and groups can have to an object. For example, the owner of a file can use a discretionary ACL to control which users and groups can and cannot have access to the file.

An object may also have system-level security information associated with it, in the form of a system ACL controlled by a system administrator. A system ACL can allow the system administrator to audit any attempts to gain access to an object.

Three ACE structures are currently defined:

ACE structure	Description
ACCESS_ALLOWED_ACE	Grants specified rights to a user or group. This ACE is stored in a discretionary ACL.
ACCESS_DENIED_ACE	Denies specified rights to a user or group. This ACE is stored in a discretionary ACL.
SYSTEM_AUDIT_ACE	Specifies what types of access will cause system-level audits. This ACE is stored in a system ACL.
A fourth ACE structure, SYSTEM_ALARM_ACE, is not currently supported by Windows NT.

The ACL structure is to be treated as though it were opaque and applications are not to attempt to work with its members directly. To ensure that ACLs are semantically correct, applications can use the functions listed in the SeeAlso section to create and manipulate ACLs.

Each ACL and ACE structure begins on a doubleword boundary.

See Also

»AddAce«, »DeleteAce«, »GetAclInformation«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorSacl«, »InitializeAcl«, »IsValidAcl«, »SetAclInformation«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorSacl«


  ACL_INFORMATION_CLASS

typedef enum tagACL_INFORMATION_CLASS { /* aclic */

    AclRevisionInformation = 1,

    AclSizeInformation

} ACL_INFORMATION_CLASS;

The ACL_INFORMATION_CLASS enumerated type indicates the type of information being assigned to or retrieved from an access-control list (ACL).

See Also

»GetAclInformation«, »SetAclInformation«, »ACL«, »ACL_REVISION_INFORMATION«, »ACL_SIZE_INFORMATION«


  ACL_REVISION_INFORMATION

typedef struct _ACL_REVISION_INFORMATION {

    DWORD   AclRevision;

} ACL_REVISION_INFORMATION;

The ACL_REVISION_INFORMATION structure contains revision information about an ACL structure.

Members

AclRevision

Specifies a revision number. The current revision number is ACL_REVISION.

See Also

»GetAclInformation«, »SetAclInformation«, ACL, »ACL_INFORMATION_CLASS«, »ACL_SIZE_INFORMATION«


  ACL_SIZE_INFORMATION

typedef struct _ACL_SIZE_INFORMATION {

    DWORD   AceCount;

    DWORD   AclBytesInUse;

    DWORD   AclBytesFree;

} ACL_SIZE_INFORMATION;

The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.

Members

AceCount

Specifies the number of access-control entries (ACEs) in the access-control list (ACL).

AclBytesInUse

Specifies the number of bytes in the ACL actually used to store the ACEs and ACL structure. This may be less than the total number of bytes allocated to the ACL.

AclBytesFree

Specifies the number of unused bytes in the ACL.

See Also

»GetAclInformation«, »SetAclInformation«, »ACL«, »ACL_INFORMATION_CLASS«, »ACL_REVISION_INFORMATION«


  ACTION_HEADER

typedef struct _ACTION_HEADER {

    ULONG   transport_id;

    USHORT  action_code;

    USHORT  reserved;

} ACTION_HEADER;

The ACTION_HEADER structure contains information about an action. This action is an extension to the standard transport interface.

Members

transport_id

Specifies the transport provider. This member can be used to check the validity of the request by the transport.

This member is always a four-character string. All strings starting with the letter M are reserved, as shown in the following example:

String	Meaning
M000	All transports
MNBF	NBF
MABF	AsyBEUI
MXNS	XNS, etc.
action_code

Specifies the action.

reserved

Reserved.

Comments

The scope of the action is determined by the ncb_lsn and ncb_num members of the NCB structure, as follows:

	ncb_lsn = 0	ncb_lsn != 0
ncb_num = 0	Action applies to control channel associated with the valid LANadapter.	Action applies to connection identifier associated with the valid local session number.
ncb_num != 0	Action applies to address associated with the valid LAN adapter.	Illegal combination.
See Also

»NCB«


  ADAPTER_STATUS

typedef struct _ADAPTER_STATUS { /* adptst */

    UCHAR   adapter_address[6];

    UCHAR   rev_major;

    UCHAR   reserved0;

    UCHAR   adapter_type;

    UCHAR   rev_minor;

    WORD    duration;

    WORD    frmr_recv;

    WORD    frmr_xmit;

    WORD    iframe_recv_err;

    WORD    xmit_aborts;

    DWORD   xmit_success;

    DWORD   recv_success;

    WORD    iframe_xmit_err;

    WORD    recv_buff_unavail;

    WORD    t1_timeouts;

    WORD    ti_timeouts;

    DWORD   reserved1;

    WORD    free_ncbs;

    WORD    max_cfg_ncbs;

    WORD    max_ncbs;

    WORD    xmit_buf_unavail;

    WORD    max_dgram_size;

    WORD    pending_sess;

    WORD    max_cfg_sess;

    WORD    max_sess;

    WORD    max_sess_pkt_size;

    WORD    name_count;

} ADAPTER_STATUS;

The ADAPTER_STATUS structure contains information about a network adapter. This structure is pointed to by the ncb_buffer member of the NCB structure. ADAPTER_STATUS is followed by as many NAME_BUFFER structures as are required to describe the network adapters on the system.

Members

adapter_address

Specifies the adapter's encoded address.

rev_major

Specifies the major software-release level. This value is 3 for IBM NetBIOS 3.x.

reserved0

Reserved. This value is always 0.

adapter_type

Specifies the adapter type. This value is 0xFF for a Token Ring adapter or 0xFE for an Ethernet adapter.

rev_minor

Specifies the minor software-release level. This value is 0 for IBM NetBIOS x.0.

duration

Specifies the duration of the reporting period, in minutes.

frmr_recv

Specifies the number of FRMR frames received.

frmr_xmit

Specifies the number of FRMR frames transmitted.

iframe_recv_err

Specifies the number of I frames received in error.

xmit_aborts

Specifies the number of aborted transmissions.

xmit_success

Specifies the number of successfully transmitted packets.

recv_success

Specifies the number of successfully received packets.

iframe_xmit_err

Specifies the number of I frames transmitted in error.

recv_buff_unavail

Specifies the number of times a buffer was not available to service a request from a remote computer.

ti_timeouts

Specifies the number of times the DLC T1 timer expired.

reserved1

Reserved. This value is always 0.

free_ncbs

Specifies the current number of free network-control blocks.

max_cfg_ncbs

Undefined for IBM NetBIOS 3.0.

max_ncbs

Undefined for IBM NetBIOS 3.0.

xmit_buf_unavail

Undefined for IBM NetBIOS 3.0.

max_dgram_size

Specifies the maximum size of a datagram packet. This value is always at least 512 bytes.

pending_sess

Specifies the number of pending sessions.

max_cfg_sess

Specifies the configured maximum pending sessions.

max_sess

Undefined for IBM NetBIOS 3.0.

max_sess_pkt_size

Specifies the maximum size of a session data packet.

name_count

Specifies the number of names in the local names table.

See Also

»NAME_BUFFER«,»NCB«


  ADDJOB_INFO_1

typedef struct _ADDJOB_INFO_1 { /* aji1 */

    LPTSTR  Path;

    DWORD   JobId;

} ADDJOB_INFO_1;

The ADDJOB_INFO_1 structure identifies a print job as well as the directory and file in which an application can store that job.

Members

Path

Points to a null-terminated string that contains the path and filename that the application can use to store the print job.

JobId

Identifies the print job.

See Also

»AddJob«


  AUXCAPS

typedef struct auxcaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    WORD  wTechnology;

    DWORD  dwSupport;

} AUXCAPS;

The AUXCAPS structure describes the capabilities of an auxiliary output device.

Members

wMid

Specifies a manufacturer identifier for the device driver for the auxiliary audio device. Manufacturer identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

wPid

Specifies a product identifier for the auxiliary audio device. Product identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

vDriverVersion

Specifies the version number of the device driver for the auxiliary audio device. The high-order byte is the major version number, and the low-order byte is the minor version number.

szPname

Specifies the product name in a null-terminated string.

wTechnology

Specifies the type of the auxiliary audio output. This member can be one of the following values:

Value	Meaning
AUXCAPS_AUXIN	Audio output from auxiliary input jacks
AUXCAPS_CDAUDIO	Audio output from an internal CD-ROM drive
dwSupport

Specifies optional functionality supported by the auxiliary audio device. This member can be one or both of the following values:

Value	Meaning
AUXCAPS_LRVOLUME	Supports separate left and right volume control.
AUXCAPS_VOLUME	Supports volume control.
Comments

If a device supports volume changes, the AUXCAPS_VOLUME flag is set for the dwSupport member. If a device supports separate volume changes on the left and right channels, both the AUXCAPS_VOLUME and the AUXCAPS_LRVOLUME flags are set for this member.

See Also

»auxGetDevCaps«


  BITMAP

typedef struct tagBITMAP {  /* bm */

   LONG   bmType;

   LONG   bmWidth;

   LONG   bmHeight;

   LONG   bmWidthBytes;

   WORD   bmPlanes;

   WORD   bmBitsPixel;

   LPVOID bmBits;

} BITMAP;

The BITMAP structure defines the type, width, height, color format, and bit values of a bitmap.

Members

bmType

Specifies the bitmap type. This member must be zero.

bmWidth

Specifies the width, in pixels, of the bitmap. The width must be greater than zero.

bmHeight

Specifies the height, in pixels, of the bitmap. The height must be greater than zero.

bmWidthBytes

Specifies the number of bytes in each scan line. This value must be divisible by 2, because Windows assumes that the bit values of a bitmap form an array that is word aligned.

bmPlanes

Specifies the count of color planes.

bmBitsPixel

Specifies the number of bits required to indicate the color of a pixel.

bmBits

Points to the location of the bit values for the bitmap. The bmBits member must be a long pointer to an array of character (1-byte) values.

Comments

The currently used bitmap formats are monochrome and color. The monochrome bitmap uses a one-bit, one-plane format. Each scan is a multiple of 32 bits.

Scans are organized as follows for a monochrome bitmap of height n:

    Scan 0

    Scan 1

    .

    .

    .

    Scan n-2

    Scan n-1

The pixels on a monochrome device are either black or white. If the corresponding bit in the bitmap is 1, the pixel is set to the foreground color; if the corresponding bit in the bitmap is zero, the pixel is set to the background color.

All devices that have the RC_BITBLT device capability support bitmaps. For more information, see the »GetDeviceCaps« function.

Each device has a unique color format. In order to transfer a bitmap from one device to another, use the GetDIBits and SetDIBits functions.

See Also

»CreateBitmapIndirect«, »GetDeviceCaps«, »GetDIBits«, »GetObject«, »SetDIBits«


  BITMAPCOREHEADER

typedef struct tagBITMAPCOREHEADER { /* bmch */

        DWORD   bcSize;

        WORD    bcWidth;

        WORD    bcHeight;

        WORD    bcPlanes;

        WORD    bcBitCount;

} BITMAPCOREHEADER;

The BITMAPCOREHEADER structure contains information about the dimensions and color format of a device-independent bitmap (DIB).

Members

bcSize

Specifies the number of bytes required by the structure.

bcWidth

Specifies the width of the bitmap, in pixels.

bcHeight

Specifies the height of the bitmap, in pixels.

bcPlanes

Specifies the number of planes for the target device. This value must be 1.

bcBitCount

Specifies the number of bits per pixel. This value must be 1, 4, 8, or 24.

Comments

The BITMAPCOREINFO structure combines the BITMAPCOREHEADER structure and a color table to provide a complete definition of the dimensions and colors of a DIB. For more information about specifying a device-independent bitmap, see the description of the »BITMAPCOREINFO« structure.

An application should use the information stored in the bcSize member to locate the color table in a BITMAPCOREINFO structure, using a method such as the following:

pColor = ((LPBYTE) pBitmapCoreInfo +

        (WORD) (pBitmapCoreInfo -> bcSize))

See Also

»BITMAPCOREINFO«


  BITMAPCOREINFO

typedef struct _BITMAPCOREINFO {    /* bmci */

        BITMAPCOREHEADER  bmciHeader;

        RGBTRIPLE         bmciColors[1];

} BITMAPCOREINFO;

The BITMAPCOREINFO structure defines the dimensions and color information for a device-independent bitmap (DIB).

Members

bmciHeader

Specifies a BITMAPCOREHEADER structure that contains information about the dimensions and color format of a DIB.

bmciColors

Specifies an array of RGBTRIPLE structures that define the colors in the bitmap.

Comments

A DIB consists of two parts: a BITMAPCOREINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG boundary. The origin of the bitmap is the lower left corner.

The bcBitCount member of the BITMAPCOREHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member can be one of the following values:

Value	Meaning
1	The bitmap is monochrome, and the bmciColors member contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmciColors table; if the bit is set, the pixel has the color of the second entry in the table.
4	The bitmap has a maximum of 16 colors, and the bmciColors member contains up to 16 entries. Each pixel in the bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color in the sixteenth table entry.
8	The bitmap has a maximum of 256 colors, and the bmciColors member contains up to 256 entries. In this case, each byte in the array represents a single pixel.
24	The bitmap has a maximum of 224 colors, and the bmciColors member is NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of red, green, and blue, respectively, for a pixel.
The colors in the bmciColors table should appear in order of importance.

Alternatively, for functions that use DIBs, the bmciColors member can be an array of 16-bit unsigned integers that specify indices into the currently realized logical palette, instead of explicit RGB values. In this case, an application using the bitmap must call the DIB functions (CreateDIBitmap, CreateDIBPatternBrush, and CreateDIBSection) with the iUsage parameter set to DIB_PAL_COLORS.

Note  The bmciColors member should not contain palette indices if the bitmap is to be stored in a file or transferred to another application. Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values.

See Also

»BITMAPCOREHEADER«, »RGBTRIPLE«


  BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER { /* bmfh */

        WORD    bfType;

        DWORD   bfSize;

        WORD    bfReserved1;

        WORD    bfReserved2;

        DWORD   bfOffBits;

} BITMAPFILEHEADER;

The BITMAPFILEHEADER data structure contains information about the type, size, and layout of a file that contains a device-independent bitmap (DIB).

Members

bfType

Specifies the file type. It must be BM.

bfSize

Specifies the size of the file, in a doubleword value. This value can be obtained by dividing the length of the file, in bytes, by 4.

bfReserved1

Reserved; must be zero.

bfReserved2

Reserved; must be zero.

bfOffBits

Specifies the offset, in bytes, from the BITMAPFILEHEADER to the bitmap bits.

Comments

A BITMAPINFO or BITMAPCOREINFO structure immediately follows the BITMAPFILEHEADER structure in the DIB file.

See Also

»BITMAPCOREINFO«, »BITMAPINFO«


  BITMAPINFO

typedef struct tagBITMAPINFO { /* bmi */

   BITMAPINFOHEADER bmiHeader;

   RGBQUAD          bmiColors[1];

} BITMAPINFO;

The BITMAPINFO structure defines the dimensions and color information for a Windows device-independent bitmap (DIB).

Members

bmiHeader

Specifies a BITMAPINFOHEADER structure that contains information about the dimensions and color format of a device-independent bitmap.

bmiColors

Specifies an array of RGBQUAD or DWORD data types that define the colors in the bitmap.

Comments

A device-independent bitmap consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeroes to end on a LONG boundary. If height is positive the origin of the bitmap is the lower-left corner. If the height is negative then the origin is the upper-left corner.

The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member can be one of the following values:

Value	Meaning
1	The bitmap is monochrome, and the bmiColors member contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if the bit is set, the pixel has the color of the second entry in the table.
4	The bitmap has a maximum of 16 colors, and the bmiColors member contains up to 16 entries. Each pixel in the bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color in the sixteenth table entry.
8	The bitmap has a maximum of 256 colors, and the bmiColors member contains up to 256 entries. In this case, each byte in the array represents a single pixel.
16	The bitmap has a maximum of 2^16 colors. The biCompression member of the BITMAPINFOHEADER must be BI_BITFIELDS. The bmiColors member contains 3 DWORD color masks which specify the red, green, and blue components, respectively, of each pixel. Bits set in the DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not have to be used. Each WORD in the array represents a single pixel.
24	The bitmap has a maximum of 224 colors, and the bmiColors member is NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green, and red, respectively, of a pixel.
32	The bitmap has a maximum of 2^32 colors. The biCompression member of the BITMAPINFOHEADER must be BI_BITFIELDS. The bmiColors member contains 3 DWORD color masks which specify the red, green, and blue components, respectively, of each pixel. Bits set in the DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not have to be used. Each DWORD in the array represents a single pixel.
The biClrUsed member of the BITMAPINFOHEADER structure specifies the number of color indices in the color table that are actually used by the bitmap. If the biClrUsed member is set to zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member.

The colors in the bmiColors table should appear in order of importance.

Alternatively, for functions that use DIBs, the bmiColors member can be an array of 16-bit unsigned integers that specify indices into the currently realized logical palette, instead of explicit RGB values. In this case, an application using the bitmap must call the DIB functions (CreateDIBitmap, CreateDIBPatternBrush, and CreateDIBSection) with the iUsage parameter set to DIB_PAL_COLORS.

If the bitmap is a packed bitmap (that is, a bitmap in which the bitmap array immediately follows the BITMAPINFO header and which is referenced by a single pointer), the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so the DIB bitmap array starts on a DWORD boundary.

Note  The bmiColors member should not contain palette indices if the bitmap is to be stored in a file or transferred to another application. Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values.

See Also

»BITMAPINFOHEADER«, »RGBQUAD«


  BITMAPINFOHEADER

typedef struct tagBITMAPINFOHEADER{ /* bmih */

   DWORD  biSize;

   LONG   biWidth;

   LONG   biHeight;

   WORD   biPlanes;

   WORD   biBitCount

   DWORD  biCompression;

   DWORD  biSizeImage;

   LONG   biXPelsPerMeter;

   LONG   biYPelsPerMeter;

   DWORD  biClrUsed;

   DWORD  biClrImportant;

} BITMAPINFOHEADER;

The BITMAPINFOHEADER structure contains information about the dimensions and color format of a device-independent bitmap (DIB).

Members

biSize

Specifies the number of bytes required by the structure.

biWidth

Specifies the width of the bitmap, in pixels.

biHeight

Specifies the height of the bitmap, in pixels. If biHeight is negative then the origin of the bitmap is the upper-left hand corner and the height is the absolute value of biHeight.

biPlanes

Specifies the number of planes for the target device. This value must be set to 1.

biBitCount

Specifies the number of bits per pixel. This value must be 1, 4, 8, 16, 24, or 32.

biCompression

Specifies the type of compression for a compressed bitmap. It can be one of the following values:

Value	Description
BI_RGB	An uncompressed format.
BI_RLE8	A run-length encoded format for bitmaps with 8 bits per pixel. The compression format is a 2-byte format consisting of a count byte followed by a byte containing a color index. For more information, see the following Comments section.
BI_RLE4	A run-length encoded format for bitmaps with 4 bits per pixel. The compression format is a 2-byte format consisting of a count byte followed by two word-length color indices. For more information, see the following Comments section.
BI_BITFIELDS	Specifies the bitmap is not compressed and the color table consists of 3 DWORD color masks which specify the red, green, and blue components, respectively, of each pixel. This is valid when used with 16 and 32 bits per pixel bitmaps.
biSizeImage

Specifies the size, in bytes, of the image. This may be set to 0 if the bitmap is not compressed.

biXPelsPerMeter

Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap. An application can use this value to select a bitmap from a resource group that best matches the characteristics of the current device.

biYPelsPerMeter

Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap.

biClrUsed

Specifies the number of color indices in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression.

If biClrUsed is nonzero and the biBitCount member is less than 16, the biClrUsed member specifies the actual number of colors the graphics engine or device driver accesses. If biBitCount is 16 or greater, then biClrUsed member specifies the size of the color table used to optimize performance of Windows color palettes. For biBitCount equal to 16 or 32 the optimal color palette starts immediately following the 3 DWORD masks.

If the bitmap is a packed bitmap (that is, a bitmap in which the bitmap array immediately follows the BITMAPINFO header and which is referenced by a single pointer), the biClrUsed member must be 0 or the actual size of the color table.

biClrImportant

Specifies the number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important.

Comments

The BITMAPINFO data structure combines the BITMAPINFOHEADER structure and a color table to provide a complete definition of the dimensions and colors of a Windows DIB. For more information about Windows DIBs, see the description of the »BITMAPINFO« data structure.

An application should use the information stored in the biSize member to locate the color table in a BITMAPINFO structure, as follows:

pColor = ((LPSTR)pBitmapInfo +

    (WORD)(pBitmapInfo->bmiHeader.biSize));

Windows supports formats for compressing bitmaps that define their colors with 8 bits per pixel and with 4 bits per pixel. Compression reduces the disk and memory storage required for the bitmap. The following paragraphs describe these formats.

When the biCompression member is BI_RLE8, the bitmap is compressed by using a run-length encoding (RLE) format for an 8-bit bitmap. This format can be compressed in encoded or absolute modes. Both modes can occur anywhere in the same bitmap.

•	Encoded mode consists of two bytes: the first byte specifies the number of consecutive pixels to be drawn using the color index contained in the second byte. In addition, the first byte of the pair can be set to zero to indicate an escape that denotes an end of line, end of bitmap, or delta. The interpretation of the escape depends on the value of the second byte of the pair. Following are the meanings of the second byte of the escape.

Value	Meaning
0	End of line.
1	End of bitmap.
2	Delta. The two bytes following the escape contain unsigned values indicating the horizontal and vertical offsets of the next pixel from the current position.
•	In absolute mode, the first byte is zero and the second byte is a value in the range 03H through FFH. The second byte represents the number of bytes that follow, each of which contains the color index of a single pixel. When the second byte is 2 or less, the escape has the same meaning as in encoded mode. In absolute mode, each run must be aligned on a WORD boundary.

The following example shows the hexadecimal values of an 8-bit compressed bitmap.

03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01

02 78 00 00 09 1E 00 01

This bitmap would expand as follows (two-digit values represent a color index for a single pixel):

04 04 04

06 06 06 06 06

45 56 67

78 78

move current position 5 right and 1 down

78 78

end of line

1E 1E 1E 1E 1E 1E 1E 1E 1E

end of RLE bitmap

When the biCompression member is BI_RLE4, the bitmap is compressed by using a run-length encoding format for a 4-bit bitmap, which also uses encoded and absolute modes:

•	In encoded mode, the first byte of the pair contains the number of pixels to be drawn using the color indices in the second byte. The second byte contains two color indices, one in its high-order nibble (that is, its high-order four bits) and one in its low-order nibble. The first of the pixels is drawn using the color specified by the high-order nibble, the second is drawn using the color in the low-order nibble, the third is drawn using the color in the high-order nibble, and so on, until all the pixels specified by the first byte have been drawn.

•	In absolute mode, the first byte is zero, the second byte contains the number of color indices that follow, and subsequent bytes contain color indices in their high- and low-order four bits, one color index for each pixel. In absolute mode, each run must be aligned on a WORD boundary. The end-of-line, end-of-bitmap, and delta escapes also apply to BI_RLE4 compression.

The following example shows the hexadecimal values of a 4-bit compressed bitmap.

03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01

04 78 00 00 09 1E 00 01

This bitmap would expand as follows (single-digit values represent a color index for a single pixel):

0 4 0

0 6 0 6 0

4 5 5 6 6 7

7 8 7 8

move current position 5 right and 1 down

7 8 7 8

end of line

1 E 1 E 1 E 1 E 1

end of RLE bitmap

See Also

»BITMAPINFO«


  BY_HANDLE_FILE_INFORMATION

typedef struct _BY_HANDLE_FILE_INFORMATION { /* bhfi */

    DWORD    dwFileAttributes;

    FILETIME ftCreationTime;

    FILETIME ftLastAccessTime;

    FILETIME ftLastWriteTime;

    DWORD    dwVolumeSerialNumber;

    DWORD    nFileSizeHigh;

    DWORD    nFileSizeLow;

    DWORD    nNumberOfLinks;

    DWORD    nFileIndexHigh;

    DWORD    nFileIndexLow;

} BY_HANDLE_FILE_INFORMATION;

The BY_HANDLE_FILE_INFORMATION structure contains information retrieved by the GetFileInformationByHandle function.

Members

dwFileAttributes

Specifies the file's attributes. This member can be one or more of the following:

Value	Meaning
FILE_ATTRIBUTE_ARCHIVE
	The file is an archive file. Applications use this flag to mark files for backup or removal.
FILE_ATTRIBUTE_DIRECTORY
	The file is a directory.
FILE_ATTRIBUTE_HIDDEN
	The file is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL
	The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_READONLY
	The file is a read-only file. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM
	The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY
	The file is a temporary file. Applications can write to the file only if absolutely necessary. Most of the file's data remains in memory without being flushed to the media because the file will soon be deleted.
FILE_ATTRIBUTE_ATOMIC_WRITE
	The file is an atomic write file. Applications write to the file using atomic write semantics. If any write operation flushes data to the medium, all write operations up to that point are also flushed, as well as any file system structures. This ensures that the data is retrievable at a later time.
FILE_ATTRIBUTE_XACTION_WRITE
	Reserved for future use. Do not specify.
ftCreationTime

Specifies the time the file was created. If the underlying file system does not support this time field, ftCreationTime is zero. The file allocation table (FAT) file system does not record file creation time, but the high-performance (HPFS) and New Technology (NTFS) file systems do.

ftLastAccessTime

Specifies the time the file was last accessed. If the underlying file system does not support this time field, ftLastAccessTime is zero. The FAT file system does not record last access time, but HPFS and NTFS do.

ftLastWriteTime

Specifies the last time the file was written to.

dwVolumeSerialNumber

Specifies the serial number of the volume that contains the file.

nFileSizeHigh

Specifies the high-order word of the file size.

nFileSizeLow

Specifies the low-order word of the file size.

nNumberOfLinks

Specifies the number of links to this file. For FAT and HPFS file systems, this member is always 1. For NTFS, it may be more than one.

nFileIndexHigh

Specifies the high order word of a unique identifier associated with the file.

nFileIndexLow

Specifies the low order word of a unique identifier associated with the file. This identifier and the volume serial number uniquely identify a file. This number may change when the system is restarted or when the file is opened. After a process opens a file, the identifier is constant until the file is closed. An application can use this identifier and the volume serial number to determine whether two handles refer to the same file.

See Also

»GetFileInformationByHandle«


  CBT_CREATEWND

typedef struct tagCBT_CREATEWND { /* cbtcw */

    LPCREATESTRUCT lpcs;

    HWND           hwndInsertAfter;

} CBT_CREATEWND;

The CBT_CREATEWND structure contains information passed to a WH_CBT hook procedure before a window is created.

Members

lpcs

Points to a CREATESTRUCT structure that contains initialization parameters for the window about to be created. The CREATESTRUCT structure has the following form:

typedef struct tagCREATESTRUCT { /* cs */

    LPVOID lpCreateParams;

    HANDLE hInstance;

    HMENU  hMenu;

    HWND   hwndParent;

    int    cy;

    int    cx;

    int    y;

    int    x;

    LONG   style;

    LPCSTR lpszName;

    LPCSTR lpszClass;

    DWORD  dwExStyle;

} CREATESTRUCT;

hwndInsertAfter

Identifies the window whose position in the Z order precedes that of the window being created.

See Also

»CBTProc«, »SetWindowsHookEx«


  CBTACTIVATESTRUCT

typedef struct tagCBTACTIVATESTRUCT { /* cas */

    BOOL fMouse;

    HWND hWndActive;

} CBTACTIVATESTRUCT;

The CBTACTIVATESTRUCT structure contains information passed to a WH_CBT hook procedure before a window is activated.

Members

fMouse

Specifies whether the window is being activated as a result of a mouse click. This value is TRUE if a mouse click is causing the activation or FALSE if it is not.

hWndActive

Identifies the active window.

See Also

»SetWindowsHookEx«


  CHAR_INFO

typedef struct _CHAR_INFO { /* chi */

    union {                /* Unicode or ANSI character  */

        WCHAR UnicodeChar;

        CHAR AsciiChar;

    } Char;

    WORD Attributes;       /* text and background colors */

} CHAR_INFO, *PCHAR_INFO;

The CHAR_INFO structure specifies the Unicode or ANSI character and the foreground (text) and background color attributes of a screen buffer character cell. This structure is used by console functions to read from and write to a console screen buffer.

Members

Char

Specifies either the Unicode (wide-character) or ANSI character of a screen buffer character cell, depending on whether the Unicode or ANSI version of the function is used.

Attributes

Specifies the foreground (text) and background colors in which a screen buffer character cell is drawn.

See Also

»ReadConsoleOutput«, »ScrollConsoleScreenBuffer«, »WriteConsoleOutput«


  CHARSET

typedef struct tagCHARSET { /* chst */

    DWORD aflBlock[3];

    DWORD flLang;

} CHARSET;

The CHARSET structure specifies the Unicode™ blocks and the character sets supported by a given font.

Members

aflBlock

Specifies which (if any) of the 96 Unicode blocks are supported by a font. If the font contains at least one character in the given block, the corresponding bit is set.

flLang

Identifies the character set supported by the font. This member can be one of the following values:

Value	Meaning
CS_UGL	Supports the Universal Glyph List (UGL) character set.
CS_LATIN	Supports the Latin character set.
CS_GREEK	Supports the Greek character set.
CS_WIN30	Supports the Windows 3.0 character set.
Bits 0 and 31 of flLang are reserved and must be set to zero.


  CHOOSECOLOR

typedef struct {   /* cc */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HWND         hInstance;

    DWORD        rgbResult;

    LPDWORD      lpCustColors;

    DWORD        Flags;

    DWORD        lCustData;

    LPCCHOOKPROC lpfnHook;

    LPCSTR       lpTemplateName;

} CHOOSECOLOR;

The CHOOSECOLOR structure contains information the operating system uses to initialize the system-defined Color dialog box. After the user closes the dialog box, the system returns information about the user's selection in this structure.

Members

lStructSize

Specifies the length, in bytes, of the structure.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, or NULL if the dialog box has no owner.

hInstance

Identifies a data block that contains the dialog box template specified by the lpTemplateName member. This member is used only if the Flags member specifies the CC_ENABLETEMPLATE flag; otherwise, this member is ignored.

rgbResult

Specifies the color initially selected when the dialog box is created, and contains the user's color selection when the dialog box is closed. When the dialog box is created, if the CC_RGBINIT flag is set in the Flags member and the value of this member is not among the colors available, the system selects the nearest solid color available. If this member is NULL, the color initially selected is black.

lpCustColors

Points to an array of 16 DWORDs that contain RGB values for the custom color boxes in the dialog box. If the user modifies these colors, the system updates the array with the new RGB values. An application should save these values for future calls to the ChooseColor function.

Flags

Specifies the dialog box initialization flags. This member may be a combination of the following values:

Value	Meaning
CC_ENABLEHOOK	Enables the hook function specified in the lpfnHook member.
CC_ENABLETEMPLATE	Causes the system to create the dialog box by using the dialog box template identified by the hInstance and lpTemplateName members.
CC_ENABLETEMPLATEHANDLE	Indicates that the hInstance member identifies a data block that contains a pre-loaded dialog box template. The system ignores the lpTemplateName member if this flag is specified.
CC_FULLOPEN	Causes the entire dialog box to appear when the dialog box is created, including the portion that allows the user to create custom colors. If this flag is not specified, the user must choose the Define Custom Color button to see this portion of the dialog box.
CC_PREVENTFULLOPEN	Disables the Define Custom Colors button, preventing the user from creating custom colors.
CC_RGBINIT	Causes the dialog box to use the color specified in the rgbResult member as the initial color selection.
CC_SHOWHELP	Causes the dialog box to show the Help button. The hwndOwner member must not be NULL if this option is specified.
lCustData

Specifies application-defined data the system passes to the hook function identified by the lpfnHook member. The system passes the data in the lParam parameter of the WM_INITDIALOG message.

lpfnHook

Points to a hook function that processes messages intended for the dialog box. An application must specify the CC_ENABLEHOOK flag in the Flags member to enable the function; otherwise, the system ignores this structure member. The hook function must return FALSE to pass a message to the standard color dialog box procedure, or TRUE to discard the message.

lpstrTemplateName

Points to a null-terminated string that names the dialog box template resource to be substituted for the standard dialog box template. An application can use the MAKEINTRESOURCE macro for numbered dialog box resources. This member is used only if the Flags member specifies the CC_ENABLETEMPLATE flag; otherwise, this member is ignored.

See Also

»ChooseColor«, »WM_INITDIALOG«


  CHOOSEFONT

typedef struct {    /* cf */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HDC          hDC;

    LPLOGFONT    lpLogFont;

    INT          iPointSize;

    DWORD        Flags;

    DWORD        rgbColors;

    DWORD        lCustData;

    LPCFHOOKPROC lpfnHook;

    LPCTSTR      lpTemplateName;

    HANDLE       hInstance;

    LPTSTR       lpszStyle;

    WORD         nFontType;

    WORD         ___MISSING_ALIGNMENT__;

    INT          nSizeMin;

    INT          nSizeMax;

} CHOOSEFONT;

The CHOOSEFONT structure contains information the operating system uses to initialize the system-defined Font dialog box. After the user closes the dialog box, the system returns information about the user's selection in this structure.

Members

lStructSize

Specifies the length, in bytes, of the structure.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, or NULL if the dialog box has no owner.

hDC

Identifies the device context (or information context) of the printer whose fonts will be listed in the dialog box. This member is used only if the Flags member specifies the CF_PRINTERFONTS flag; otherwise, this member is ignored.

lpLogFont

Points to a LOGFONT structure. If an application initializes the members of this structure before calling ChooseFont and also sets the CF_INITTOLOGFONTSTRUCT flag, the ChooseFont function initializes the dialog with a font that is the closest possible match. After the user closes the dialog box, ChooseFont sets the members of the LOGFONT structure based on the user's final selection.

iPointSize

Specifies the size of the selected font in units of 1/10 of a point. ChooseFont sets this value after the user closes the dialog box.

Flags

Specifies the dialog box initialization flags. This member may be a combination of the following values:

Value	Meaning
CF_APPLY	Specifies that ChooseFont should enable the Apply button.
CF_ANSIONLY	Specifies that ChooseFont should allow only the selection of fonts using the Windows character set. (If this flag is set, the user will not be able to select a font that contains only symbols.)
CF_BOTH	Causes the dialog box to list the available printer and screen fonts. The hDC member identifies the device context (or information context) associated with the printer.
CF_TTONLY	Specifies that ChooseFont should enumerate only and allow the selection of TrueType fonts.
CF_EFFECTS	Specifies that ChooseFont should enable strikeout, underline, and color effects. If this flag is set, the lfStrikOut, lfUnderline, and rgbColors members can be set before calling ChooseFont, and ChooseFont can set these members after the user closes the dialog box.
CF_ENABLEHOOK	Enables the hook function specified in the lpfnHook member of this structure.
CF_ENABLETEMPLATE	Indicates that hInstance member identifies a data block that contains a dialog box template identified by lpTemplateName.
CF_ENABLETEMPLATEHANDLE	Indicates that hInstance member identifies a data block that contains a preloaded dialog box template. The system ignores the lpTemplateName member if this flag is specified.
CF_FIXEDPITCHONLY	Specifies ChooseFont should select only fixed-pitch fonts.
CF_FORCEFONTEXIST	Specifies that ChooseFont should indicate an error condition if the user attempts to select a font or style that does not exist.
CF_INITTOLOGFONTSTRUCT	Specifies that ChooseFont should use the LOGFONT structure pointed to by lpLogFont to initialize the dialog box controls.
CF_LIMITSIZE	Specifies that ChooseFont should select only font sizes within the range specified by the nSizeMin and nSizeMax members.
CF_NOOEMFONTS	See the CF_NOVECTORFONTS description.
CF_NOFACESEL	Specifies that ChooseFont should not allow font selections.
CF_NOSTYLESEL	Specifies that ChooseFont should not allow style selections.
CF_NOSIZESEL	Specifies that ChooseFontw should not allow size selections.
CF_NOSIMULATIONS	Specifies that ChooseFont should not allow graphics device interface (GDI) font simulations.
CF_NOVECTORFONTS	Specifies that ChooseFont should not allow vector-font selections.
CF_PRINTERFONTS	Causes the dialog box to list only the fonts supported by the printer associated with the device context (or information context) identified by the hDC member.
CF_SCALABLEONLY	Specifies that ChooseFont should allow only the selection of scalable fonts. (Scalable fonts include: vector fonts, scalable printer fonts, TrueType fonts, and fonts scaled by other algorithms or technologies.)
CF_SCREENFONTS	Causes the dialog box to list only the screen fonts supported by the system.
CF_SHOWHELP	Causes the dialog box to show the Help button. The hwndOwner member must not be NULL if this option is specified.
CF_USESTYLE	Specifies that lpszStyle member points to a buffer that contains style data that ChooseFont should use to initialize the Font Style selection. When the user closes the dialog box, ChooseFont copies style data for the user's selection to this buffer.
CF_WYSIWYG	Specifies that ChooseFont should allow only the selection of fonts available on both the printer and the display. If this flag is set, the CF_BOTH and CF_SCALABLEONLY flags should also be set.
rgbColors

If the CF_EFFECTS flag is set, this member contains an RGB value that ChooseFont should use to set the text color. After the user closes the dialog box, this member contains the RGB value of the color the user selected.

lCustData

Specifies application-defined data the application passes to the hook function.

lpfnHook

Points to a hook function that processes messages intended for the dialog box. An application must specify the CF_ENABLEHOOK flag in the Flags member to enable the function; otherwise, the system ignores this member. The hook function must return FALSE to pass a message to the standard dialog box procedure, or TRUE to discard the message.

lpTemplateName

Points to a null-terminated string that names the dialog box template resource to be substituted for the standard dialog box template. An application can use the MAKEINTRESOURCE macro for numbered dialog box resources. This member is used only if the Flags member specifies the CF_ENABLETEMPLATE flag; otherwise, this member is ignored.

hInstance

Identifies a data block that contains the dialog box template specified by the lpstrTemplateName member. This member is used only if the Flags member specifies the CF_ENABLETEMPLATE flag; otherwise, this member is ignored.

lpszStyle

Points to a buffer that contains style data. If the CF_USESTYLE flag is set, that ChooseFont uses the data in this buffer to initialize the style control. When the user closes the dialog box, that ChooseFont copies the string in the style control into this buffer.

nFontType

Specifies the type of the selected font. This member may contain one of the values in the following list:

Value	Meaning
SIMULATED_FONTTYPE	The font is simulated by graphics device interface (GDI).
PRINTER_FONTTYPE	The font is a printer font.
SCREEN_FONTTYPE	The font is a screen font.
nSizeMin

Specifies the minimum point size a user can select. ChooseFont recognizes this member only if the CF_LIMITSIZE flag is set.

nSizeMax

Specifies the maximum point size a user can select. ChooseFont recognizes this member only if the CF_LIMITSIZE flag is set.

See Also

»ChooseFont«


  COLORADJUSTMENT

typedef struct  tagCOLORADJUSTMENT {    /* ca */

    WORD  caSize;

    WORD  caFlags;

    WORD  caIlluminantIndex;

    WORD  caRedGamma;

    WORD  caGreenGamma;

    WORD  caBlueGamma;

    WORD  caReferenceBlack;

    WORD  caReferenceWhite;

    SHORT caContrast;

    SHORT caBrightness;

    SHORT caColorfulness;

    SHORT caRedGreenTint;

} COLORADJUSTMENT;

The COLORADJUSTMENT structure defines the color adjustment values used by the StretchBlt and StretchDIBits functions when the stretchblt mode is HALFTONE.

Members

caSize

Specifies the size of the structure in bytes.

caFlags

Specifies how the output image should be prepared. This member may be set to NULL or any combination of the following values:

Value	Meaning
CA_NEGATIVE	Specifies that the negative of the original image should be displayed.
CA_LOG_FILTER	Specifies that a logarithmic function should be applied to the final density of the output colors. This will increase the color contrast when the luminance is low.
caIlluminantIndex

Specifies the luminance of the light source under which the image object is viewed. This member may be set to one of the following values:

•	ILLUMINANT_EQUAL_ENERGY

•	ILLUMINANT_A

•	ILLUMINANT_B

•	ILLUMINANT_C

•	ILLUMINANT_D50

•	ILLUMINANT_D55

•	ILLUMINANT_D65

•	ILLUMINANT_D75

•	ILLUMINANT_F2

•	ILLUMINANT_TURNGSTEN

•	ILLUMINANT_DAYLIGHT

•	ILLUMINANT_FLUORESCENT

•	ILLUMINANT_NTSC

caRedGamma

Specifies the n-th power gamma-correction value for the red primary of the source colors. The value must be in the range from 2,500 to 65,000. A value of 10,000 means no gamma-correction.

caGreenGamma

Specifies the n-th power gamma-correction value for the green primary of the source colors. The value must be in the range from 2,500 to 65,000. A value of 10,000 means no gamma-correction.

caBlueGamma

Specifies the n-th power gamma-correction value for the blue primary of the source colors. The value must be in the range from 2,500 to 65,000. A value of 10,000 means no gamma-correction.

caReferenceBlack

Specifies the black reference for the source colors. Any colors that are darker than this are treated as black. The value must be in the range from 0 to 4,000.

caReferenceWhite

Specifies the white reference for the source colors. Any colors that are lighter than this are treated as white. The value must be in the range from 6,000 to 10,000.

caContrast

Specifies the amount of contrast to be applied to the source object. The value must be in the range from -100 to 100. A value of 0 means no contrast adjustment.

caBrightness

Specifies the amount of brightness to be applied to the source object. The value must be in the range from -100 to 100. A value of 0 means no brightness adjustment.

caColorfulness

Specifies the amount of colorfulness to be applied to the source object. The value must be in the range from -100 to 100. A value of 0 means no colorfulness adjustment.

caRedGreenTint

Specifies the amount of red or green tint adjustment to be applied to the source object. The value must be in the range from -100 to 100. Positive numbers would adjust towards red and negative numbers adjust towards green. A 0 means no tint adjustment.

See Also

»SetStretchBltMode« »StretchBlt«, »StretchDIBits«


  CLIENTCREATESTRUCT

typedef struct tagCLIENTCREATESTRUCT { /* ccs */

    HANDLE hWindowMenu;

    UINT   idFirstChild;

} CLIENTCREATESTRUCT;

The CLIENTCREATESTRUCT structure contains information about the menu and first multiple document interface (MDI) child window of an MDI client window. An application passes a pointer to this structure as the lpvParam parameter of the CreateWindow function when creating an MDI client window.

Members

hWindowMenu

Identifies the handle of the MDI application's Window menu. An MDI application can retrieve this handle from the menu of the MDI frame window by using the GetSubMenu function.

idFirstChild

Specifies the child window identifier of the first MDI child window created. Windows increments the identifier for each additional MDI child window the application creates, and reassigns identifiers when the application destroys a window to keep the range of identifiers contiguous. These identifiers are used in WM_COMMAND messages sent to the application's MDI frame window when a child window is chosen from the Window menu; they should not conflict with any other command identifiers.

See Also

»CreateWindow«, »GetSubMenu«, »MDICREATESTRUCT«


  COLORREF

The COLORREF value is a 32-bit value used to specify an RGB color.

Comments

When specifying an explicit RGB color, the COLORREF value has the following hexadecimal form:

0x00bbggrr

The low-order byte contains a value for the relative intensity of red; the second byte contains a value for green; and the third byte contains a value for blue. The high-order byte must be zero. The maximum value for a single byte is 0xFF.

See Also

»GetBValue«, »GetGValue«, »GetRValue«, »RGB«


  COMMPROP

typedef struct _COMMPROP { /* cmmp */

    WORD  wPacketLength;       /* packet size, in bytes    */

    WORD  wPacketVersion;      /* packet version           */

    DWORD dwServiceMask;       /* services implemented     */

    DWORD dwReserved1;         /* reserved                 */

    DWORD dwMaxTxQueue;        /* max Tx bufsize, in bytes */

    DWORD dwMaxRxQueue;        /* max Rx bufsize, in bytes */

    DWORD dwMaxBaud;           /* max baud rate, in bps    */

    DWORD dwProvSubType;       /* specific provider type   */

    DWORD dwProvCapabilities;  /* capabilities supported   */

    DWORD dwSettableParams;    /* changable parameters     */

    DWORD dwSettableBaud;      /* allowable baud rates     */

    WORD  wSettableData;       /* allowable byte sizes     */

    WORD  wSettableStopParity; /* stop bits/parity allowed */

    DWORD dwCurrentTxQueue;    /* Tx buffer size, in bytes */

    DWORD dwCurrentRxQueue;    /* Rx buffer size, in bytes */

    DWORD dwProvSpec1;         /* provider-specific data   */

    DWORD dwProvSpec2;         /* provider-specific data   */

    WCHAR wcProvChar[1];       /* provider-specific data   */

} COMMPROP;

The COMMPROP structure is used in the GetCommProperties function to return information about a given communications driver.

Members

wPacketLength

Specifies the size, in bytes, of the entire data packet, regardless of the amount of data requested.

wPacketVersion

Specifies the version of the structure.

dwServiceMask

Specifies a bitmask indicating which services are implemented by this provider. The SP_SERIALCOMM bit is always set for communications providers.

dwReserved1

Reserved; do not use.

dwMaxTxQueue

Specifies the maximum size, in bytes, of the driver's internal output buffer. A value of zero indicates that no maximum value is imposed by the serial provider. See the Comments section below for further discussion of a zero value.

dwMaxRxQueue

Specifies the maximum size, in bytes, of the driver's internal input buffer. A value of zero indicates that no maximum value is imposed by the serial provider. See the Comments section below for further discussion of a zero value.

dwMaxBaud

Specifies the maximum allowable baud rate, in bits per second (bps). This member can be one of the following values:

Value	Meaning
BAUD_075	75 bps
BAUD_110	110 bps
BAUD_134_5	134.5 bps
BAUD_150	150 bps
BAUD_300	300 bps
BAUD_600	600 bps
BAUD_1200	1200 bps
BAUD_1800	1800 bps
BAUD_2400	2400 bps
BAUD_4800	4800 bps
BAUD_7200	7200 bps
BAUD_9600	9600 bps
BAUD_14400	14400 bps
BAUD_19200	19200 bps
BAUD_38400	38400 bps
BAUD_56K	56K bps
BAUD_128K	128K bps
BAUD_USER	Programmable baud rates available
dwProvSubType

Specifies the specific communications provider type.

Value	Meaning
PST_UNSPECIFIED	Unspecified
PST_RS232	RS-232 serial port
PST_PARALLELPORT	Parallel port
PST_RS422	RS-422 port
PST_RS423	RS-423 port
PST_RS449	RS-449 port
PST_FAX	Fax device
PST_SCANNER	Scanner device
PST_NETWORK_BRIDGE	Unspecified network bridge
PST_LAT	LAT protocol
PST_TCPIP_TELNET	TCP/IP Telnet protocol
PST_X25	X.25 standards
dwProvCapabilities

Specifies a bitmask indicating the capabilities offered by the provider. This member can be one of the following values:

Flag	Meaning
PCF_DTRDSR	DTR (data-terminal-ready)/DSR (data-set-ready) supported
PCF_RTSCTS	RTS (request-to-send)/CTS (clear-to-send) supported
PCF_RLSD	RLSD (receive-line-signal-detect supported)
PCF_PARITY_CHECK	Parity checking supported
PCF_XONXOFF	XON/XOFF flow control supported
PCF_SETXCHAR	Settable XON/XOFF supported
PCF_TOTALTIMEOUTS	Total (elapsed) timeouts supported
PCF_INTTIMEOUTS	Interval timeouts supported
PCF_SPECIALCHARS	Special character support provided
PCF_16BITMODE	Special 16-bit mode supported
dwSettableParams

Specifies a bitmask indicating the communications parameter that can be changed. This member can be one of the following values:

Flag	Meaning
SP_PARITY	Parity
SP_BAUD	Baud rate
SP_DATABITS	Data bits
SP_STOPBITS	Stop bits
SP_HANDSHAKING	Handshaking (flow control)
SP_PARITY_CHECK	Parity checking
SP_RLSD	RLSD (receive-line-signal-detect)
dwSettableBaud

Specifies a bitmask indicating the baud rates that can be set. For values, see the dwMaxBaud member.

wSettableData

Specifies a bitmask indicating the number of data bits that can be set. This member can be one of the following values:

Flag	Meaning
DATABITS_5	5 data bits
DATABITS_6	6 data bits
DATABITS_7	7 data bits
DATABITS_8	8 data bits
DATABITS_16	Special wide path through serial hardware lines
wSettableStopParity

Specifies a bitmask indicating the stop bit and parity settings that can be selected. This member can be one of the following values:

Flag	Meaning
STOPBITS_10	1 stop bit
STOPBITS_15	1.5 stop bits
STOPBITS_20	2 stop bits
PARITY_NONE	No parity
PARITY_ODD	Odd parity
PARITY_EVEN	Even parity
PARITY_MARK	Mark parity
PARITY_SPACE	Space parity
dwCurrentTxQueue

Specifies the size, in bytes, of the driver's internal output buffer. A value of zero indicates that the value is unavailable.

dwCurrentRxQueue

Specifies the size, in bytes, of the driver's internal input buffer. A value of zero indicates that the value is unavailable.

dwProvSpec1

Specifies provider-specific data. Applications should ignore this member unless they have detailed information about the format of the data required by the provider.

dwProvSpec2

Specifies provider-specific data. Applications should ignore this member unless they have detailed information about the format of the data required by the provider.

wcProvChar

Specifies provider-specific data. Applications should ignore this member unless they have detailed information about the format of the data required by the provider.

Comments

A zero value for dwMaxTxQueue and dwMaxRxQueue indicates that no maximum value is imposed by the serial provider. What does this really mean ? In the case of the transmit buffer, for example, it means that the serial driver is using a buffer provided as a parameter by a caller of the WriteFile function. The serial buffer doesn't have its own separate write buffer in such a situation, and no maximum values can be imposed on a non-existent entity.

See Also

»GetCommProperties«


  COMMTIMEOUTS

typedef struct _COMMTIMEOUTS { /* ctmo */

    DWORD ReadIntervalTimeout;

    DWORD ReadTotalTimeoutMultiplier;

    DWORD ReadTotalTimeoutConstant;

    DWORD WriteTotalTimeoutMultiplier;

    DWORD WriteTotalTimeoutConstant;

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

The COMMTIMEOUTS structure is used in the SetCommTimeouts and GetCommTimeouts functions to set and query the timeout parameters for a communications device. The parameters determine the behavior of ReadFile, WriteFile, ReadFileEx, and WriteFileEx operations on the device.

Members

ReadIntervalTimeout

Specifies the maximum time, in milliseconds, allowed to elapse between the arrival of two characters on the communications line. During a ReadFile operation, the time period begins when the first character is received. If the interval between the arrival of any two characters exceeds this amount, the ReadFile operation is completed and any buffered data is returned. A value of zero indicates that interval timeouts are not used.

A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the characters that have already been received, even if no characters have been received.

ReadTotalTimeoutMultiplier

Specifies the multiplier, in milliseconds, used to calculate the total timeout period for read operations. For each read operation, this value is multiplied by the requested number of bytes to read.

ReadTotalTimeoutConstant

Specifies the constant, in milliseconds, used to calculate the total timeout period for read operations. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.

A value of zero for both the ReadTotalTimeoutMultiplier and ReadTotalTimeoutConstant members indicates that total timeouts are not used for read operations.

WriteTotalTimeoutMultiplier

Specifies the multiplier, in milliseconds, used to calculate the total timeout period for write operations. For each write operation, this value is multiplied by the number of bytes to be written.

WriteTotalTimeoutConstant

Specifies the constant, in milliseconds, used to calculate the total timeout period for write operations. For each write operation, this value is added to the product of the WriteTotalTimeoutMultiplier member and the number of bytes to be written.

A value of zero for both the WriteTotalTimeoutMultiplier and WriteTotalTimeoutConstant members indicates that total timeouts are not used for write operations.

See Also

»GetCommTimeouts«, »SetCommTimeouts«


  COMPAREITEMSTRUCT

typedef struct tagCOMPAREITEMSTRUCT { /* cis */

    UINT  CtlType;

    UINT  CtlID;

    HWND  hwndItem;

    UINT  itemID1;

    DWORD itemData1;

    UINT  itemID2;

    DWORD itemData2;

} COMPAREITEMSTRUCT;

The COMPAREITEMSTRUCT structure supplies the identifiers and application-supplied data for two items in a sorted owner-draw list box or combo box.

Whenever an application adds a new item to an owner-drawn list box or combo box created with the CBS_SORT or LBS_SORT style, Windows sends the owner a WM_COMPAREITEM message. The lParam parameter of the message contains a long pointer to a COMPAREITEMSTRUCT structure. Upon receiving the message, the owner compares the two items and returns a value indicating which item sorts before the other.

Members

CtlType

Specifies ODT_LISTBOX (an owner-drawn list box) or ODT_COMBOBOX (an owner-drawn combo box).

CtlID

Specifies the identifier of the list box or combo box.

hwndItem

Identifies the control.

itemID1

Specifies the index of the first item in the list box or combo box being compared.

itemData1

Specifies application-supplied data for the first item being compared. (This value was passed as the lParam parameter of the message that added the item to the list box or combo box.)

itemID2

Specifies the index of the second item in the list box or combo box being compared.

itemData2

Specifies application-supplied data for the second item being compared. This value was passed as the lParam parameter of the message that added the item to the list box or combo box.

See Also

»WM_COMPAREITEM«


  COMSTAT

typedef struct _COMSTAT { /* cst */

    DWORD fCtsHold : 1;   /* Tx waiting for CTS signal    */

    DWORD fDsrHold : 1;   /* Tx waiting for DSR signal    */

    DWORD fRlsdHold : 1;  /* Tx waiting for RLSD signal   */

    DWORD fXoffHold : 1;  /* Tx waiting, XOFF char rec'd  */

    DWORD fXoffSent : 1;  /* Tx waiting, XOFF char sent   */

    DWORD fEof : 1;       /* EOF character sent           */

    DWORD fTxim : 1;      /* character waiting for Tx     */

    DWORD fReserved : 25; /* reserved                     */

    DWORD cbInQue;        /* bytes in input buffer        */

    DWORD cbOutQue;       /* bytes in output buffer       */

} COMSTAT, *LPCOMSTAT;

The COMSTAT structure contains information about a communications device. This structure is filled in by the ClearCommError function.

Members

fCtsHold

Specifies whether transmission is waiting for the CTS (clear-to-send) signal to be sent. If this member is TRUE, transmission is waiting.

fDsrHold

Specifies whether transmission is waiting for the DSR (data-set-ready) signal to be sent. If this member is TRUE, transmission is waiting.

fRlsdHold

Specifies whether transmission is waiting for the RLSD (receive-line-signal-detect) signal to be sent. If this member is TRUE, transmission is waiting.

fXoffHold

Specifies whether transmission is waiting because the XOFF character was received. If this member is TRUE, transmission is waiting.

fXoffSent

Specifies whether transmission is waiting because the XOFF character was transmitted. If this member is TRUE, transmission is waiting. Transmission halts when the XOFF character is transmitted to a system that takes the next character as XON, regardless of the actual character.

fEof

Specifies whether the EOF character has been received. If this member is TRUE, the EOF character has been received.

fTxim

Specifies whether a character is waiting to be transmitted. If this member is TRUE, a character is waiting to be transmitted.

fReserved

Reserved; do not use.

cbInQue

Specifies the number of bytes received by the serial provider but not yet read by a ReadFile operation.

cbOutQue

Specifies the number of bytes of user data remaining to be transmitted for all write operations. This value will be 0 when doing a non-overlapped write.

See Also

»ClearCommError«


  CONSOLE_CURSOR_INFO

typedef struct _CONSOLE_CURSOR_INFO { /* cci */

    DWORD  dwSize;

    BOOL   bVisible;

} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

The CONSOLE_CURSOR_INFO structure contains information about the console cursor.

Members

dwSize

Specifies a number between 1 and 100, indicating the percentage of the character cell that is filled by the cursor. The cursor appearance varies, ranging from completely filling the cell to showing up as a horizontal line at the bottom of the cell.

bVisible

Specifies the visibility of the cursor. If the cursor is visible, this member is TRUE.

See Also

»GetConsoleCursorInfo«, »SetConsoleCursorInfo«


  CONSOLE_SCREEN_BUFFER_INFO

typedef struct _CONSOLE_SCREEN_BUFFER_INFO { /* csbi */

    COORD      dwSize;

    COORD      dwCursorPosition;

    WORD       wAttributes;

    SMALL_RECT srWindow;

    COORD      dwMaximumWindowSize;

} CONSOLE_SCREEN_BUFFER_INFO ;

The CONSOLE_SCREEN_BUFFER_INFO structure contains information about a console screen buffer.

Members

dwSize

Specifies the size, in character columns and rows, of the screen buffer.

dwCursorPosition

Specifies the column and row coordinates of the cursor in the screen buffer.

wAttributes

Specifies the foreground (text) and background color attributes to be used for characters that are written to a screen buffer by the WriteFile and WriteConsole functions, or echoed to a screen buffer by the ReadFile and ReadConsole functions. The attribute values are some combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a white background.

FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE

srWindow

Specifies a SMALL_RECT structure that contains the screen buffer coordinates of the upper left and lower right corners of the display window. The SMALL_RECT structure has the following form:

typedef struct _SMALL_RECT { /* srct */

    SHORT Left;

    SHORT Top;

    SHORT Right;

    SHORT Bottom;

} SMALL_RECT;

dwMaximumWindowSize

Specifies the maximum size of the console window, given the current screen buffer size and font and the screen size.

See Also

»GetConsoleScreenBufferInfo«


  CONTEXT

The CONTEXT structure contains processor-specific register data. Currently, there is a CONTEXT structure for Intel® processors and one for MIPS® processors. This structure is defined in the header file.


  CONVCONTEXT

typedef struct tagCONVCONTEXT {   /* cc */

    UINT  cb;

    UINT  wFlags;

    UINT  wCountryID;

    int   iCodePage;

    DWORD dwLangID;

    DWORD dwSecurity;

    SECURITY_QUALITY_OF_SERVICE qos;  /* client side's quality of service */

} CONVCONTEXT;

The CONVCONTEXT structure contains information supplied by a dynamic data exchange (DDE) client application. The information is useful for specialized or cross-language DDE conversations.

Members

cb

Specifies the size, in bytes, of the structure.

wFlags

Specifies conversation context flags. Currently, no flags are defined for this member.

wCountryID

Specifies the country-code identifier for topic-name and item-name strings.

iCodePage

Specifies the code page for topic-name and item-name strings. Non-multilingual clients should set this member to CP_WINANSI. Unicode clients should set this value to CP_WINUNICODE.

dwLangID

Specifies the language identifier for topic-name and item-name strings.

dwSecurity

Specifies a private (application-defined) security code.

qos

Specifies the quality of service a DDE client wants from the system during a given conversation. The quality of service level specified lasts for the duration of the conversation. It cannot be changed once the conversation is started.


  CONVINFO

typedef struct tagCONVINFO {  /* ci */

    DWORD       cb;

    DWORD       hUser;

    HCONV       hConvPartner;

    HSZ         hszSvcPartner;

    HSZ         hszServiceReq;

    HSZ         hszTopic;

    HSZ         hszItem;

    UINT        wFmt;

    UINT        wType;

    UINT        wStatus;

    UINT        wConvst;

    UINT        wLastError;

    HCONVLIST   hConvList;

    CONVCONTEXT ConvCtxt;

    HWND        hwnd;

    HWND        hwndPartner;

} CONVINFO;

The CONVINFO structure contains information about a dynamic data exchange (DDE) conversation.

Members

cb

Specifies the length, in bytes, of the structure.

hUser

Identifies application-defined data.

hConvPartner

Identifies the partner application in the DDE conversation. This member is set to zero if the partner has not registered itself (using the DdeInitialize function) to make DDE Management Library (DDEML) function calls. An application should not pass this member to any DDEML function except DdeQueryConvInfo.

hszSvcPartner

Identifies the service name of the partner application.

hszServiceReq

Identifies the service name of the server application that was requested for connection.

hszTopic

Identifies the name of the requested topic.

hszItem

Identifies the name of the requested item. This member is transaction specific.

wFmt

Specifies the format of the data being exchanged. This member is transaction specific.

wType

Specifies the type of the current transaction. This member is transaction specific; it can be one of the following values:

Value	Meaning
XTYP_ADVDATA	Informs a client that advise data from a server has arrived.
XTYP_ADVREQ	Requests a server send updated data to the client during an advise loop. This transaction results when the server calls the DdePostAdvise function.
XTYP_ADVSTART	Requests a server begin an advise loop with a client.
XTYP_ADVSTOP	Notifies a server an advise loop is stopping.
XTYP_CONNECT	Requests a server establish a conversation with a client.
XTYP_CONNECT_CONFIRM	Notifies a server a conversation with a client has been established.
XTYP_DISCONNECT	Notifies a server a conversation has terminated.
XTYP_EXECUTE	Requests a server execute a command sent by a client.
XTYP_MONITOR	Notifies an application registered as APPCMD_MONITOR that DDE data is being transmitted.
XTYP_POKE	Requests a server accept unsolicited data from a client.
XTYP_REGISTER	Notifies other DDEML applications that a server has registered a service name.
XTYP_REQUEST	Requests a server send data to a client.
XTYP_UNREGISTER	Notifies other DDEML applications that a server has unregistered a service name.
XTYP_WILDCONNECT	Requests a server establish multiple conversations with the same client.
XTYP_XACT_COMPLETE	Notifies a client that an asynchronous data transaction has been completed.
wStatus

Specifies the status of the current conversation. This member can be a combination of the following values:

Value	Meaning
ST_ADVISE	One or more links are in progress.
ST_BLOCKED	The conversation is blocked.
ST_BLOCKNEXT	The conversation will block after calling the next callback.
ST_CLIENT	The conversation handle passed to the DdeQueryConvInfo function is a client-side handle. If the handle is zero, the conversation handle passed to the DdeQueryConvInfo function is a server-side handle.
ST_CONNECTED	The conversation is connected.
ST_INLIST	The conversation is a member of a conversation list.
ST_ISLOCAL	Both sides of the conversation are using the DDEML.
ST_ISSELF	Both sides of the conversation are using the same instance of the DDEML.
ST_TERMINATED	The conversation has been terminated by the partner.
wConvst

Specifies the conversation state. This member can be one of the following values:

Value	Meaning
XST_ADVACKRCVD	The advise transaction has just been completed.
XST_ADVDATAACKRCVD	The advise data transaction has just been completed.
XST_ADVDATASENT	Advise data has been sent and is awaiting an acknowledgement.
XST_ADVSENT	An advise transaction is awaiting an acknowledgement.
XST_CONNECTED	The conversation has no active transactions.
XST_DATARCVD	The requested data has just been received.
XST_EXECACKRCVD	An execute transaction has just been completed.
XST_EXECSENT	An execute transaction is awaiting an acknowledgement.
XST_INCOMPLETE	The last transaction failed.
XST_INIT1	Mid-initiate state 1.
XST_INIT2	Mid-initiate state 2.
XST_NULL	Pre-initiate state.
XST_POKEACKRCVD	A poke transaction has just been completed.
XST_POKESENT	A poke transaction is awaiting an acknowledgement.
XST_REQSENT	A request transaction is awaiting an acknowledgement.
XST_UNADVACKRCVD	An unadvise transaction has just been completed.
XST_UNADVSENT	An unadvise transaction is awaiting an acknowledgement.
wLastError

Specifies the error value associated with the last transaction.

hConvList

Identifies the conversation list if the handle of the current conversation is in a conversation list. This member is NULL if the conversation is not in a conversation list.

ConvCtxt

Specifies the conversation context.

hwnd

Identifies the window of the calling application involved in the conversation.

hwndPartner

Identifies the window of the partner application involved in the current conversation.

See Also

»CONVCONTEXT«


  COORD

typedef struct _COORD { /* coord. */

    SHORT X;      /* horizontal coordinate    */

    SHORT Y;      /* vertical coordinate      */

} COORD;

The COORD structure defines the coordinates of a character cell in a console screen buffer. The origin of the coordinate system (0,0) is at the top, left cell of the buffer.

Members

X

Horizontal or column value.

Y

Vertical or row value.


  COPYDATASTRUCT

typedef struct tagCOPYDATASTRUCT {  /* cds */

    DWORD dwData;

    DWORD cbData;

    PVOID lpData;

} COPYDATASTRUCT;

The COPYDATASTRUCT structure contains data to be passed to another application by the WM_COPYDATA message.

Members

dwData

Specifies up to 32 bits of data to be passed to the receiving application.

cbData

Specifies the size, in bytes, of the data pointed to by the lpData member.

lpData

Points to data to be passed to the receiving application. This member can be NULL.

See Also

»WM_COPYDATA«


  CPINFO

struct tagCPINFO {

    UINT MaxCharSize;

    BYTE DefaultChar[MAX_DEFAULTCHAR];

    BYTE LeadByte[MAX_LEADBYTES];

} CPINFO;

The CPINFO structure contains information about a code page.

Members

MaxCharSize

Specifies the maximum length, in bytes, of a character in this code page.

DefaultChar

Specifies the default character used in translations into this code page as determined by the translation options specified in the WideCharToMultiByte function.

LeadByte

Specifies lead-byte ranges in a variable-length array. If there are no lead bytes in this code page, every element of the array is NULL. If there are lead bytes, a starting value and an ending value are given for each range. Ranges are inclusive.

Comments

Lead bytes are unique to double-byte character sets. A lead byte introduces a double-byte character. Lead bytes occupy a specific range of byte values.

The maximum number of lead-byte ranges for any code page is 5. Each range requires 2 bytes to describe, plus a double-byte terminating null character. Therefore, a value of 12 for the LeadByte member designates 5 lead-byte ranges.

See Also

»GetCPInfo«, »WideCharToMultiByte«


  CPLINFO

typedef struct tagCPLINFO { /* cpli */

    int  idIcon;

    int  idName;

    int  idInfo;

    LONG lData;

} CPLINFO;

The CPLINFO structure contains resource information and a user-defined value for a Control Panel application.

Members

idIcon

Specifies an icon resource identifier for the application icon. This icon is displayed in the Control Panel window.

idName

Specifies a string resource identifier for the application name. The name is the short string displayed below the application icon in the Control Panel window. The name is also displayed in the Settings menu of Control Panel.

idInfo

Specifies a string resource identifier for the application description. The description is the descriptive string displayed at the bottom of the Control Panel window when the application icon is selected.

lData

Specifies user-defined data for the application.

See Also

»CPL_INQUIRE«, »NEWCPLINFO«


  CREATE_PROCESS_DEBUG_INFO

typedef struct _CREATE_PROCESS_DEBUG_INFO { /* cpdi */

    HANDLE hFile;

    HANDLE hProcess;

    HANDLE hThread;

    LPVOID lpBaseOfImage;

    DWORD dwDebugInfoFileOffset;

    DWORD nDebugInfoSize;

    LPVOID lpThreadLocalBase;

    LPTHREAD_START_ROUTINE lpStartAddress;

    LPVOID lpImageName;

    WORD fUnicode;

} CREATE_PROCESS_DEBUG_INFO;

The CREATE_PROCESS_DEBUG_INFO structure contains process creation information that can be used by a debugger.

Members

hFile

Identifies an open handle of the process's image file. If hFile is NULL, the handle is not valid. Otherwise, the debugger can use hFile to read from and write to the image file.

hProcess

Identifies an open handle of the process. If hProcess is NULL, the handle is not valid. Otherwise, the debugger can use hProcess to read from and write to the process's memory.

hThread

Identifies an open handle of the initial thread of the process identified by the hProcess member. If hThread is NULL, the handle is not valid. Otherwise, the debugger has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread. This allows the debugger to read from and write to the registers of the thread and control execution of the thread.

lpBaseOfImage

Points to the base address of the executable image that the process is running.

dwDebugInfoFileOffset

Specifies the offset to the debugging information in the file identified by the hFile member. The kernel expects the debugging information to be in Microsoft® CodeView® version 4.0 format. This format is currently a derivative of COFF (Common Object File Format).

nDebugInfoSize

Specifies the size, in bytes, of the debugging information in the file. If this value is zero, there is no debugging information.

lpThreadLocalBase

Specifies the base address of a per-thread data block. At offset 0x2C within this block there exists an array of LPVOIDs. There is one LPVOID for each DLL/EXE loaded at process initialization, and that LPVOID points to thread local storage. This gives a debugger access to per-thread data in its debuggee's threads using the same algorithms that a compiler would use.

lpStartAddress

Points to the starting address of the thread. This value may only be an approximation of the thread's starting address, because any application with appropriate access to the thread can change the thread's context by using the SetThreadContext function.

lpImageName

Provides an optional pointer to the file name associated with the hFile parameter. The lpImageName parameter may be NULL, or may contain the address of a string pointer in the debuggee's address space. That address may in turn either be NULL, or point to the actual file name. If fUnicode is a non-zero value, the name string is Unicode; otherwise it is ANSI.

This parameter is strictly optional. Debuggers must be prepared to handle the case where lpImageName is NULL, OR *lpImageName (in the debuggee's address space) is NULL. Specifically, this release of Windows NT will never provide an image name for a create process event, and will not likely pass an image name for the first DLL event. This version of Windows NT will also never provide this information in the case of debug events that originate from a call to the DebugActiveProcess function.

fUnicode

Indicates whether a file name specified by lpImageName is Unicode or ANSI. A non-zero value indicates Unicode; zero indicates ANSI.

See Also

»CREATE_THREAD_DEBUG_INFO«, »DEBUG_EVENT«, »LOAD_DLL_DEBUG_INFO«


  CREATE_THREAD_DEBUG_INFO

typedef struct _CREATE_THREAD_DEBUG_INFO { /* ctdi */

    HANDLE hThread;

    LPVOID lpThreadLocalBase;

    LPTHREAD_START_ROUTINE lpStartAddress;

} CREATE_THREAD_DEBUG_INFO;

The CREATE_THREAD_DEBUG_INFO structure contains thread-creation information that can be used by a debugger.

Members

hThread

Identifies a handle of the thread whose creation caused the debugging event. If hThread is NULL, the handle is not valid. Otherwise, the debugger has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread. This allows the debugger to read from and write to the registers of the thread and control execution of the thread.

lpThreadLocalBase

Specifies the base address of a per-thread data block. At offset 0x2C within this block there exists an array of LPVOIDs. There is one LPVOID for each DLL/EXE loaded at process initialization, and that LPVOID points to thread local storage. This gives a debugger access to per-thread data in its debuggee's threads using the same algorithms that a compiler would use.

lpStartAddress

Points to the starting address of the thread. This value may only be an approximation of the thread's starting address, because any application with appropriate access to the thread can change the thread's context by using the SetThreadContext function.

See Also

»CREATE_PROCESS_DEBUG_INFO«, »DEBUG_EVENT«, »LOAD_DLL_DEBUG_INFO«


  CREATESTRUCT

typedef struct tagCREATESTRUCT { /* cs */

    LPVOID lpCreateParams;

    HANDLE hInstance;

    HMENU  hMenu;

    HWND   hwndParent;

    int    cy;

    int    cx;

    int    y;

    int    x;

    LONG   style;

    LPCSTR lpszName;

    LPCSTR lpszClass;

    DWORD  dwExStyle;

} CREATESTRUCT;

The CREATESTRUCT structure defines the initialization parameters passed to the window procedure of an application.

Members

lpCreateParams

Points to data to be used for creating the window.

hInstance

Identifies the module that owns the new window.

hMenu

Identifies the menu to be used by the new window.

hwndParent

Identifies the parent window, if the window is a child window. If the window is owned, this member identifies the owner window. If the window is not a child or owned window, this member is NULL.

cy

Specifies the height of the new window, in pixels.

cx

Specifies the width of the new window, in pixels.

y

Specifies the y-coordinate of the upper-left corner of the new window. If the new window is a child window, coordinates are relative to the parent window. Otherwise, the coordinates are relative to the screen origin.

x

Specifies the x-coordinate of the upper-left corner of the new window. If the new window is a child window, coordinates are relative to the parent window. Otherwise, the coordinates are relative to the screen origin.

style

Specifies the style for the new window.

lpszName

Points to a null-terminated string that specifies the name of the new window.

lpszClass

Points to a null-terminated string that specifies the class name of the new window.

dwExStyle

Specifies the extended style for the new window.

See Also

»CreateWindow«, »CreateWindowEx«


  CWPSTRUCT

typedef struct tagCWPSTRUCT { /* cwps */

    LPARAM lParam;

    WPARAM wParam;

    DWORD  message;

    HWND   hwnd;

} CWPSTRUCT;

The CWPSTRUCT structure defines the message parameters passed to a WH_CALLWNDPROC hook procedure.

Members

lParam

Specifies additional information about the message. The exact meaning depends on the message value.

wParam

Specifies additional information about the message. The exact meaning depends on the message value.

message

Specifies the message.

hwnd

Identifies the window to receive the message.

See Also

»SetWindowsHook«, »SetWindowsHookEx«


  DCB

typedef struct _DCB { /* dcb */

    DWORD DCBlength;           /* sizeof(DCB)                    */

    DWORD BaudRate;            /* current baud rate              */

    DWORD fBinary: 1;          /* binary mode, no EOF check      */

    DWORD fParity: 1;          /* enable parity checking         */

    DWORD fOutxCtsFlow:1;      /* CTS output flow control        */

    DWORD fOutxDsrFlow:1;      /* DSR output flow control        */

    DWORD fDtrControl:2;       /* DTR flow control type          */

    DWORD fDsrSensitivity:1;   /* DSR sensitivity                */

    DWORD fTXContinueOnXoff:1; /* XOFF continues Tx              */

    DWORD fOutX: 1;            /* XON/XOFF out flow control      */

    DWORD fInX: 1;             /* XON/XOFF in flow control       */

    DWORD fErrorChar: 1;       /* enable error replacement       */

    DWORD fNull: 1;            /* enable null stripping          */

    DWORD fRtsControl:2;       /* RTS flow control               */

    DWORD fAbortOnError:1;     /* abort reads/writes on error    */

    DWORD fDummy2:17;          /* reserved                       */

    WORD wReserved;            /* not currently used             */

    WORD XonLim;               /* transmit XON threshold         */

    WORD XoffLim;              /* transmit XOFF threshold        */

    BYTE ByteSize;             /* number of bits/byte, 4-8       */

    BYTE Parity;               /* 0-4=no,odd,even,mark,space     */

    BYTE StopBits;             /* 0,1,2 = 1, 1.5, 2              */

    char XonChar;              /* Tx and Rx XON character        */

    char XoffChar;             /* Tx and Rx XOFF character       */

    char ErrorChar;            /* error replacement character    */

    char EofChar;              /* end of input character         */

    char EvtChar;              /* received event character       */

} DCB;

The DCB structure defines the control setting for a serial communications device.

Members

DCBlength

Specifies the length, in bytes, of the DCB structure.

BaudRate

Specifies the baud rate at which the communications device operates.

fBinary

Specifies whether binary mode is enabled. Windows NT does not support non-binary mode transfers, so this member should be set TRUE. Trying to set it to FALSE, under Windows NT, will not work.

Under Windows 3.1, if this member is FALSE, non-binary mode is enabled, and the character specified by the EofChar member is recognized on input and remembered as the end of data.

fParity

Specifies whether parity checking is enabled. If this member is TRUE, parity checking is performed and errors are reported.

fOutxCtsFlow

Specifies whether the CTS (clear-to-send) signal is monitored for output flow control. If this member is TRUE, when CTS is turned off, output is suspended until CTS is sent again.

fOutxDsrFlow

Specifies whether the DSR (data-set-ready) signal is monitored for output flow control. If this member is TRUE, when DSR is turned off, output is suspended until DSR is sent again.

fDtrControl

Specifies the DTR (data-terminal-ready) flow control. This member  can be one of the following values:

Value	Description
DTR_CONTROL_DISABLE
	Disables the DTR line on device open and leaves it disabled.
DTR_CONTROL_ENABLE
	Enables the DTR line on device open and leaves it on.
DTR_CONTROL_HANDSHAKE
	Enables DTR handshaking. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.
fDsrSensitivity

Specifies whether the communications driver is sensitive to the state of the DSR signal. If this member is TRUE, the driver ignores any bytes received, unless the DSR modem input line is high.

fTXContinueOnXoff

Specifies whether transmission stops when the input buffer is full and the driver has transmitted the XoffChar character. If this member is TRUE, transmission continues after the input buffer has come within XoffLim bytes of being full and the driver has transmitted the XoffChar character to stop receiving bytes. If this member is FALSE, transmission does not continue until the input buffer is within XonLim bytes of being empty and the driver has transmitted the XonChar character to resume reception.

fOutX

Specifies whether XON/XOFF flow control is used during transmission. If this member is TRUE, transmission stops when the XoffChar character is received and starts again when the XonChar character is received.

fInX

Specifies whether XON/XOFF flow control is used during reception. If this member is TRUE, the XoffChar character is sent when the input buffer comes within XoffLim bytes of being full, and the XonChar character is sent when the input buffer comes within XonLim bytes of being empty.

fErrorChar

Specifies whether bytes received with parity errors are replaced with the character specified by the ErrorChar member. If this member is TRUE, and the fParity member is TRUE, replacement occurs.

fNull

Specifies whether null bytes are discarded. If this member is TRUE, null bytes are discarded when received.

fRtsControl

Specifies the RTS (request-to-send) flow control. If this flag is zero, the default is RTS_CONTROL_HANDSHAKE. This member can be one of the following values:

Value	Meaning
RTS_CONTROL_DISABLE
	Disables the RTS line when the device is opened and leaves it disabled.
RTS_CONTROL_ENABLE
	Enables the RTS line when the device is opened and leaves it on.
RTS_CONTROL_HANDSHAKE
	Enables RTS handshaking. The driver raises the RTS line when the "type-ahead" (input) buffer is less than one-half full and lowers the RTS line when the buffer is more than three-quarters full. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.
RTS_CONTROL_TOGGLE
	Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low.
fAbortOnError

Specifies whether read and write operations are terminated if an error occurs. If this member is TRUE, the driver terminates all read and write operations with an error status if an error occurs. The driver will not accept any further communications operations until the application has acknowledged the error by calling the ClearCommError function.

fdummy2

Reserved; do not use.

wReserved

Not used; must be set to zero.

XonLim

Specifies the minimum number of bytes allowed in the input buffer before the XON character is sent.

XoffLim

Specifies the maximum number of bytes allowed in the input buffer before the XOFF character is sent. To calculate the maximum number of bytes allowed, this value is subtracted from the size, in bytes, of the input buffer.

ByteSize

Specifies the number of bits in the bytes transmitted and received.

Parity

Specifies the parity scheme to be used. This member can be one of the following values:

Value	Meaning
EVENPARITY	Even
MARKPARITY	Mark
NOPARITY	No parity
ODDPARITY	Odd
StopBits

Specifies the number of stop bits to be used. This member can be one of the following values:

Value	Meaning
ONESTOPBIT	1 stop bit
ONE5STOPBITS	1.5 stop bits
TWOSTOPBITS	2 stop bits
XonChar

Specifies the value of the XON character for both transmission and reception.

XoffChar

Specifies the value of the XOFF character for both transmission and reception.

ErrorChar

Specifies the value of the character used to replace bytes received with a parity error.

EofChar

Specifies the value of the character used to signal the end of data.

EvtChar

Specifies the value of the character used to signal an event.

Comments

When a DCB structure is used to configure the 8250, the following restrictions apply to the values specified for the the ByteSize and StopBits members:

•	The number of data bits must be 5 to 8 bits.

•	The use of 5 data bits with 2 stop bits is an invalid combination, as is 6, 7, or 8 data bits with 1.5 stop bits.

See Also

»BuildCommDCB«, »GetCommState«, »SetCommState«


  DDEACK

typedef struct { /* ddeack */

    unsigned short bAppReturnCode:8,

    reserved:6,

    fBusy:1,

    fAck:1;

} DDEACK;

The DDEACK structure contains status flags that a dynamic data exchange (DDE) application passes to its partner as part of the WM_DDE_ACK message. The flags provide details about the application's response to a WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_EXECUTE, WM_DDE_REQUEST, WM_DDE_POKE, or WM_DDE_UNADVISE message.

Members

bAppReturnCode

Specifies an application-defined return code.

fBusy

Indicates whether the application was busy and unable to respond to the partner's message at the time the message was received. A nonzero value indicates the partner was busy and unable to respond. The fBusy member is defined only when the fAck member is zero.

fAck

Indicates whether the application accepted the message from its partner. A nonzero value indicates the partner accepted the message.

See Also

»WM_DDE_ACK«, »WM_DDE_ADVISE«, »WM_DDE_DATA«, »WM_DDE_EXECUTE«, »WM_DDE_REQUEST«, »WM_DDE_POKE«, »WM_DDE_UNADVISE«


  DDEADVISE

typedef struct { /* ddeadv */

    unsigned short reserved:14,

        fDeferUpd:1,

        fAckReq:1;

    short cfFormat;

} DDEADVISE;

The DDEADVISE structure contains flags that specify how a dynamic data exchange (DDE) server application should send data to a client application during an advise loop. A client passes the handle of a DDEADVISE structure to a server as part of a WM_DDE_ADVISE message.

Members

fDeferUpd

Indicates whether the server should defer sending updated data to the client. If this value is nonzero, the server should send a WM_DDE_DATA message with a NULL data handle whenever the data item changes. In response, the client can post a WM_DDE_REQUEST message to the server to get a handle of the updated data.

fAckReq

Indicates whether the server should set the fAckReq flag in the WM_DDE_DATA messages it posts to the client. If this value is nonzero, the server should set the fAckReq bit.

cfFormat

Specifies the client application's preferred data format. The format must be a standard or registered clipboard format. The following standard clipboard formats can be used:

CF_BITMAP
CF_DIB
CF_DIF
CF_ENHMETAFILE
CF_METAFILEPICT
CF_OEMTEXT
CF_PALETTE
CF_PENDATA
CF_RIFF
CF_SYLK
CF_TEXT
CF_TIFF
CF_WAVE
CF_UNICODETEXT

See Also

»WM_DDE_ADVISE«, »WM_DDE_DATA«, »WM_DDE_UNADVISE«


  DDEDATA

typedef struct { /* ddedat */

    unsigned short unused:12,

        fResponse:1,

        fRelease:1,

        reserved:1,

        fAckReq:1;

    short cfFormat;

    BYTE  Value[1];

} DDEDATA;

The DDEDATA structure contains the data, and information about the data, sent as part of a WM_DDE_DATA message.

Members

fResponse

Indicates whether the application receiving the WM_DDE_DATA message should acknowledge receipt of the data by sending a WM_DDE_ACK message. If this value is nonzero, the application should send the acknowledgment.

fRelease

Indicates whether the application receiving the WM_DDE_POKE message should free the data. If this value is nonzero, the application should free the data.

fAckReq

Indicates whether the data was sent in response to a WM_DDE_REQUEST message or a WM_DDE_ADVISE message. If this value is nonzero, the data was sent in response to a WM_DDE_REQUEST message.

cfFormat

Specifies the format of the data. The format should be a standard or registered clipboard format. The following standard clipboard formats can be used:

CF_BITMAP
CF_DIB
CF_DIF
CF_ENHMETAFILE
CF_METAFILEPICT
CF_OEMTEXT
CF_PALETTE
CF_PENDATA
CF_RIFF
CF_SYLK
CF_TEXT
CF_TIFF
CF_WAVE
CF_UNICODETEXT

Value[1]

Contains the data. The length and the type of data depends on the cfFormat member.

See Also

»WM_DDE_ACK«, »WM_DDE_ADVISE«, »WM_DDE_DATA«, »WM_DDE_POKE«, »WM_DDE_REQUEST«


  DDELN

typedef struct { /* ddeln */

    unsigned short unused:13,

        fRelease:1,

        fDeferUpd:1,

        fAckReq:1;

    short cfFormat;

} DDELN;

The DDELN structure is obsolete. Win32 applications should use the DDEADVISE structure.

See Also

»DDEADVISE«, »WM_DDE_ADVISE«, »WM_DDE_UNADVISE«


  DDEML_MSG_HOOK_DATA

typedef struct tagDDEML_MSG_HOOK_DATA { /* dmhd */

    UINT  uiLo;

    UINT  uiHi;

    DWORD cbData;

    DWORD Data[8];

} DDEML_MSG_HOOK_DATA;

The DDEML_MSG_HOOK_DATA structure contains information about a dynamic data exchange (DDE) message, and provides read access to the data referenced by the message. This structure is intended to be used by a DDE Management Library (DDEML) monitoring application.

Members

uiLo

Specifies the unpacked low-order word of the lParam parameter associated with the DDE message.

uiHi

Specifies the unpacked high-order word of the lParam parameter associated with the DDE message.

cbData

Specifies the amount, in bytes, of data being passed with the message. This value can be greater than 32.

Data

Contains the first 32 bytes of data being passed with the message (8 * sizeof(DWORD)).

See Also

»MONCBSTRUCT«, »MONCONVSTRUCT«, »MONERRSTRUCT«, »MONHSZSTRUCT«, »MONLINKSTRUCT«, »MONMSGSTRUCT«


  DDEPOKE

typedef struct { /* ddepok */

    unsigned short unused:13,

        fRelease:1,

        fReserved:2;

    short cfFormat;

    BYTE  Value[1];

} DDEPOKE;

The DDEPOKE structure contains the data, and information about the data, sent as part of a WM_DDE_POKE message.

Members

fRelease

Indicates whether the application receiving the WM_DDE_POKE message should free the data. If this value is nonzero, the application should free the data.

fReserved

Reserved; do not use.

cfFormat

Specifies the format of the data. The format should be a standard or registered clipboard format. The following standard clipboard formats can be used:

CF_BITMAP
CF_DIB
CF_DIF
CF_ENHMETAFILE
CF_METAFILEPICT
CF_OEMTEXT
CF_PALETTE
CF_PENDATA
CF_RIFF
CF_SYLK
CF_TEXT
CF_TIFF
CF_WAVE
CF_UNICODETEXT

Value

Contains the data. The length and type of data depends on the value of the cfFormat member.

See Also

»WM_DDE_POKE«


  DDEUP

typedef struct { /* ddeup */

    unsigned short unused:12,

        fAck:1,

        fRelease:1,

        fReserved:1,

        fAckReq:1;

    short cfFormat;

    BYTE rgb[1];

} DDEUP;

The DDEUP structure is obsolete. Win32 applications should use the DDEDATA and DDEPOKE structures.

See Also

»DDEDATA«, »DDEPOKE«, »WM_DDE_DATA«, »WM_DDE_POKE«


  DEBUG_EVENT

typedef struct _DEBUG_EVENT { /* de */

    DWORD dwDebugEventCode;

    DWORD dwProcessId;

    DWORD dwThreadId;

    union {

        EXCEPTION_DEBUG_INFO Exception;

        CREATE_THREAD_DEBUG_INFO CreateThread;

        CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;

        EXIT_THREAD_DEBUG_INFO ExitThread;

        EXIT_PROCESS_DEBUG_INFO ExitProcess;

        LOAD_DLL_DEBUG_INFO LoadDll;

        UNLOAD_DLL_DEBUG_INFO UnloadDll;

        OUTPUT_DEBUG_STRING_INFO DebugString;

        RIP_INFO RipInfo;

    } u;

} DEBUG_EVENT;

The DEBUG_EVENT structure describes a debugging event.

Members

dwDebugEventCode

Specifies a debugging event code that identifies the type of debugging event. This parameter can be one of the following values:

Value	Meaning
EXCEPTION_DEBUG_EVENT
	Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure.
CREATE_THREAD_DEBUG_EVENT
	Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure.
CREATE_PROCESS_DEBUG_EVENT
	Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure.
EXIT_THREAD_DEBUG_EVENT
	Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure.
EXIT_PROCESS_DEBUG_EVENT
	Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure.
LOAD_DLL_DEBUG_EVENT
	Reports a load-DLL debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure.
UNLOAD_DLL_DEBUG_EVENT
	Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure.
OUTPUT_DEBUG_STRING_EVENT
	Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure.
RIP_EVENT
	Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure.
dwProcessId

Specifies the identifier of the process in which the debugging event occurred. A debugger uses this value to locate the debugger's per-process structure. These values are not necessarily small integers that can be used as table indices.

dwThreadId

Specifies the identifier of the thread in which the debugging event occurred. A debugger uses this value to locate the debugger's per-thread structure. These values are not necessarily small integers that can be used as table indices.

u

Specifies additional information relating to the debugging event. This union takes on the type and value appropriate to the type of debugging event, as described in the dwDebugEventCode member.

Comments

If the WaitForDebugEvent function succeeds, it fills in the members of a DEBUG_EVENT structure.

See Also

»WaitForDebugEvent«


  DEBUGHOOKINFO

typedef struct tagDEBUGHOOKINFO { /* dh */

    DWORD  idThread;

    LPARAM reserved;

    LPARAM lParam;

    WPARAM wParam;

    int    code;

} DEBUGHOOKINFO;

The DEBUGHOOKINFO structure contains debugging information.

Members

idThread

Identifies the thread containing the filter function.

reserved

Not used.

lParam

Specifies the value to be passed to the hook in the lParam parameter of the DebugProc callback function.

wParam

Specifies the value to be passed to the hook in the wParam parameter of the DebugProc callback function.

code

Specifies the value to be passed to the hook in the nCode parameter of the DebugProc callback function.

See Also

»DebugProc«, »SetWindowsHook«


  DELETEITEMSTRUCT

typedef struct tagDELETEITEMSTRUCT { /* ditms */

    UINT CtlType;

    UINT CtlID;

    UINT itemID;

    HWND hwndItem;

    UINT itemData;

} DELETEITEMSTRUCT;

The DELETEITEMSTRUCT structure describes a deleted owner-drawn list-box or combo-box item. When an item is removed from the list box or combo box or when the list box or combo box is destroyed, Windows sends the WM_DELETEITEM message to the owner for each deleted item. The lParam parameter of the message contains a pointer to this structure.

Members

CtlType

Specifies ODT_LISTBOX (an owner-drawn list box) or ODT_COMBOBOX (an owner-drawn combo box).

CtlID

Specifies the identifier of the list box or combo box.

itemID

Specifies index of the item in the list box or combo box being removed.

hwndItem

Identifies the control.

itemData

Specifies application-defined data for the item. This value is passed to the control in the lParam parameter of the message that adds the item to the list box or combo box.

See Also

»WM_DELETEITEM«


  DEVMODE

typedef struct _devicemode {    /* dvmd */

    TCHAR  dmDeviceName[32];

    WORD   dmSpecVersion;

    WORD   dmDriverVersion;

    WORD   dmSize;

    WORD   dmDriverExtra;

    DWORD  dmFields;

    short  dmOrientation;

    short  dmPaperSize;

    short  dmPaperLength;

    short  dmPaperWidth;

    short  dmScale;

    short  dmCopies;

    short  dmDefaultSource;

    short  dmPrintQuality;

    short  dmColor;

    short  dmDuplex;

    short  dmYResolution;

    short  dmTTOption;

    short  dmCollate;

    TCHAR  dmFormName[32];

    WORD   dmUnusedPadding;

    USHORT dmBitsPerPel;

    DWORD  dmPelsWidth;

    DWORD  dmPelsHeight;

    DWORD  dmDisplayFlags;

    DWORD  dmDisplayFrequency;

} DEVMODE;

The DEVMODE data structure contains information about the device initialization and environment of a printer.

Members

dmDeviceName

Specifies the name of the device the driver supports; for example, "PCL/HP LaserJet" in the case of PCL/HP LaserJet®. This string is unique among device drivers.

dmSpecVersion

Specifies the version number of the initialization data specification on which the structure is based.

dmDriverVersion

Specifies the printer driver version number assigned by the printer driver developer.

dmSize

Specifies the size, in bytes, of the DEVMODE structure except the dmDriverData (device-specific) member. If an application manipulates only the driver-independent portion of the data, it can use this member to determine the length of the structure without having to account for different versions.

dmDriverExtra

Contains the number of bytes of private driver-data that follow this structure. If a device driver does not use device-specific information, set this member to zero.

dmFields

Specifies which of the remaining members in the DEVMODE structure have been initialized. Bit 0 (defined as DM_ORIENTATION) corresponds to dmOrientation; bit 1 (defined as DM_PAPERSIZE) specifies dmPaperSize, and so on. A printer driver supports only those members that are appropriate for the printer technology.

dmOrientation

Selects the orientation of the paper. This member can be either DMORIENT_PORTRAIT (1) or DMORIENT_LANDSCAPE (2).

dmPaperSize

Selects the size of the paper to print on. This member can be set to zero if the length and width of the paper are both set by the dmPaperLength and dmPaperWidth members. Otherwise, the dmPaperSize member can be set to one of the following predefined values:

Value	Meaning
DMPAPER_LETTER	Letter, 8 1/2- by 11-inches
MPAPER_LEGAL	Legal, 8 1/2- by 14-inches
DMPAPER_A4	A4 Sheet, 210- by 297-millimeters
DMPAPER_CSHEET	C Sheet, 17- by 22-inches
DMPAPER_DSHEET	D Sheet, 22- by 34-inches
DMPAPER_ESHEET	E Sheet, 34- by 44-inches
DMPAPER_LETTERSMALL	Letter Small, 8 1/2- by 11-inches
DMPAPER_TABLOID	Tabloid, 11- by 17-inches
DMPAPER_LEDGER	Ledger, 17- by 11-inches
DMPAPER_STATEMENT	Statement, 5 1/2- by 8 1/2-inches
DMPAPER_EXECUTIVE	Executive, 7 1/4- by 10 1/2-inches
DMPAPER_A3	A3 sheet, 297- by 420-millimeters
DMPAPER_A4SMALL	A4 small sheet, 210- by 297-millimeters
DMPAPER_A5	A5 sheet, 148- by 210-millimeters
DMPAPER_B4	B4 sheet, 250- by 354-millimeters
DMPAPER_B5	B5 sheet, 182- by 257-millimeter paper
DMPAPER_FOLIO	Folio, 8 1/2- by 13-inch paper
DMPAPER_QUARTO	Quarto, 215- by 275-millimeter paper
DMPAPER_10X14	10- by 14-inch sheet
DMPAPER_11X17	11- by 17-inch sheet
DMPAPER_NOTE	Note, 8 1/2- by 11-inches
DMPAPER_ENV_9	#9 Envelope, 3 7/8- by 8 7/8-inches
DMPAPER_ENV_10	#10 Envelope, 4 1/8- by 9 1/2-inches
DMPAPER_ENV_11	#11 Envelope, 4 1/2- by 10 3/8-inches
DMPAPER_ENV_12	#12 Envelope, 4 3/4- by 11-inches
DMPAPER_ENV_14	#14 Envelope, 5- by 11 1/2-inches
DMPAPER_ENV_DL	DL Envelope, 110- by 220-millimeters
DMPAPER_ENV_C5	C5 Envelope, 162- by 229-millimeters
DMPAPER_ENV_C3	C3 Envelope,  324- by 458-millimeters
DMPAPER_ENV_C4	C4 Envelope,  229- by 324-millimeters
DMPAPER_ENV_C6	C6 Envelope,  114- by 162-millimeters
DMPAPER_ENV_C65	C65 Envelope, 114- by 229-millimeters
DMPAPER_ENV_B4	B4 Envelope,  250- by 353-millimeters
DMPAPER_ENV_B5	B5 Envelope,  176- by 250-millimeters
DMPAPER_ENV_B6	B6 Envelope,  176- by 125-millimeters
DMPAPER_ENV_ITALY	Italy Envelope, 110- by 230-millimeters
DMPAPER_ENV_MONARCH	Monarch Envelope, 3 7/8- by 7 1/2-inches
DMPAPER_ENV_PERSONAL	6 3/4 Envelope, 3 5/8- by 6 1/2-inches
DMPAPER_FANFOLD_US	US Std Fanfold, 14 7/8- by 11-inches
DMPAPER_FANFOLD_STD_GERMAN	German Std Fanfold, 8 1/2- by 12-inches
DMPA PER_FANFOLD_LGL_GERMAN	German Legal Fanfold, 8 1/2- by 13-inches
dmPaperLength

Overrides the length of the paper specified by the dmPaperSize member, either for custom paper sizes or for devices such as dot-matrix printers, which can print on a page of arbitrary length. These values, along with all other values in this structure that specify a physical length, are in tenths of a millimeter.

dmPaperWidth

Overrides the width of the paper specified by the dmPaperSize member.

dmScale

Specifies the factor by which the printed output is to be scaled. The apparent page size is scaled from the physical page size by a factor of dmScale/100. For example, a letter-sized page with a dmScale value of 50 would contain as much data as a page of 17- by 22-inches because the output text and graphics would be half their original height and width.

dmCopies

Selects the number of copies printed if the device supports multiple-page copies.

dmDefaultSource

Reserved; must be zero.

dmPrintQuality

Specifies the printer resolution. There are four predefined device-independent values:

DMRES_HIGH
DMRES_MEDIUM
DMRES_LOW
DMRES_DRAFT

If a positive value is given, it specifies the number of dots per inch (DPI) and is therefore device dependent.

dmColor

Switches between color and monochrome on color printers. Following are the possible values:

DMCOLOR_COLOR
DMCOLOR_MONOCHROME

dmDuplex

Selects duplex or double-sided printing for printers capable of duplex printing. Following are the possible values:

DMDUP_SIMPLEX
DMDUP_HORIZONTAL
DMDUP_VERTICAL

dmYResolution

Specifies the y-resolution, in dots per inch, of the printer. If the printer initializes this member, the dmPrintQuality member specifies the x-resolution, in dots per inch, of the printer.

dmTTOption

Specifies how TrueType® fonts should be printed. This member can be one of the following values:

Value	Meaning
DMTT_BITMAP	Prints TrueType fonts as graphics. This is the default action for dot-matrix printers.
DMTT_DOWNLOAD	Downloads TrueType fonts as soft fonts. This is the default action for Hewlett-Packard printers that use Printer Control Language (PCL).
DMTT_SUBDEV	Substitute device fonts for TrueType fonts. This is the default action for PostScript® printers.
dmUnusedPadding

Used to align the structure to a DWORD boundary. This should not be used or referenced. Its name and usage is reserved, and can change in future releases.

dmCollate

Specifies whether collation should be used when printing multiple copies. This member can be be one of the following values:

Value	Meaning
DMCOLLATE_TRUE	Collate when printing multiple copies.
DMCOLLATE_FALSE	Do NOT collate when printing multiple copies.
Using DMCOLLATE_FALSE provides faster, more efficient output, since the data is sent to a page printer just once, no matter how many copies are required. The printer is told to simply print the page again.

dmFormName

Specifies the name of the form to use; for example, "Letter" or "Legal". A complete set of names can be retrieved through the EnumForms function.

dmBitsPerPel

Specifies in bits per pixel the color resolution of the display device. For example: 4 bits for 16 colors, 8 bits for 256 colors, or 16 bits for 65536 colors.

dmPelsWidth

Specifies the width, in pixels, of the visible device surface.

dmPelsHeight

Specifies the height, in pixels, of the visible device surface.

dmDisplayFlags

Specifies the device's display mode. The following are valid flags:

Value	Meaning
DM_GRAYSCALE	Specifies that the display is a NON-color device. If this flag is not set, color is assumed.
DM_INTERLACED	Specifies that the display mode is interlaced. If the flag is not set, NON-interlaced is assumed.
dmDisplayFrequency

Specifies the frequency, in hertz (cycles per second), of the display device in a particular mode.

Comments

A device driver's private data will follow the dmDisplayMode member. The number of bytes of private data is specified by the dmDriverExtra member.

See Also

»AdvancedDocumentProperties«, »CreateDC«, »CreateIC«, »DeviceCapabilitiesEx«, »DocumentProperties«, »OpenPrinter«


  DEVNAMES

typedef struct tagDEVNAMES { /* dvnm */

    WORD wDriverOffset;

    WORD wDeviceOffset;

    WORD wOutputOffset;

    WORD wDefault;

    /* driver, device, and port-name strings follow wDefault */

} DEVNAMES;

The DEVNAMES structure contains strings that identify the driver, device, and output-port names for a printer. The PrintDlg function uses these strings to initialize members in the system-defined Print dialog box. When the user closes the dialog box, information about the selected printer is returned in this structure.

Members

wDriverOffset

(Input/Output) Specifies the offset to a null-terminated string that contains the MS-DOS filename (without the extension) of the device driver. On input, this string is used to determine the printer to display initially in the dialog box.

wDeviceOffset

(Input/Output) Specifies the offset to the null-terminated string (maximum of 32 bytes including the null) that contains the name of the device. This string must be identical to the dmDeviceName member of the DEVMODE structure.

wOutputOffset

(Input/Output) Specifies the offset to the null-terminated string that contains the MS-DOS device name for the physical output medium (output port).

wDefault

Specifies whether the strings contained in the DEVNAMES structure identify the default printer. This string is used to verify that the default printer has not changed since the last print operation. On input, if the DN_DEFAULTPRN flag is set, the other values in the DEVNAMES structure are checked against the current default printer. If any of the strings do not match, a warning message is displayed informing the user that the document may need to be reformatted.

On output, the wDefault member is changed only if the Print Setup dialog box was displayed and the user chose the OK button. The DN_DEFAULTPRN flag is set if the default printer was selected. If a specific printer is selected, the flag is not set. All other bits in this member are reserved for internal use by the Print Dialog box procedure.

See Also

»PrintDlg«


  DISK_GEOMETRY

typedef struct _DISK_GEOMETRY {

   MEDIA_TYPE  MediaType;

   LARGE_INTEGER  Cylinders;

   DWORD  TracksPerCylinder;

   DWORD  SectorsPerTrack;

   DWORD  BytesPerSector;

} DISK_GEOMETRY ;

The DISK_GEOMETRY structure describes the geometry of disk devices and media.

Members

MediaType

The type of media. See »MEDIA_TYPE«.

Cylinders

The number of cylinders.

TracksPerCylinder

The number of tracks per cylinder.

SectorsPerTrack

The number of sectors per track.

BytesPerSector

The number of bytes per sector

Comments

The DeviceIoControl function receives a DISK_GEOMETRY structure in response to an IOCTL_DISK_GET_DRIVE_GEOMETRY device i/o operation. The DeviceIoControl function receives an array of DISK_GEOMETRY structures in response to an IOCTL_DISK_GET_MEDIA_TYPES device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_GET_DRIVE_GEOMETRY«, »IOCTL_DISK_GET_MEDIA_TYPES«, »MEDIA_TYPE«


  DISK_PERFORMANCE

typedef struct _DISK_PERFORMANCE {

        LARGE_INTEGER BytesRead;

        LARGE_INTEGER BytesWritten;

        LARGE_INTEGER ReadTime;

        LARGE_INTEGER WriteTime;

        DWORD ReadCount;

        DWORD WriteCount;

        DWORD QueueDepth;

} DISK_PERFORMANCE ;

The DISK_PERFORMANCE structure provides disk performance information.

Members

BytesRead

Specifies the number of bytes read.

BytesWritten

Specifies the number of bytes written.

ReadTime

Specifies the time it took to complete the read.

WriteTime

The time it took to complete the write.

ReadCount

Specifies the number of read operations.

WriteCount

Specifies the number of write operations.

QueueDepth

Specifies the depth of the queue.

Comments

The DeviceIoControl function receives a DISK_PERFORMANCE structure in response to an IOCTL_DISK_PERFORMANCE device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_PERFORMANCE«


  DLGITEMTEMPLATE

typedef struct { /* dlit */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

    WORD  id;

} DLGITEMTEMPLATE;

The DLGITEMTEMPLATE structure defines the dimensions and style of a control in a dialog box. One or more of these structures are combined with a DLGTEMPLATE structure to form a dialog box template.

Members

style

Specifies the style of the control. This member can be a combination of window style values (such as WS_BORDER) and one or more of the control style values (such as BS_PUSHBUTTON and ES_LEFT).

dwExtendedStyle

Specifies extended styles for a window. This member is not used to create controls in dialog boxes, but applications that use dialog box templates can use it to create other types of windows.

x

Specifies the x-coordinate, in dialog units, of the upper left corner of the control. This coordinate is always relative to the upper left corner of the dialog box's client area.

y

Specifies the y-coordinate, in dialog units, of the upper left corner of the control. This coordinate is always relative to the upper left corner of the dialog box's client area.

cx

Specifies the width, in dialog units, of the control.

cy

Specifies the height, in dialog units, of the control.

id

Specifies the control identifier.

Comments

In a dialog box template, the DLGITEMTEMPLATE structure is always immediately followed by three variable-length arrays specifying the class, title, and creation data for the control. Each array consists of one or more 16-bit elements.

The class array follows the DLGITEMTEMPLATE structure. When the first element of this array is 0xFFFF, the array has one additional element that specifies an atom value identifying a registered window class. When the first element has any other value, Windows assumes the array is a null-terminated Unicode string that specifies the name of a registered window class. Following are the class atom values for predefined controls:

Value	Meaning
0x0080	Button
0x0081	Edit
0x0082	Static
0x0083	List box
0x0084	Scroll bar
0x0085	Combo box
The title array follows the class array. When the first element is 0xFFFF, the array has one additional element that specifies the identifier of a resource, such as an icon, in an executable file. Resource identifiers are usually given for controls, such as static icon controls, that load and display an icon or other resources rather than text. When the first element is any other value, Windows assumes the array is a null-terminated Unicode string that specifies the initial text for the control.

The creation data array follows the text array. This array can contain any number of elements; the control's window procedure must understand the content and format of the data. Windows passes this data to the control when it calls the CreateWindowEx function.

The x, y, cx, and cy members specify values in dialog units. You can convert these values to screen units (pixels) by using the MapDialogRect function.

See Also

»CreateDialogIndirect«, »CreateDialogIndirectParam«, »CreateWindowEx«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »MapDialogRect«


  DLGTEMPLATE

typedef struct { /* dltt */

    DWORD style;

    DWORD dwExtendedStyle;

    WORD  cdit;

    WORD  x;

    WORD  y;

    WORD  cx;

    WORD  cy;

} DLGTEMPLATE;

The DLGTEMPLATE structure defines the dimensions and style of a dialog box. This structure, always the first in a dialog box template, also specifies the number of controls in the dialog box and therefore specifies the number of subsequent DLGITEMTEMPLATE structures in the template.

Members

style

Specifies the style of the dialog box. This member can be a combination of window style values (such as WS_CAPTION and WS_SYSMENU) and one or more of the following dialog box style values:

Value	Meaning
DS_ABSALIGN	Specifies that the dialog box position is relative to the upper-left corner of the screen. If this style is not given, the position is relative to the upper-left corner of the owner window's client area.
DS_MODALFRAME	Specifies a dialog box with a modal dialog box border.
DS_NOIDLEMSG	Prevents Windows from sending the WM_ENTERIDLE messages to the owner window when no messages are in the application queue. This value applies to modal dialog boxes only.
DS_SETFONT	Specifies that a font other than the system font is used to draw text in the dialog box and its controls. When this value is given, the dialog box template must specify a point size and typeface name as described in the "Comments" section.
DS_SETFOREGROUND	Specifies that the application creating the dialog box is to be made the foreground task. Windows calls the SetForegroundWindow function to set the foreground task.
The DS_LOCALEDIT and DS_SYSMODAL styles are not fully supported in Windows NT. DS_LOCALEDIT applies only to applications written for Windows 3.x. DS_SYSMODAL creates a dialog box having the WS_EX_TOPMOST style but does not cause the system to disable all other windows.

dwExtendedStyle

Specifies extended styles for a window. This member is not used to create dialog boxes, but applications that use dialog box templates can use it to create other types of windows.

cdit

Specifies the number of items in the dialog box.

x

Specifies the x-coordinate, in dialog units, of the upper left corner of the dialog box.

y

Specifies the y-coordinate, in dialog units, of the upper left corner of the dialog box

cx

Specifies the width, in dialog units, of the dialog box.

cy

Specifies the height, in dialog units, of the dialog box.

Comments

In a dialog box template, the DLGTTEMPLATE structure is always immediately followed by three variable-length arrays that specify the menu, class, and title for the dialog box. When the DS_SETFONT style is given, these arrays are also followed by a 16-bit value specifying point size and another variable-length array specifying a typeface name. Each array consists of one or more 16-bit elements.

The menu array follows the DLGTEMPLATE structure. When the first element of this array is 0x0000, the dialog box has no menu and the array has no other elements. When the first element is 0xFFFF, the array has one additional element that specifies the resource identifier for a menu resource in an executable file. If the first element has any other value, Windows assumes the array is a null-terminated Unicode string that specifies the name of the menu resource in an executable file.

The class array follows the menu array. When the first element of the array is 0x0000, Windows uses the predefined dialog box class for the dialog box. When the first element is 0xFFFF, the array has one additional element that specifies the atom value identifying a registered window class. When the first element has any other value, Windows assumes the array is a null-terminated Unicode string that specifies the name of a registered window class.

The title array follows the class array. When the first element of the array is 0x0000, the dialog box has no title. When the first element has any other value, Windows assumes the array is a null-terminated Unicode string that specifies the title.

The 16-bit point size value and the typeface array follow the title array, but only if the style member gives the DS_SETFONT style. The point size value specifies the size in points of the font to use for the text in the dialog box and its controls. The typeface array is a null-terminated Unicode string specifying the name of the typeface for the font. When these values are given, Windows creates a font having the given size and typeface (if possible) and sends a WM_SETFONT message to the dialog box procedure and the control window procedures as it creates the dialog box and controls.

Every dialog box template also contains the number of DLGITEMTEMPLATE structures as given by the cdit member. These structures define the dimensions and style of the controls in the dialog box.

The x, y, cx, and cy members specify values in dialog units. You can convert these values to screen units (pixels) by using the MapDialogRect function.

See Also

»CreateDialogIndirect«, »CreateDialogIndirectParam«, »DialogBoxIndirect«, »DialogBoxIndirectParam«, »MapDialogRect«


  DOCINFO

typedef struct {    /* di */

    int    cbSize;

    LPTSTR lpszDocName;

    LPTSTR lpszOutput;

} DOCINFO;

The DOCINFO structure contains the input and output filenames used by the StartDoc function.

Members

cbSize

Specifies the size, in bytes, of the structure.

lpszDocName

Points to a null-terminated string that specifies the name of the document.

pszOutput

Points to a null-terminated string that specifies the name of an output file. If this pointer is NULL, the output will be sent to the device identified by the DC handle which was passed to the StartDoc function.

See Also

»StartDoc«


  DOC_INFO_1

typedef struct _DOC_INFO_1 { /* dci1 */

    LPTSTR pDocName;

    LPTSTR pOutputFile;

    LPTSTR pDatatype;

} DOC_INFO_1;

The DOC_INFO_1 structure describes a document that will be printed.

Members

pDocName

Points to a null-terminated string that specifies the name of the document.

pOutputFile

Points to a null-terminated string that specifies the name of an output file.

pDatatype

Points to a null-terminated string that identifies the type of data used to record the document.

See Also

»StartDocPrinter«


  DRAWITEMSTRUCT

typedef struct tagDRAWITEMSTRUCT {  /* dis */

    UINT  CtlType;

    UINT  CtlID;

    UINT  itemID;

    UINT  itemAction;

    UINT  itemState;

    HWND  hwndItem;

    HDC   hDC;

    RECT  rcItem;

    DWORD itemData;

} DRAWITEMSTRUCT;

The DRAWITEMSTRUCT structure provides information the owner window must have to determine how to paint an owner-drawn control or menu item. The owner window of the owner-drawn control or menu item receives a pointer to this structure as the lParam parameter of the WM_DRAWITEM message.

Members

CtlType

Specifies the control type. This member can be one of the following values:

Value	Meaning
ODT_BUTTON	Owner-drawn button
ODT_COMBOBOX	Owner-drawn combo box
ODT_LISTBOX	Owner-drawn list box
ODT_MENU	Owner-drawn menu item
CtlID

Specifies the identifier of the combo box, list box, or button. This member is not used for a menu item.

itemID

Specifies the menu item identifier for a menu item or the index of the item in a list box or combo box. For an empty list box or combo box, this member can be −1. This allows the application to draw only the focus rectangle at the coordinates specified by the rcItem member even though there are no items in the control. This indicates to the user whether the list box or combo box has the focus. How the bits are set in the itemAction member determines whether the rectangle is to be drawn as though the list box or combo box has the focus.

itemAction

Specifies the drawing action required. This member can be one or more of the following values:

Value	Meaning
ODA_DRAWENTIRE	The entire control needs to be drawn.
ODA_FOCUS	The control has lost or gained the keyboard focus. The itemState member should be checked to determine whether the control has the focus.
ODA_SELECT	The selection status has changed. The itemState member should be checked to determine the new selection state.
itemState

Specifies the visual state of the item after the current drawing action takes place. This member can be a combination of the following values:

Value	Meaning
ODS_CHECKED	The menu item is to be checked. This bit is used only in a menu.
ODS_DISABLED	The item is to be drawn as disabled.
ODS_FOCUS	The item has the keyboard focus.
ODS_GRAYED	The item is to be grayed. This bit is used only in a menu.
ODS_SELECTED	The menu item's status is selected.
hwndItem

Identifies the control for combo boxes, list boxes, and buttons. For menus, this member identifies the menu containing the item.

hDC

Identifies a device context (DC); this DC must be used when performing drawing operations on the control.

rcItem

Specifies a rectangle that defines the boundaries of the control to be drawn. This rectangle is in the DC specified by the hDC member. Windows automatically clips anything the owner window draws in the DC for combo boxes, list boxes, and buttons, but does not clip menu items. When drawing menu items, the owner window must not draw outside the boundaries of the rectangle defined by the rcItem member.

itemData

Specifies the application-defined 32-bit value associated with the menu item. For a control, this parameter specifies the value last assigned to the list box or combo box by the LB_SETITEMDATA or CB_SETITEMDATA message. If the list box or combo box has the LB_HASSTRINGS or CB_HASSTRINGS style, this value is initially zero. Otherwise, this value is initially the value that was passed to the list box or combo box in the lParam parameter of one of the following messages:

CB_ADDSTRING
CB_INSERTSTRING
LB_ADDSTRING
LB_INSERTSTRING


  DRIVE_LAYOUT_INFORMATION

typedef struct _DRIVE_LAYOUT_INFORMATION {

   DWORD  PartitionCount;

   DWORD  Signature;

   PARTITION_INFORMATION  PartitionEntry[1];

} DRIVE_LAYOUT_INFORMATION;

The DRIVE_LAYOUT_INFORMATION structure provides information about a drive's partitions.

Members

PartitionCount

The number of partitions on the drive.

Signature

A drive signature value.

PartitionEntry[1]

A variable-sized array of PARTITION_INFORMATION structures, one structure for each partition on the drive.

Comments

The DeviceIoControl function receives a DRIVE_LAYOUT_INFORMATION structure in response to an IOCTL_GET_DRIVE_LAYOUT device i/o operation. The DeviceIoControl function  uses a DRIVE_LAYOUT_INFORMATION structure as input to an IOCTL_SET_DRIVE_LAYOUT device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_GET_DRIVE_LAYOUT«, »IOCTL_DISK_SET_DRIVE_LAYOUT«, »PARTITION_INFORMATION«


  DRIVER_INFO_1

typedef struct _DRIVER_INFO_1 { /* dri1 */

    LPTSTR pName;

} DRIVER_INFO_1;

The DRIVER_INFO_1 structure identifies a printer driver.

Members

pName

Points to a null-terminated string that specifies the name of a printer driver.

See Also

»EnumPrinterDrivers«


  DRIVER_INFO_2

typedef struct _DRIVER_INFO_2 { /* dri2 */

    DWORD  cVersion;

    LPTSTR pName;

    LPTSTR pEnvironment;

    LPTSTR pDriverPath;

    LPTSTR pDataFile;

    LPTSTR pConfigFile;

} DRIVER_INFO_2;

The DRIVER_INFO_2 structure identifies a printer driver, the driver version number, the environment for which the driver was written, the name of the file in which the driver is stored, and so on.

Members

cVersion

Specifies a printer-driver version number.

pName

Points to a null-terminated string that specifies the name of the driver (for example, "QMS 810").

pEnvironment

Points to a null-terminated string that specifies the environment for which the driver was written (for example, "W32X86" or "W32MIPS").

pDriverPath

Points to null-terminated string that specifies a filename or full path and filename for the file that contains the device driver (for example, "c:\drivers\pscript.dll").

pDataFile

Points to a null-terminated string that specifies a filename or a full path and filename for the file that contains driver data (for example, "c:\driversQMS810.PPD").

pConfigFile

Points to a null-terminated string that specifies a filename or a full path and filename for the device-driver's configuration DLL (for example, "c:\drivers\PSCRPTUI.DLL").

See Also

»AddPrinterDriver«, »GetPrinterDriver«


  ENHMETAHEADER

typedef struct tagENHMETAHEADER { /* enmh */

    DWORD iType;

    DWORD nSize;

    RECTL rclBounds;

    RECTL rclFrame;

    DWORD dSignature;

    DWORD nVersion;

    DWORD nBytes;

    DWORD nRecords;

    WORD  nHandles;

    WORD  sReserved;

    DWORD nDescription;

    DWORD offDescription;

    DWORD nPalEntries;

    SIZEL szlDevice;

    SIZEL szlMillimeters;

} ENHMETAHEADER;

The ENHMETAHEADER structure contains enhanced-metafile data such as the dimensions of the picture stored in the enhanced metafile, the count of records in the enhanced metafile, the resolution of the device on which the picture was created, and so on.

This structure is always the first record in an enhanced metafile.

Members

iType

Specifies the record type. This member must specify the value assigned to the EMR_HEADER constant.

nSize

Specifies the structure size, in bytes.

rclBounds

Specifies the dimensions, in device units, of the smallest rectangle that can be drawn around the picture stored in the metafile. This rectangle is supplied by graphics device interface (GDI). Its dimensions include the right and bottom edges.

rclFrame

Specifies the dimensions, in .01 millimeter units, of a rectangle that surrounds the picture stored in the metafile. This rectangle must be supplied by the application that creates the metafile. Its dimensions include the right and bottom edges.

dSignature

Specifies a doubleword signature. This member must specify the value assigned to the ENHMETA_SIGNATURE constant.

nVersion

Specifies the metafile version. For the first release of Windows NT, the version value is 0x10000.

nBytes

Specifies the size of the enhanced metafile, in bytes.

nRecords

Specifies the number of records in the enhanced metafile.

nHandles

Specifies the number of handles in the enhanced-metafile handle table. (Index zero in this table is reserved.)

sReserved

Reserved; must be zero.

nDescription

Specifies the number of characters in the array that contains the description of the enhanced metafile's contents. This member should be set to zero if the enhanced metafile does not contain a description string.

offDescription

Specifies the offset from the beginning of the ENHMETAHEADER structure to the array that contains the description of the enhanced metafile's contents. This member should be set to zero if the enhanced metafile does not contain a description string.

nPalEntries

Specifies the number of entries in the enhanced metafile's palette.

szlDevice

Specifies the resolution of the reference device, in pixels.

szlMillimeters

Specifies the resolution of the reference device, in millimeters.

See Also

»ENHMETARECORD«


  ENHMETARECORD

typedef struct tagENHMETARECORD { /* enmr */

    DWORD iType;

    DWORD nSize;

    DWORD dParm[1];

} ENHMETARECORD;

The ENHMETARECORD structure contains data that describes a graphics device interface (GDI) function used to create part of a picture in an enhanced-format metafile.

Members

iType

Specifies the record type.

nSize

Specifies the size of the record, in bytes.

dParm

Specifies an array of parameters passed to the GDI function identified by the record.

See Also

»ENHMETAHEADER«


  ENUMLOGFONT

typedef struct tagENUMLOGFONT { /* elf */

    LOGFONT elfLogFont;

    BYTE    elfFullName[LF_FULLFACESIZE];

    BYTE    elfStyle[LF_FACESIZE];

} ENUMLOGFONT;

The ENUMLOGFONT structure defines the attributes of a font, the complete name of a font, and the style of a font.

Members

elfLogFont

Specifies a LOGFONT structure that defines the attributes of a font.

The LOGFONT structure has the following format:

typedef struct tagLOGFONT { /* lf */

   LONG lfHeight;

   LONG lfWidth;

   LONG lfEscapement;

   LONG lfOrientation;

   LONG lfWeight;

   BYTE lfItalic;

   BYTE lfUnderline;

   BYTE lfStrikeOut;

   BYTE lfCharSet;

   BYTE lfOutPrecision;

   BYTE lfClipPrecision;

   BYTE lfQuality;

   BYTE lfPitchAndFamily;

   CHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

elfFullName

Specifies a unique name for the font. For example "ABC Font Company TrueType Bold Italic Sans Serif".

elfStyle

Specifies the style of the font. For example "Bold Italic"

See Also

»EnumFontFamProc«, »LOGFONT«


  ENUM_SERVICE_STATUS

typedef struct _ENUM_SERVICE_STATUS { /* ess */

    LPTSTR lpServiceName;

    LPTSTR lpDisplayName;

    SERVICE_STATUS ServiceStatus;

} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;

The ENUM_SERVICE_STATUS structure is used by the EnumDependentServices and EnumServicesStatus functions to return the name of a service in a service control manager database and to return information about that service.

Members

lpServiceName

Points to a null-terminated string that names a service in a service control manager database. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. A forward-slash (/), back-slash (\), comma, and space are invalid service name characters.

lpDisplayName

Points to a NULL-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the Service Control Manager. Display name comparisons are always case-insensitive.

ServiceStatus

Specifies a SERVICE_STATUS structure in which status information about the lpServiceName service is returned. The SERVICE_STATUS structure has the following form:

typedef struct _SERVICE_STATUS { /* ss */

    DWORD dwServiceType;

    DWORD dwCurrentState;

    DWORD dwControlsAccepted;

    DWORD dwWin32ExitCode;

    DWORD dwServiceSpecificExitCode;

    DWORD dwCheckPoint;

    DWORD dwWaitHint;

} SERVICE_STATUS, *LPSERVICE_STATUS;

For a full description of this structure, see »SERVICE_STATUS«.

See Also

»EnumDependentServices«, »EnumServicesStatus«


  EVENTLOGRECORD

typedef struct _EVENTLOGRECORD { /* evlr        */

    DWORD  Length;

    DWORD  Reserved;

    DWORD  RecordNumber;

    DWORD  TimeGenerated;

    DWORD  TimeWritten;

    DWORD  EventID;

    WORD   EventType;

    WORD   NumStrings;

    WORD   EventCategory;

    WORD   ReservedFlags;

    DWORD  ClosingRecordNumber;

    DWORD  StringOffset;

    DWORD  UserSidLength;

    DWORD  UserSidOffset;

    DWORD  DataLength;

    DWORD  DataOffset;

    //

    // Then follow:

    //

    // WCHAR SourceName[]

    // WCHAR Computername[]

    // SID   UserSid

    // WCHAR Strings[]

    // BYTE  Data[]

    // CHAR  Pad[]

    // DWORD Length;

    //

} EVENTLOGRECORD;

The EVENTLOGRECORD structure contains information about an event record.

Members

Length

Specifies the length, in bytes, of this event record. Note that this value is stored at both ends of the entry to ease moving forward or backward through the log. The length includes any pad bytes inserted at the end of the record for DWORD alignment.

Reserved

Reserved.

RecordNumber

Contains a record number that can be used with the EVENTLOG_SEEK_READ flag passed in a call to the ReadEventLog function to begin reading at a specified record.

TimeGenerated

The time at which this entry was submitted. This time is measured in the number of seconds elapsed since 00:00:00 January 1, 1970.

TimeWritten

Specifies the time at which this entry was received by the service to be written to the logfile. This time is measured in the number of seconds elapsed since 00:00:00 January 1, 1970.

EventID

Identifies the event. This is specific to the source that generated the event log entry, and is used, together with SourceName, to identify a message in a message file that is presented to the user while viewing the log.

EventType

Specifies the type of event. This member can be one of the following values:

Value	Meaning
EVENTLOG_ERROR_TYPE	Error event
EVENTLOG_WARNING_TYPE	Warning event
EVENTLOG_INFORMATION_TYPE	Information event
EVENTLOG_AUDIT_SUCCESS	Success Audit event
EVENTLOG_AUDIT_FAILURE	Failure Audit event
For more information about event types, see Chapter 65, "Event Logging," in the Microsoft Win32 Programmer's Reference, Volume 2.

NumStrings

Specifies the number of strings present in the log (at the position indicated by StringOffset). These strings are merged into the message before it is displayed to the user.

EventCategory

Specifies a subcategory for this event. This subcategory is source specific.

ReservedFlags

Reserved.

ClosingRecordNumber

Reserved.

StringOffset

Specifies the offset of the strings within this event log entry.

UserSiDLength

Specifies the length, in bytes, of the UserSiD member. This value can be zero if no security identifier was provided.

UserSiDOffset

Specifies the offset of the security identifier within this event record.

DataLength

Specifies the length, in bytes, of the event-specific data (at the position indicated by DataOffset).

DataOffset

Specifies the offset of the event-specific information within this log. This information could be something specific (a disk driver might log the number of retries, for example), followed by binary information specific to the event being logged and to the source that generated the entry.

SourceName

Contains the variable-length null-terminated string specifying the name of the source (application, service, driver, subsystem) that generated the entry. This is the name used to retrieve from the registry the name of the file containing the message strings for this source. It is used, together with the event identifier, to get the message string that describes this event.

Computername

Contains the variable-length null-terminated string specifying the name of the computer that generated this event. There may also be some pad bytes after this field to ensure that the UserSid is aligned on a DWORD boundary.

UserSiD

Specifies the security identifier of the active user at the time this event was logged. This member may be empty if the UserSiDLength member is zero.

The defined members are followed by the replacement strings for the message identified by the event identifier, the binary information, some pad bytes to make sure the full entry is on a DWORD boundary, and finally the length of the log entry again. Because the strings and the binary information can be of any length, no structure members are defined to reference them.

The event identifier together with SourceName and a language identifier identify a message string that describes the event in more detail. The strings are used as replacement strings and are merged into the message string to make a complete message. The message strings are contained in a message file specified in the source entry in the registry.

The binary information is information that is specific to the event. It could be the contents of the processor registers when a device driver got an error, a dump of an invalid packet that was received from the network, a dump of all the structures in a program (when the data area was detected to be corrupt), and so on. This information should be useful to the writer of the device driver or the application in tracking down bugs or unauthorized breaks into the application.

See Also

»ReadEventLog«


  EVENTMSG

typedef struct tagEVENTMSG {    /* em */

    UINT  message;

    UINT  paramL;

    UINT  paramH;

    DWORD time;

    HWND  hwnd;

} EVENTMSG;

The EVENTMSG structure contains information about a hardware message sent to the system message queue. This structure is used to store message information for the JournalPlaybackProc callback function.

Members

message

Specifies the message.

paramL

Specifies additional information about the message. The exact meaning depends on the message value.

paramH

Specifies additional information about the message. The exact meaning depends on the message value.

time

Specifies the time at which the message was posted.

hwnd

Identifies the window to which the message was posted.

See Also

»JournalPlaybackProc«, »SetWindowsHookEx«


  EXCEPTION_DEBUG_INFO

typedef struct _EXCEPTION_DEBUG_INFO { /* exdi */

    EXCEPTION_RECORD ExceptionRecord;

    DWORD dwFirstChance;

} EXCEPTION_DEBUG_INFO;

The EXCEPTION_DEBUG_INFO structure contains exception information that could be used by a debugger.

Members

ExceptionRecord

Contains an EXCEPTION_RECORD structure with information specific to the exception. This includes the exception code, flags, address, a pointer to a related exception, extra parameters, and so on.

dwFirstChance

Indicates whether the debugger has previously encountered the exception specified by ExceptionRecord. If dwFirstChance is nonzero, this is the first time the debugger has encountered the exception. Debuggers typically handle breakpoint and single-step exceptions when they are first encountered. If dwFirstChance is zero, the debugger has previously encountered the exception. This occurs only if, during the search for structured exception handlers, either no handler was found or the exception was continued.

See Also

»DEBUG_EVENT«


  EXCEPTION_POINTERS

typedef struct _EXCEPTION_POINTERS { /* exp */

    PEXCEPTION_RECORD ExceptionRecord;

    PCONTEXT ContextRecord;

} EXCEPTION_POINTERS;

The EXCEPTION_POINTERS structure contains an exception record with a machine-independent description of an exception and a context record with a machine-dependent description of the processor context at the time of the exception.

Members

ExceptionRecord

Points to an EXCEPTION_RECORD structure that contains a machine-independent description of the exception.

ContextRecord

Points to a CONTEXT structure that contains a processor-specific description of the state of the processor at the time of the exception.

See Also

»GetExceptionInformation«, »CONTEXT«, »EXCEPTION_RECORD«


  EXCEPTION_RECORD

typedef struct _EXCEPTION_RECORD { /* exr */

    DWORD ExceptionCode;

    DWORD ExceptionFlags;

    struct _EXCEPTION_RECORD *ExceptionRecord;

    PVOID ExceptionAddress;

    DWORD NumberParameters;

    DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];

} EXCEPTION_RECORD;

The EXCEPTION_RECORD structure describes an exception.

Members

ExceptionCode

Specifies the reason the exception occurred. This is the code generated by a hardware exception, or the code specified in the RaiseException function for a software-generated exception. Following are the exception codes likely to occur due to common programming errors:

Value	Meaning
EXCEPTION_ACCESS_VIOLATION
	The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
EXCEPTION_BREAKPOINT
	A breakpoint was encountered.
EXCEPTION_DATATYPE_MISALIGNMENT
	The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on.
EXCEPTION_SINGLE_STEP
	A trace trap or other single-instruction mechanism signaled that one instruction has been executed.
EXCEPTION_ARRAY_BOUNDS_EXCEEDED
	The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking.
EXCEPTION_FLT_DENORMAL_OPERAND
	One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.
EXCEPTION_FLT_DIVIDE_BY_ZERO
	The thread tried to divide a floating-point value by a floating-point divisor of zero.
EXCEPTION_FLT_INEXACT_RESULT
	The result of a floating-point operation cannot be represented exactly as a decimal fraction.
EXCEPTION_FLT_INVALID_OPERATION
	This exception represents any floating-point exception not included in this list.
EXCEPTION_FLT_OVERFLOW
	The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.
EXCEPTION_FLT_STACK_CHECK
	The stack overflowed or underflowed as the result of a floating-point operation.
EXCEPTION_FLT_UNDERFLOW
	The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.
EXCEPTION_INT_DIVIDE_BY_ZERO
	The thread tried to divide an integer value by an integer divisor of zero.
EXCEPTION_INT_OVERFLOW
	The result of an integer operation caused a carry out of the most significant bit of the result.
EXCEPTION_PRIV_INSTRUCTION
	The thread tried to execute an instruction whose operation is not allowed in the current machine mode.
STATUS_NONCONTINUABLE_EXCEPTION
	The thread tried to continue execution after a noncontinuable exception occurred.
ExceptionFlags

Specifies the exception flags. This member can be either zero, indicating a continuable exception, or EXCEPTION_NONCONTINUABLE indicating a noncontinuable exception. Any attempt to continue execution after a noncontinuable exception causes the STATUS_NONCONTINUABLE_EXCEPTION exception.

ExceptionRecord

Points to an associated EXCEPTION_RECORD structure. Exception records can be chained together to provide additional information when nested exceptions occur.

ExceptionAddress

Specifies the address where the exception occurred.

NumberParameters

Specifies the number of parameters associated with the exception. This is the number of defined elements in the ExceptionInformation array.

ExceptionInformation

Specifies an array of additional 32-bit arguments that describe the exception. The RaiseException function can specify this array of arguments. For most exception codes, the array elements are undefined. For the following exception code, the array elements are defined as follows:

Exception code	Array contents
EXCEPTION_ACCESS_VIOLATION
	The first element of the array contains a read-write flag that indicates the type of operation that caused the access violation. If this value is zero, the thread attempted to read the inaccessible data. If this value is 1, the thread attempted to write to an inaccessible address.
	The second array element specifies the virtual address of the inaccessible data.
See Also

»GetExceptionInformation«, »UnhandledExceptionFilter«, »EXCEPTION_DEBUG_INFO«, »EXCEPTION_POINTERS«


  EXIT_PROCESS_DEBUG_INFO

typedef struct _EXIT_PROCESS_DEBUG_INFO { /* epdi */

    DWORD dwExitCode;

} EXIT_PROCESS_DEBUG_INFO;

The EXIT_PROCESS_DEBUG_INFO structure contains an exiting process's exit code.

Members

dwExitCode

Specifies the exit code for the process.

See Also

»DEBUG_EVENT«


  EXIT_THREAD_DEBUG_INFO

typedef struct _EXIT_THREAD_DEBUG_INFO { /* etdi */

    DWORD dwExitCode;

} EXIT_THREAD_DEBUG_INFO;

The EXIT_THREAD_DEBUG_INFO structure contains an exiting thread's exit code.

Members

dwExitCode

Specifies the exit code for the thread.

See Also

»DEBUG_EVENT«


  EXTLOGFONT

typedef struct tagEXTLOGFONT {

    LOGFONT elfLogFont;

    BYTE    elfFullName[LF_FULLFACESIZE];

    BYTE    elfStyle[LF_FACESIZE];

    DWORD   elfVersion;

    DWORD   elfStyleSize;

    DWORD   elfMatch;

    DWORD   elfReserved;

    BYTE    elfVendorId[ELF_VENDOR_SIZE];

    DWORD   elfCulture;

    PANOSE  elfPanose;

} EXTLOGFONT;

The EXTLOGFONT structure defines the attributes of a font.

Members

elfLogFont

Specifies some of the attributes of the given font. This member is a LOGFONT structure.

typedef struct tagLOGFONT { /* lf */

   LONG lfHeight;

   LONG lfWidth;

   LONG lfEscapement;

   LONG lfOrientation;

   LONG lfWeight;

   BYTE lfItalic;

   BYTE lfUnderline;

   BYTE lfStrikeOut;

   BYTE lfCharSet;

   BYTE lfOutPrecision;

   BYTE lfClipPrecision;

   BYTE lfQuality;

   BYTE lfPitchAndFamily;

   CHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

elfFullName

Specifies a unique name for the font (for example, ABC Font Company TrueType Bold Italic Sans Serif).

elfStyle

Specifies the style of the font (for example, Bold Italic).

elfVersion

Reserved. Must be zero for the first release of Windows NT.

elfStyleSize

This member only has meaning for hinted fonts. It specifies the point size at which the font is hinted. If set to zero, which is its default value, the font is hinted at the point size corresponding to the lfHeight member of the LOGFONT structure specified by elfLogFont.

elfMatch

A unique identifier for an enumerated font. This will be filled in by graphics device interface (GDI) upon font enumeration.

elfReserved

Reserved; must be zero.

elfVendorId

A 4-byte identifier of the font vendor.

elfCulture

Reserved; must be zero.

elfPanose

Specifies the shape of the font. If all members of this structure are set to zero, the elfPanose member is ignored by the font mapper. The PANOSE structure has the following form:

typedef struct tagPANOSE { /* pnse */

    DWORD ulCulture;

    BYTE bFamilyType;

    BYTE bSerifStyle;

    BYTE bWeight;

    BYTE bProportion;

    BYTE bContrast;

    BYTE bStrokeVariation;

    BYTE bArmStyle;

    BYTE bLetterform;

    BYTE bMidline;

    BYTE bXHeight;

} PANOSE

See Also

»ExtCreateFontIndirect«


  EXTLOGPEN

typedef struct tagEXTLOGPEN { /* exlp */

    UINT     elpPenStyle;

    UINT     elpWidth;

    UINT     elpBrushStyle;

    COLORREF elpColor;

    LONG     elpHatch;

    DWORD    elpNumEntries;

    DWORD    elpStyleEntry[1];

} EXTLOGPEN;

The EXTLOGPEN structure defines the pen style, width, and brush attributes for an extended pen. This structure is used by the GetObject function when it retrieves a description of a pen that was created when an application called the ExtCreatePen function.

Members

elpPenStyle

Specifies a combination of pen type, style, end cap style, and join style. The values from each category can be retrieved by using a bitwise AND with the appropriate mask.

The elpPenStyle member masked with PS_TYPE_MASK has one of the following pen type values:

Value	Meaning
PS_GEOMETRIC	The pen is geometric.
PS_COSMETIC	The pen is cosmetic.
The elpPenStyle member masked with PS_STYLE_MASK has one of the following pen styles values:

Value	Meaning
PS_SOLID	The pen is solid.
PS_DASH	The pen is dashed.
PS_DOT	The pen is dotted.
PS_DASHDOT	The pen has alternating dashes and dots.
PS_DASHDOTDOT	The pen has alternating dashes and double dots.
PS_NULL	The pen is invisible.
PS_USERSTYLE	The pen will use a styling array supplied by the user.
PS_INSIDEFRAME	The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the dimensions of the figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to PS_GEOMETRIC pens.
The following category applies only to PS_GEOMETRIC pens. The elpPenStyle member masked with PS_ENDCAP_MASK has one of the following end cap values:

Value	Meaning
PS_ENDCAP_ROUND	Line end caps are round.
PS_ENDCAP_SQUARE	Line end caps are square.
PS_ENDCAP_FLAT	Line end caps are flat.
The following category applies only to PS_GEOMETRIC pens. The elpPenStyle member masked with PS_JOIN_STYLE has one of the following join values:

Value	Meaning
PS_JOIN_BEVEL	Line joins are beveled.
PS_JOIN_MITER	Line joins are mitered when they are within the current SetMiterLimit limit. A join is beveled when it would exceed the limit.
PS_JOIN_ROUND	Line joins are round.
elpWidth

Specifies the width of the pen.

If the elpPenStyle member specifies geometric lines, this value is the width, in logical units, of the line. Otherwise, the lines are cosmetic and this value is 1.

elpBrushStyle

Specifies the brush style of the pen. The elpBrushStyle member values can be one of the following:

Value	Description
BS_DIBPATTERN	Specifies a pattern brush defined by a device-independent bitmap (DIB) specification. If elpBrushStyle is BS_DIBPATTERN, the elpHatch member contains a handle to a packed DIB.
BS_DIBPATTERNPT	Specifies a pattern brush defined by a device-independent bitmap (DIB) specification. If elpBrushStyle is BS_DIBPATTERNPT, the elpHatch member contains a pointer to a packed DIB.
BS_HATCHED	Specifies a hatched brush.
BS_HOLLOW	Specifies a hollow or NULL brush.
BS_PATTERN	Specifies a pattern brush defined by a memory bitmap.
BS_SOLID	Specifies a solid brush.
elpColor

If elpBrushStyle is BS_SOLID or BS_HATCHED, elpColor specifies the color in which the pen is to be drawn. For BS_HATCHED, the SetBkMode and SetBkColor functions determine the background color.

If elpBrushStyle is BS_HOLLOW or BS_PATTERN, elpColor is ignored.

If elpBrushStyle is BS_DIBPATTERN or BS_DIBPATTERNPT, the low-order word of elpColor specifies whether the bmiColors members of the BITMAPINFO structure contain explicit red, green, blue (RGB) values or indexes into the currently realized logical palette. The elpColor value must be one of the following:

Value	Meaning
DIB_PAL_COLORS	The color table consists of an array of 16-bit indexes into the currently realized logical palette.
DIB_RGB_COLORS	The color table contains literal RGB values.
elpHatch

If elpBrushStyle is BS_PATTERN, elpHatch is a handle to the bitmap that defines the pattern.

If elpBrushStyle is BS_SOLID or BS_HOLLOW, elpHatch is ignored.

If elpBrushStyle is BS_DIBPATTERN, the elpHatch member is a handle to a packed DIB. To obtain this handle, an application calls the GlobalAlloc function to allocate a block of global memory and then fills the memory with the packed DIB. A packed DIB consists of a BITMAPINFO structure immediately followed by the array of bytes that define the pixels of the bitmap.

If elpBrushStyle is BS_DIBPATTERNPT, the elpHatch member is a pointer to a packed DIB.

If elpBrushStyle is BS_HATCHED, the elpHatch member specifies the orientation of the lines used to create the hatch. It can be any one of the following values:

Value	Meaning
HS_BDIAGONAL	45-degree upward hatch (left to right)
HS_CROSS	Horizontal and vertical crosshatch
HS_DIAGCROSS	45-degree crosshatch
HS_FDIAGONAL	45-degree downward hatch (left to right)
HS_HORIZONTAL	Horizontal hatch
HS_VERTICAL	Vertical hatch
elpNumEntries

Specifies the number of entries in the style array in the elpStyleEntry member. This value is zero if elpPenStyle does not specify PS_USERSTYLE.

elpStyleEntry

Specifies a user-supplied style array. The array is specified with a finite length, but it is used as if it repeated indefinitely. The first entry in the array specifies the length of the first dash. The second entry specifies the length of the first gap. Thereafter, lengths of dashes and gaps alternate.

If elpWidth specifies geometric lines, the lengths are in logical units. Otherwise, the lines are cosmetic and lengths are in device units.

See Also

»ExtCreatePen«, »GetObject«, »SetBkColor«, »SetBkMode«


  EXT_BUTTON

typedef struct tagEXT_BUTTON { /* extbtn */

    WORD idCommand;

    WORD idsHelp;

    WORD fsStyle;

} EXT_BUTTON;

The EXT_BUTTON structure contains information about a button that a File Manager extension dynamic-link library is adding to the toolbar of File Manager.

Members

idCommand

Specifies the command identifier for the button.

idsHelp

Specifies the identifier of the Help string for the button.

fsStyle

Specifies the style of the button.

See Also

»FMEVENT_TOOLBARLOAD«, »FMS_TOOLBARLOAD«


  FILETIME

typedef struct _FILETIME { /* ft */

    DWORD dwLowDateTime;

    DWORD dwHighDateTime;

} FILETIME;

The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.

Members

dwLowDateTime

Specifies the low-order 32 bits of the file time.

dwHighDateTime

Specifies the high-order 32 bits of the file time.

See Also

»CompareFileTime«, »DosDateTimeToFileTime«, »FileTimeToDosDateTime«, »FileTimeToLocalFileTime«, »FileTimeToSystemTime«, »GetFileTime«, »LocalFileTimeToFileTime«, »SetFileTime«, »SystemTimeToFileTime«


  FIND_NAME_BUFFER

typedef struct _FIND_NAME_BUFFER { /* fnb */

    UCHAR length;

    UCHAR access_control;

    UCHAR frame_control;

    UCHAR destination_addr[6];

    UCHAR source_addr[6];

    UCHAR routing_info[18];

} FIND_NAME_BUFFER;

The FIND_NAME_BUFFER structure contains information about a local network session. One or more FIND_NAME_BUFFER structures follows a FIND_NAME_HEADER structure when an application specifies NCBFINDNAME in the ncb_command member of the NCB structure.

Members

length

Specifies the length, in bytes, of the FIND_NAME_BUFFER structure. Although this structure always occupies 33 bytes, not all of the structure is necessarily valid.

access_control

Specifies the access control for the LAN header.

frame_control

Specifies the frame control for the LAN header.

destination_addr[6]

Specifies the destination address of the remote node where the name was found.

source_addr[6]

Specifies the source address for the remote node where the name was found.

routing_info[18]

Specifies additional routing information.

See Also

»FIND_NAME_HEADER«, »NCB«


  FIND_NAME_HEADER

typedef struct _FIND_NAME_HEADER { /* fnh */

    WORD  node_count;

    UCHAR reserved;

    UCHAR unique_group;

} FIND_NAME_HEADER;

The FIND_NAME_HEADER structure contains information about a network name. FIND_NAME_HEADER is followed by as many FIND_NAME_BUFFER structures as are required to describe the name.

Members

node_count

Specifies the number of nodes on which the specified name was found. The FIND_NAME_HEADER structure is followed by the number of FIND_NAME_BUFFER structures specified by the node_count member.

reserved

Reserved.

unique_group

Specifies whether the name is unique. This value is 0 to specify a unique name or 1 to specify a group.

Comments

The FIND_NAME_HEADER structure is pointed to by the ncb_buffer member of the NCB structure when an application issues an NCBFINDNAME command.

See Also

»FIND_NAME_BUFFER«, »NCB«


  FINDREPLACE

typedef struct {    /* fr */

    DWORD        lStructSize;

    HWND         hwndOwner;

    HINSTANCE    hInstance;

    DWORD        Flags;

    LPSTR        lpstrFindWhat;

    LPSTR        lpstrReplaceWith;

    WORD         wFindWhatLen;

    WORD         wReplaceWithLen;

    DWORD        lCustData;

    LPFRHOOKPROC lpfnHook;

    LPCSTR       lpTemplateName;

} FINDREPLACE;

The FINDREPLACE structure contains information the operating system uses to initialize the system-defined Find and Replace dialog boxes. After the user closes the dialog box, the system returns information about the user-defined find or replace parameters in this structure.

Members

lStructSize

Specifies the length, in bytes, of the structure.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, but it must not be NULL.

hInstance

Identifies a data block that contains a dialog box template specified by the lpstrTemplateName member. This member is used only if the Flags member specifies the FR_ENABLETEMPLATE flag; otherwise, this member is ignored.

Flags

Specifies the dialog box initialization flags. This member may be a combination of the following values:

Value	Meaning
FR_DIALOGTERM
	Indicates that the dialog box is closing. The window handle returned by the FindText or ReplaceText function is not valid if this flag is set.
FR_DOWN
	Determines the direction of searches through a document. If this flag is set, the search direction is down; if the flag is clear, the search direction is up. Initially, this flag specifies the state of the Up and Down controls; after the user closes the dialog box, this flag specifies the user's selection.
FR_ENABLEHOOK
	Enables the hook function specified in the lpfnHook member of this structure. This flag is used only to initialize the dialog box.
FR_ENABLETEMPLATE
	Causes the system to create the dialog box by using the dialog box template identified by the hInstance and lpTemplateName members. This flag is used only to initialize the dialog box.
FR_ENABLETEMPLATEHANDLE
	Indicates that the hInstance member identifies a data block that contains a preloaded dialog box template. The system ignores the lpTemplateName member if this flag is specified.
FR_FINDNEXT
	Indicates that the application should search for the next occurrence of the string specified by the lpstrFindWhat member.
FR_HIDEUPDOWN
	Causes the system to hide the Direction check box and the Up and Down controls.
FR_HIDEMATCHCASE
	Causes the system to hide the Match Case check box.
FR_HIDEWHOLEWORD
	Causes the system to hide the Match Whole Word Only check box.
FR_MATCHCASE
	Set for case-sensitive searches.
FR_NOMATCHCASE
	Disables the Match Case check box. This flag is used only to initialize the dialog box.
FR_NOUPDOWN
	Disables the direction radio buttons. This flag is used only to initialize the dialog box.
FR_NOWHOLEWORD
	Disables the Whole Word check box. This flag is used only to initialize the dialog box.
FR_REPLACE
	Indicates that the application should replace the current occurrence of the string specified in the lpstrFindWhat member with the string specified in the lpstrReplaceWith member.
FR_REPLACEALL
	Indicates that the application should replace all occurrences of the string specified in the lpstrFindWhat member with the string specified in the lpstrReplaceWith member.
FR_SHOWHELP
	Causes the dialog box to show the Help button. The hwndOwner member must not be NULL if this option is specified.
FR_WHOLEWORD
	Checks the Whole Word check box. Only whole words matching the search string will be considered.
lpstrFindWhat

Specifies the string to search for. If there is a string specified when the dialog box starts, the dialog box initializes the Find What: text control with this string. If the FR_FINDNEXT flag is set when the dialog box is opened, the application should search for an occurrence of this string by using the FR_DOWN, FR_WHOLEWORD, and FR_MATCHCASE flags to further define the direction and type of search. The application must allocate a buffer for the string. This buffer should be at least 80 characters long.

lpstrReplaceWith

Specifies the replacement string for replace operations. The FindText function ignores this member.

wFindWhatLen

Specifies the length, in bytes, of the buffer pointed to by the lpstrFindWhat member points.

wReplaceWithLen

Specifies the length, in bytes, of the buffer pointed to by the lpstrReplaceWith member.

lCustData

Specifies application-defined data the system passes to the hook function identified by the lpfnHook member. The system passes the data in the lParam parameter of the WM_INITDIALOG message.

lpfnHook

Points to a hook function that processes messages intended for the dialog box. An application must specify the FR_ENABLEHOOK flag in the Flags member to enable the function; otherwise, the system ignores this structure member. The hook function should return FALSE to pass a message on to the standard dialog procedure, or TRUE to discard the message.

If the hook function returns FALSE in response to the WM_INITDIALOG message, it is responsible for displaying the dialog. This is done by calling the ShowWindow and UpdateWindow functions (note: remember to put these calls after any other paint operations). The following code snippet provides an example:

    /* we've returned FALSE in response to WM_INITDIALOG */

    /* we've performed any other paint operations */

    /* now we display the dialog */

    ShowWindow(hDlg, SW_SHOWNORMAL);

    UpdateWindow(hDlg);

If the hook function returns FALSE in response to the WM_INITDIALOG message, but fails to display the dialog, the dialog will not be shown.

lpstrTemplateName

Points to a null-terminated string that names the dialog box template resource to be substituted for the standard dialog box template. An application can use the MAKEINTRESOURCE macro for numbered dialog resources. This member is used only if the Flags member specifies the FR_ENABLETEMPLATE flag; otherwise, this member is ignored.

See Also

»FindText«, »ReplaceText«, »WM_INITDIALOG«


  FIXED

typedef struct _FIXED { /* fix */

    WORD  fract;

    short value;

} FIXED;

The FIXED structure contains the integral and fractional parts of a fixed-point real number.

Members

fract

Specifies the fractional part of the number.

value

Specifies the integer part of the number.

Comments

The FIXED structure is used to describe the elements of the MAT2 structure.


  FMS_GETDRIVEINFO

typedef struct _FMS_GETDRIVEINFO { /* fmsgdi */

    DWORD dwTotalSpace;

    DWORD dwFreeSpace;

    CHAR  szPath[260];

    CHAR  szVolume[14];

    CHAR  szShare[128];

} FMS_GETDRIVEINFO;

The FMS_GETDRIVEINFO structure contains information about the drive selected in the active File Manager window (the directory window or the Search Results window).

Members

dwTotalSpace

Specifies the total amount of storage space, in bytes, on the disk associated with the drive.

dwFreeSpace

Specifies the amount of free storage space, in bytes, on the disk associated with the drive.

szPath

Specifies the null-terminated path of the current directory.

szVolume

Specifies the null-terminated volume label of the disk associated with the drive.

szShare

Specifies the null-terminated name of the sharepoint (if the drive is being accessed through a network).

See Also

»FMExtensionProc«, »FM_GETDRIVEINFO«


  FMS_GETFILESEL

typedef struct _FMS_GETFILESEL { /* fmsgfs */

    FILETIME ftTime;

    DWORD    dwSize;

    BYTE     bAttr;

    CHAR     szName[260];

} FMS_GETFILESEL;

The FMS_GETFILESEL structure contains information about a selected file in the active File Manager window (the directory window or the Search Results window).

Members

ftTime

Specifies the time and date the file was created.

dwSize

Specifies the size, in bytes, of the file.

bAttr

Specifies the attributes of the file.

szName

Specifies the null-terminated full path and filename of the selected file.

See Also

»FMExtensionProc«


  FMS_LOAD

typedef struct _FMS_LOAD { /* fmsld */

    DWORD dwSize;

    CHAR  szMenuName[MENU_TEXT_LEN];

    HMENU hMenu;

    UINT  wMenuDelta;

} FMS_LOAD;

The FMS_LOAD structure contains information that File Manager uses to add a custom menu provided by a File Manager extension DLL. The structure also provides a delta value that the extension DLL can use to manipulate the custom menu after File Manager has loaded the menu.

Members

dwSize

Specifies the length, in bytes, of the structure.

szMenuName

Specifies the null-terminated name for a menu item that appears on the menu bar in File Manager.

hMenu

Identifies the pop-up menu added to the menu bar in File Manager.

wMenuDelta

Specifies the menu-item delta value. To avoid conflicts with its own menu items, File Manager renumbers the menu-item identifiers in the pop-up menu identified by the hMenu member by adding this delta value to each identifier. An extension DLL that must modify a menu item must identify the item by adding the delta value to the menu item's identifier. The value of this member can vary from session to session.

See Also

»FMExtensionProc«


  FMS_TOOLBARLOAD

typedef struct tagFMS_TOOLBARLOAD { /* fmstbl */

    DWORD        dwSize;

    LPEXT_BUTTON lpButtons;

    WORD         cButtons;

    WORD         cBitmaps;

    WORD         idBitmap;

    HBITMAP      hBitmap;

} FMS_TOOLBARLOAD;

The FMS_TOOLBARLOAD structure contains information about custom buttons to be added to the File Manager toolbar. The buttons are provided by a File Manager extension DLL.

Members

dwSize

Specifies the size, in bytes, of the structure. File Manager sets the size before calling the extension and checks the size after the extension procedure returns.

lpButtons

Points to an array of EXT_BUTTON structures that specify the style, command identifier, and Help string identifier for each toolbar button.

cButtons

Specifies the number of EXT_BUTTON structures in the array pointed to by the lpButtons member. This number equals the number of buttons and separators to add to the toolbar.

cBitmaps

Specifies the number of buttons represented by the given bitmap.

idBitmap

Specifies the identifier of a bitmap resource in the executable file for the extension DLL. The bitmap resource contains images for the number of buttons specified by cBitmaps. File Manager loads the bitmap resource, then uses it to display the buttons.

hBitmap

Specifies the handle of a bitmap that the File Manager will use to obtain and display button images if idBitmap is 0.

See Also

»FMEVENT_TOOLBARLOAD«, »EXT_BUTTON«


  FOCUS_EVENT_RECORD

typedef struct _FOCUS_EVENT_RECORD { /* fer */

    BOOL bSetFocus;

} FOCUS_EVENT_RECORD;

The FOCUS_EVENT_RECORD structure is used to report focus events in a console INPUT_RECORD structure. These events are used internally and should be ignored.

Members

bSetFocus

Used internally.

See Also

»INPUT_RECORD«


  FORM_INFO_1

typedef struct _FORM_INFO_1 { /* fi1 */

    LPTSTR pName;

    SIZEL  Size;

    RECTL  ImageableArea;

} FORM_INFO_1;

The FORM_INFO_1 structure identifies a form, specifies its dimensions, and specifies the dimensions of its printable area.

Members

pName

Points to a null-terminated string that specifies the name of the form.

Size

Specifies the width and height, in thousandths of millimeters, of the form.

ImageableArea

Specifies the width and height, in thousandths of millimeters, of the form.

See Also

»AddForm«, »GetForm«, »SetForm«


  FORMAT_PARAMETERS

typedef struct _FORMAT_PARAMETERS{

   MEDIA_TYPE MediaType;

   DWORD StartCylinderNumber;

   DWORD EndCylinderNumber;

   DWORD StartHeadNumber;

   DWORD EndHeadNumber;

} FORMAT_PARAMETERS ;

The FORMAT_PARAMETERS structure provides information used in formatting a contiguous set of disk tracks.

Members

MediaType

Specifies the media type. See »MEDIA_TYPE«.

StartCylinderNumber

Specifies the cylinder number at which to begin the format.

EndCylinderNumber

Specifies the cylinder number at which to end the format.

StartHeadNumber

Specifies the beginning head location.

EndHeadNumber

Specifies the ending head location.

Comments

The DeviceIoControl function uses a FORMAT_PARAMETERS structure as input to an IOCTL_DISK_FORMAT_TRACKS  device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_FORMAT_TRACKS«, »MEDIA_TYPE«


  GENERIC_MAPPING

typedef struct _GENERIC_MAPPING { /* gm */

    ACCESS_MASK GenericRead;

    ACCESS_MASK GenericWrite;

    ACCESS_MASK GenericExecute;

    ACCESS_MASK GenericAll;

} GENERIC_MAPPING;

The GENERIC_MAPPING structure defines the mapping of generic access rights to specific and standard access rights for an object. When a client application requests generic access to an object, that request is mapped to the access rights defined in this structure.

Members

GenericRead

Specifies an access mask defining read access to an object.

GenericWrite

Specifies an access mask defining write access to an object.

GenericExecute

Specifies an access mask defining execute access to an object.

GenericAll

Specifies an access mask defining all possible types of access to an object.

See Also

»AccessCheck«, »AccessCheckAndAuditAlarm«, »CreatePrivateObjectSecurity«, »MapGenericMask«, »SetPrivateObjectSecurity«, »ACCESS_MASK«


  GLYPHMETRICS

typedef struct _GLYPHMETRICS { /* glmt */

    UINT  gmBlackBoxX;

    UINT  gmBlackBoxY;

    POINT gmptGlyphOrigin;

    short gmCellIncX;

    short gmCellIncY;

} GLYPHMETRICS;

The GLYPHMETRICS structure contains information about the placement and orientation of a glyph in a character cell.

Members

gmBlackBoxX

Specifies the width of the smallest rectangle that completely encloses the glyph (its "black box").

gmBlackBoxY

Specifies the height of the smallest rectangle that completely encloses the glyph (its "black box").

gmptGlyphOrigin

Specifies the x- and y-coordinates of the upper left corner of the smallest rectangle that completely encloses the glyph.

gmCellIncX

Specifies the horizontal distance from the origin of the current character cell to the origin of the next character cell.

gmCellIncY

Specifies the vertical distance from the origin of the current character cell to the origin of the next character cell.

Comments

Values in the GLYPHMETRICS structure are specified in logical units.

See Also

»GetGlyphOutline«


  HANDLETABLE

typedef struct tagHANDLETABLE { /* ht */

    HGDIOBJ objectHandle[1];

} HANDLETABLE;

The HANDLETABLE structure is an array of handles, each of which identifies a graphics device interface (GDI) object.

Members

objectHandle[1]

Contains an array of handles.


  HELPWININFO

typedef struct {    /* hi */

    int   wStructSize;

    int   x;

    int   y;

    int   dx;

    int   dy;

    int   wMax;

    TCHAR rgchMember[2];

} HELPWININFO;

The HELPWININFO structure contains the size and position of either a primary or a secondary Help window. An application can set this information by calling the WinHelp function with the HELP_SETWINPOS value.

Members

wStructSize

Specifies the size of the HELPWININFO structure.

x

Specifies the x-coordinate of the upper left corner of the window.

y

Specifies the y-coordinate of the upper left corner of the window.

dx

Specifies the width of the window.

dy

Specifies the height of the window.

wMax

Specifies how the window is to be shown. This member must be one of the following values:

Value	Action
SW_HIDE	Hides the window and passes activation to another window.
SW_SHOWNORMAL	Activates and displays the window. Whether the window is minimized or maximized, Windows restores it to its original size and position.
SW_SHOWMINIMIZED	Activates the window and displays it as an icon.
SW_SHOWMAXIMIZED	Activates the window and displays it as a maximized window.
SW_SHOWNOACTIVATE	Displays a window in its most recent size and position. The window that is currently active remains active.
SW_SHOW	Activates a window and displays it in its current size and position.
SW_MINIMIZE	Minimizes the specified window and activates the top-level window in the Z order.
SW_SHOWMINNOACTIVE	Displays the window as an icon. The window that is currently active remains active.
SW_SHOWNA	Displays the window in its current state. The window that is currently active remains active.
SW_RESTORE	Same as SW_SHOWNORMAL.
rgchMember

Specifies the name of the window.

Comments

Microsoft Windows Help divides the display into 1024 units in both the x- and y-directions. To create a secondary window that fills the upper left quadrant of the display, for example, an application would specify zero for the x and y members and 512 for the dx and dy members.

See Also

»WinHelp«


  HSZPAIR

typedef struct tagHSZPAIR {   /* hp */

    HSZ hszSvc;

    HSZ hszTopic;

} HSZPAIR;

The HSZPAIR structure contains a dynamic data exchange (DDE) service name and topic name. A DDE server application can use this structure during an XTYP_WILDCONNECT transaction to enumerate the service-topic pairs that it supports.

Members

hszSvc

Identifies a service name.

hszTopic

Identifies a topic name.


  ICONINFO

typedef struct _ICONINFO { /* ii */

   BOOL    fIcon;

   DWORD   xHotspot;

   DWORD   yHotspot;

   HBITMAP hbmMask;

   HBITMAP hbmColor;

} ICONINFO;

The ICONINFO structure contains information about an icon or a cursor.

Members

fIcon

Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies an icon; FALSE specifies a cursor.

xHotspot

Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot spot is always in the center of the icon, and this member is ignored.

yHotspot

Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot spot is always in the center of the icon, and this member is ignored.

hbmMask

Specifies the icon bitmask bitmap. If this structure defines a black and white icon, this bitmask is formatted so that the upper half is the icon AND bitmask, and the lower half is the icon XOR bitmask. Under this condition, the height should be an even multiple of two. If this structure defines a color icon, this mask defines the AND bitmask of the icon ONLY.

hbmColor

Identifies the icon color bitmap. This member can be optional if this structure defines a black and white icon. After the AND bitmask of hbmMask is applied with SRCAND to the destination, the color bitmap is applied (using XOR) to the destination by using SRCINVERT.

See Also

»CreateIconIndirect«, »GetIconInfo«


  INPUT_RECORD

typedef struct _INPUT_RECORD { /* ir */

    WORD EventType;

    union {

        KEY_EVENT_RECORD KeyEvent;

        MOUSE_EVENT_RECORD MouseEvent;

        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;

        MENU_EVENT_RECORD MenuEvent;

        FOCUS_EVENT_RECORD FocusEvent;

    } Event;

} INPUT_RECORD;

The INPUT_RECORD structure is used to report input events in the console input buffer. These records can be read from the input buffer by using the ReadConsoleInput or PeekConsoleInput function, or written to the input buffer by using the WriteConsoleInput function.

Members

EventType

Identifies the type of input event and the event record stored in the Event member. This member can have one of the following values:

Value	Meaning
KEY_EVENT
	The Event member contains a KEY_EVENT_RECORD structure with information about a keyboard input event. The KEY_EVENT_RECORD structure has the following form:
typedef struct _KEY_EVENT_RECORD { /* ker */

    BOOL bKeyDown;

    WORD wRepeatCount;

    WORD wVirtualKeyCode;

    WORD wVirtualScanCode;

    union {

        WCHAR UnicodeChar;

        CHAR  AsciiChar;

    } uChar;

    DWORD dwControlKeyState;

} KEY_EVENT_RECORD;

MOUSE_EVENT
	The Event member contains a MOUSE_EVENT_RECORD structure with information about a mouse movement or button press event. The MOUSE_EVENT_RECORD structure has the following form:
typedef struct _MOUSE_EVENT_RECORD { /* mer */

    COORD dwMousePosition;

    DWORD dwButtonState;

    DWORD dwControlKeyState;

    DWORD dwEventFlags;

} MOUSE_EVENT_RECORD;

WINDOW_BUFFER_SIZE_EVENT
	The Event member contains a WINDOW_BUFFER_SIZE_RECORD structure with information a user action to change the console window size. The WINDOW_BUFFER_SIZE_RECORD structure has the following form:
typedef struct _WINDOW_BUFFER_SIZE_RECORD { /* wbsr */

    COORD dwSize;

} WINDOW_BUFFER_SIZE_RECORD;

MENU_EVENT
	The Event member contains a MENU_EVENT_RECORD structure. These events are used internally, and should be ignored. The MENU_EVENT_RECORD structure has the following form:
typedef struct _MENU_EVENT_RECORD { /* mer */

    UINT dwCommandId;

} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;

FOCUS_EVENT
	The Event member contains a FOCUS_EVENT_RECORD structure. These events are used internally, and should be ignored. The FOCUS_EVENT_RECORD structure has the following form:
typedef struct _FOCUS_EVENT_RECORD { /* fer */

    BOOL bSetFocus;

} FOCUS_EVENT_RECORD;

Event

Contains a KEY_EVENT_RECORD, MOUSE_EVENT_RECORD, WINDOW_BUFFER_SIZE_RECORD, MENU_EVENT_RECORD, or FOCUS_EVENT_RECORD structure, depending on the event type specified by the EventType member.

See Also

»PeekConsoleInput«, »ReadConsoleInput«, »WriteConsoleInput«


  JOB_INFO_1

typedef struct _JOB_INFO_1 {    /* ji1 */

    DWORD  JobId;

    LPTSTR pPrinterName;

    LPTSTR pMachineName;

    LPTSTR pUserName;

    LPTSTR pDocument;

    LPTSTR pDatatype;

    LPTSTR pStatus;

    DWORD  Status;

    DWORD  Priority;

    DWORD  Position;

    DWORD  TotalPages;

    DWORD  PagesPrinted;

    SYSTEMTIME Submitted;

} JOB_INFO_1;

The JOB_INFO_1 structure specifies print-job information such as the job-identifier value, the name of the printer for which the job is spooled, the name of the machine that created the print job, the name of the user that owns the print job, and so on.

Members

JobId

Specifies a job identifier.

pPrinterName

Points to a null-terminated string that specifies the name of the printer for which the job is spooled.

pMachineName

Points to a null-terminated string that specifies the name of the machine that created the print job.

pUserName

Points to a null-terminated string that specifies the name of the user that owns the print job.

pDocument

Points to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc").

pDatatype

Points to a null-terminated string that specifies the type of data used to record the print job.

pStatus

Points to a null-terminated string that specifies the status of the print job.

Status

Specifies the job status. This member can be one or more of the following values:

JOB_STATUS_DELETING
JOB_STATUS_ERROR
JOB_STATUS_OFFLINE
JOB_STATUS_PAPEROUT
JOB_STATUS_PAUSED
JOB_STATUS_PRINTED
JOB_STATUS_PRINTING
JOB_STATUS_SPOOLING

Priority

Specifies the job priority.

Position

Specifies the job's position in the print queue.

TotalPages

Specifies how many pages the document contains.

PagesPrinted

Specifies the number of pages that have printed.

Submitted

Specifies the time that this document was spooled.

See Also

»EnumJobs«, »GetJob«, »SetJob«


  JOB_INFO_2

typedef struct _JOB_INFO_2 { /* ji2 */

    DWORD      JobId;

    LPTSTR     pPrinterName;

    LPTSTR     pMachineName;

    LPTSTR     pUserName;

    LPTSTR     pDocument;

    LPTSTR     pNotifyName;

    LPTSTR     pDatatype;

    LPTSTR     pPrintProcessor;

    LPTSTR     pParameters;

    LPTSTR     pDriverName;

    LPDEVMODE  pDevMode;

    LPTSTR     pStatus;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD      Status;

    DWORD      Priority;

    DWORD      Position;

    DWORD      StartTime;

    DWORD      UntilTime;

    DWORD      TotalPages;

    DWORD      Size;

    SYSTEMTIME Submitted;

    DWORD      Time;

    DWORD      PagesPrinted ;

} JOB_INFO_2;

The JOB_INFO_2 structure describes a full set of values associated with a job.

Members

JobId

Specifies a job ID value.

pPrinterName

Points to a null-terminated string that specifies the name of the printer for which the job is spooled.

pMachineName

Points to a null-terminated string that specifies the name of the machine that created the print job.

pUserName

Points to a null-terminated string that specifies the name of the user who owns the print job.

pDocument

Points to a null-terminated string that specifies the name of the print job (for example, "MS-WORD: Review.doc").

pNotifyName

Points to a null-terminated string that specifies the name of the user who should be notified when the job has been printed or when an error occurs while printing the job.

pDatatype

Points to a null-terminated string that specifies the type of data used to record the print job.

pPrintProcessor

Points to a null-terminated string that specifies the name of the print processor that should be used to print the job.

pParameters

Points to a null-terminated string that specifies print-processor parameters.

pDriverName

Points to a null-terminated string that specifies the name of the printer driver that should be used to process the print job.

pDevMode

Points to a DEVMODE structure that contains device-initialization and environment data for the printer driver.

pStatus

Points to a null-terminated string that specifies the status of the print job.

pSecurityDescriptor

Points to a SECURITY_DESCRIPTOR structure that defines the print-job's owner and group, as well as other access-related data.

Status

Specifies the job status. This member can be one or more of the following values:

JOB_STATUS_PAUSED
JOB_STATUS_ERROR
JOB_STATUS_DELETING
JOB_STATUS_SPOOLING
JOB_STATUS_PRINTING
JOB_STATUS_OFFLINE
JOB_STATUS_PAPEROUT
JOB_STATUS_PRINTED

Priority

Specifies the job priority.

Position

Specifies the job's position in the print queue.

StartTime

Specifies the earliest time that the job can be printed.

UntilTime

Specifies the the latest time that the job can be printed.

TotalPages

Specifies the number of pages required for the job.

Size

Specifies the size, in bytes, of the job.

Submitted

Specifies the time when the job was submitted.

Time

Specifies the total time (in seconds) elapsed since the job began printing.

PagesPrinted

Specifies the number of pages that have printed.

See Also

»EnumJobs«, »GetJob«, »SetJob«


  JOYCAPS

typedef struct joyinfo_tag {

    WORD  wMid;

    WORD  wPid;

    TCHAR  szPname[MAXPNAMELEN];

    UINT  wXmin;

    UINT  wXmax;

    UINT  wYmin;

    UINT  wYmax;

    UINT  wZmin;

    UINT  wZmax;

    UINT  wNumButtons;

    UINT  wPeriodMin;

    UINT  wPeriodMax;

} JOYCAPS;

The JOYCAPS structure stores joystick-capability information.

Members

wMid

Specifies the manufacturer identifier of the joystick. Manufacturer identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

wPid

Specifies the product identifier of the joystick. Product identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

szPname

Specifies the product name of the joystick, stored as a null-terminated string.

wXmin

Specifies the minimum x-position of the joystick.

wXmax

Specifies the maximum x-position of the joystick.

wYmin

Specifies the minimum y-position of the joystick.

wYmax

Specifies the maximum y-position of the joystick.

wZmin

Specifies the minimum z-position of the joystick.

wZmax

Specifies the maximum z-position of the joystick.

wNumButtons

Specifies the number of buttons on the joystick.

wPeriodMin

Specifies the smallest polling interval supported when captured by the joySetCapture function.

wPeriodMax

Specifies the largest polling interval supported when captured by joySetCapture.

See Also

»joyGetDevCaps«


  JOYINFO

typedef struct joyinfo_tag {

    UINT  wXpos;

    UINT  wYpos;

    UINT  wZpos;

    UINT  wButtons;

} JOYINFO;

The JOYINFO structure stores joystick-position and button-state information.

Members

wXpos

Specifies the current x-position of the joystick.

wYpos

Specifies the current y-position of the joystick.

wZpos

Specifies the current z-position of the joystick.

wButtons

Specifies the current state of the joystick buttons. This member can be any combination of the following bit flags:

Value	Meaning
JOY_BUTTON1	Set if button 1 is pressed
JOY_BUTTON2	Set if button 2 is pressed
JOY_BUTTON3	Set if button 3 is pressed
JOY_BUTTON4	Set if button 4 is pressed
See Also

»joyGetPos«


  KERNINGPAIR

typedef struct tagKERNINGPAIR { /* kp */

    WORD wFirst;

    WORD wSecond;

    int  iKernAmount;

} KERNINGPAIR;

The KERNINGPAIR structure defines a kerning pair.

Members

wFirst

Specifies the character code for the first character in the kerning pair.

wSecond

Specifies the character code for the second character in the kerning pair.

iKernAmount

Specifies the amount this pair will be kerned if they appear side by side in the same font and size. This value is typically negative, because pair kerning usually results in two characters being set more tightly than normal. The value is given in logical units — that is, it depends on the current mapping mode.

See Also

»GetKerningPairs«


  KEY_EVENT_RECORD

typedef struct _KEY_EVENT_RECORD { /* ker */

    BOOL bKeyDown;

    WORD wRepeatCount;

    WORD wVirtualKeyCode;

    WORD wVirtualScanCode;

    union {

        WCHAR UnicodeChar;

        CHAR  AsciiChar;

    } uChar;

    DWORD dwControlKeyState;

} KEY_EVENT_RECORD;

The KEY_EVENT_RECORD structure is used to report keyboard input events in a console INPUT_RECORD structure.

Members

bKeyDown

Specifies TRUE if the key is being pressed, FALSE if the key is being released.

wRepeatCount

Specifies a count indicating that a key is being held down. For example, when a key is held down, you might get five events with this member equal to 1, one event with this member equal to 5, or multiple events with this member greater than or equal to 1.

wVirtualKeyCode

Specifies the virtual-key code that identifies the given key in a device-independent manner.

wVirtualScanCode

Specifies the virtual scan code of the given key that represents the device-dependent value generated by the keyboard hardware.

uChar

Specifies the translated Unicode or ASCII character, depending on whether the wide-character (Unicode) or ANSI version of the ReadConsoleInput function was used.

dwControlKeyState

Indicates the state of the control keys. This member can be a combination of the following values:

Value	Meaning
RIGHT_ALT_PRESSED	The right ALT key is pressed.
LEFT_ALT_PRESSED	The left ALT key is pressed.
RIGHT_CTRL_PRESSED	The right CTRL key is pressed.
LEFT_CTRL_PRESSED	The left CTRL key is pressed.
SHIFT_PRESSED	The SHIFT key is pressed.
NUMLOCK_ON	The NUM LOCK light is on.
SCROLLLOCK_ON	The SCROLL LOCK light is on.
CAPSLOCK_ON	The CAPS LOCK light is on.
ENHANCED_KEY	The key is enhanced.
Comments

Enhanced keys for the IBM 101- and 102-key keyboards are the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and direction keys in the clusters to the left of the keypad; and the divide (/) and ENTER keys in the keypad.

Keyboard input events are generated when any key, including control keys, is pressed or released. However, the ALT key when pressed and released without combining with another character, has special meaning to Windows and is not passed through to the application. Also, the CTRL+C key combination is not passed through if the input handle is in processed mode (ENABLE_PROCESSED_INPUT).

See Also

»PeekConsoleInput«, »ReadConsoleInput«, »WriteConsoleInput«, »INPUT_RECORD«


  LANA_ENUM

typedef struct _LANA_ENUM { /* le */

    UCHAR length;

    UCHAR lana[MAX_LANA];

} LANA_ENUM;

The LANA_ENUM structure contains the numbers for the current LAN adapters.

Members

length

Specifies the number of valid entries in the array of LAN adapter numbers.

lana

Specifies an array of LAN adapter numbers.

Comments

The LANA_ENUM structure is pointed to by the ncb_buffer member of the NCB structure when an application issues the NCBENUM command. The NCBENUM command is not part of the IBM NetBIOS 3.0 specification.

See Also

»NCB«


  LARGE_INTEGER

typedef struct _LARGE_INTEGER { /* li */

    DWORD LowPart;

    LONG  HighPart;

} LARGE_INTEGER;

The LARGE_INTEGER structure is used to represent a 64-bit signed integer value.

Members

LowPart

Specifies the low-order 32 bits.

HighPart

Specifies the high-order 32 bits.

See Also

»LUID«, »ULARGE_INTEGER«


  LDT_ENTRY

typedef struct _LDT_ENTRY { /* ldte */

    WORD LimitLow;

    WORD BaseLow;

    union {

        struct {

            BYTE BaseMid;

            BYTE Flags1;

            BYTE Flags2;

            BYTE BaseHi;

        } Bytes;

        struct {

            DWORD BaseMid : 8;

            DWORD Type : 5;

            DWORD Dpl : 2;

            DWORD Pres : 1;

            DWORD LimitHi : 4;

            DWORD Sys : 1;

            DWORD Reserved_0 : 1;

            DWORD Default_Big : 1;

            DWORD Granularity : 1;

            DWORD BaseHi : 8;

        } Bits;

    } HighWord;

} LDT_ENTRY, *PLDT_ENTRY;

The LDT_ENTRY structure describes an entry in the descriptor table. This structure is valid only on x86-based systems.

Members

LimitLow

Contains the low 16 bits of the address of the last byte in the segment.

BaseLow

Contains the low 16 bits of the base address of the segment.

HighWord

Contains the high two words of the descriptor. This member may be interpreted as bytes or collections of bits, depending on the level of detail required.

The members of the Bits structure are as follows:

Member	Contents
BaseMid	Middle bits (16−23) of the base address of the segment.
Type	Bitmask that indicates the type of segment. This can be one of the following values:
Value	Meaning
0	Read-only data segment
1	Read-write data segment
2	Unused segment
3	Read-write expand-down data segment
4	Execute-only code segment
5	Executable-readable code segment
6	Execute-only "conforming" code segment
7	Executable-readable "conforming" code segment
Dpl	The privilege level of the descriptor. This member is an integer value in the range 0 (most privileged) through 3 (least privileged).
Pres	The present flag. This member is 1 if the segment is present in physical memory; 0 if not.
LimitHi	High bits (16−19) of the address of the last byte in the segment.
Sys	Space that is available to system programmers. This member might be used for marking segments in some system-specific way.
Reserved_0	Reserved.
Default_Big	Size of segment. If the segment is a data segment, this member contains 1 if the segment is larger than 64K, 0 if the segment is smaller than or equal to 64K.
	If the segment is a code segment, this member contains 1 if the segment is a code segment and runs with the default (native mode) instruction set. This member contains 0 if the code segment is an 80286 code segment and runs with 16-bit offsets and the 80286-compatible instruction set.
Granularity	Granularity. This member contains 0 if the segment is byte granular, 1 if the segment is page granular.
BaseHi	High bits (24−31) of the base address of the segment.
The members of the Bytes structure are as follows:

Member	Contents
BaseMid	Middle bits (16−23) of the base address of the segment.
Flags1	Values of the Type, Dpl, and Pres members in the Bits structure.
Flags2	Values of the LimitHi, Sys, Reserved_0, Default_Big, and Granularity members in the Bits structure.
BaseHi	High bits (24−31) of the base address of the segment.
Comments

The GetThreadSelectorEntry function fills this structure with information from an entry in the descriptor table. You can use this information to convert a segment-relative address to a linear virtual address.

The base address of a segment is the address of offset 0 in the segment. To calculate this value, combine BaseLow, BaseMid, and BaseHi.

The limit of a segment is the address of the last byte that can be addressed in the segment. To calculate this value, combine LimitLow and LimitHi.

See Also

»GetThreadSelectorEntry«


  LIST_ENTRY

typedef struct _LIST_ENTRY { /* le */

    struct _LIST_ENTRY *Flink;

    struct _LIST_ENTRY *Blink;

} LIST_ENTRY;

The LIST_ENTRY structure is available for any entry in a double-linked list.

Members

Flink

Points to the preceding entry in a double-linked list.

Blink

Points to the next entry in a double-linked list.

Comments

This structure can be used as the beginning of a double-linked list or as any subsequent entry in the list.


  LOAD_DLL_DEBUG_INFO

typedef struct _LOAD_DLL_DEBUG_INFO { /* lddi */

    HANDLE hFile;

    LPVOID lpBaseOfDll;

    DWORD  dwDebugInfoFileOffset;

    DWORD  nDebugInfoSize;

    LPVOID lpImageName;

    WORD fUnicode;

} LOAD_DLL_DEBUG_INFO;

The LOAD_DLL_DEBUG_INFO structure contains information about a dynamic-link library (DLL) that has just been loaded.

Members

hFile

Identifies a handle of the DLL. If hFile is NULL, the handle is not valid. Otherwise, hFile is opened for reading and read-sharing in the context of the debugger.

lpBaseOfDll

Points to the base address of the DLL in the address space of the process loading the DLL.

dwDebugInfoFileOffset

Specifies the offset to the debugging information in the file identified by the hFile member. The kernel expects the debugging information to be in CodeView 4.0 format. This format is currently a derivative of Common Object File Format (COFF).

nDebugInfoSize

Specifies the size, in bytes, of the debugging information in the file. If this value is zero, there is no debugging information.

lpImageName

Provides an optional pointer to the file name associated with the hFile parameter. The lpImageName parameter may be NULL, or may contain the address of a string pointer in the debuggee's address space. That address may in turn either be NULL, or point to the actual file name. If fUnicode is a non-zero value, the name string is Unicode; otherwise it is ANSI.

This parameter is strictly optional. Debuggers must be prepared to handle the case where lpImageName is NULL, OR *lpImageName (in the debuggee's address space) is NULL. Specifically, this release of Windows NT will never provide an image name for a create process event, and will not likely pass an image name for the first DLL event. This version of Windows NT will also never provide this information in the case of debug events that originate from a call to the DebugActiveProcess function.

fUnicode

Indicates whether a file name specified by lpImageName is Unicode or ANSI. A non-zero value indicates Unicode; zero indicates ANSI.

See Also

»CREATE_PROCESS_DEBUG_INFO«, »CREATE_THREAD_DEBUG_INFO«, »DEBUG_EVENT«


  LOGBRUSH

typedef struct tagLOGBRUSH { /* lb */

   UINT     lbStyle;

   COLORREF lbColor;

   LONG     lbHatch;

} LOGBRUSH;

The LOGBRUSH structure defines the style, color, and pattern of a physical brush. It is used by the CreateBrushIndirect and ExtCreatePen functions.

Members

lbStyle

Specifies the brush style. The lbStyle member must be one of the following styles:

Value	Meaning
BS_DIBPATTERN	A pattern brush defined by a device-independent bitmap (DIB) specification. If lbStyle is BS_DIBPATTERN, the lbHatch member contains a handle to a packed DIB.
BS_DIBPATTERNPT	A pattern brush defined by a device-independent bitmap (DIB) specification. If lbStyle is BS_DIBPATTERNPT, the lbHatch member contains a pointer to a packed DIB.
BS_HATCHED	Hatched brush.
BS_HOLLOW	Hollow brush.
BS_NULL	Same as BS_HOLLOW.
BS_PATTERN	Pattern brush defined by a memory bitmap.
BS_SOLID	Solid brush.
lbColor

Specifies the color in which the brush is to be drawn. If lbStyle is the BS_HOLLOW or BS_PATTERN style, lbColor is ignored.

If lbStyle is BS_DIBPATTERN or BS_DIBPATTERNBT, the low-order word of lbColor specifies whether the bmiColors members of the BITMAPINFO structure contain explicit red, green, blue (RGB) values or indices into the currently realized logical palette. The lbColor member must be one of the following values:

Value	Meaning
DIB_PAL_COLORS	The color table consists of an array of 16-bit indices into the currently realized logical palette.
DIB_RGB_COLORS	The color table contains literal RGB values.
lbHatch

Specifies a hatch style. The meaning depends on the brush style defined by lbStyle.

If lbStyle is BS_DIBPATTERN, the lbHatch member contains a handle to a packed DIB. If lbStyle is BS_DIBPATTERNPT, the lbHatch member contains a pointer to a packed DIB.

If lbStyle is BS_HATCHED, the lbHatch member specifies the orientation of the lines used to create the hatch. It can be one of the following values:

Value	Meaning
HS_BDIAGONAL	A 45-degree upward, left-to-right hatch
HS_CROSS	Horizontal and vertical cross-hatch
HS_DIAGCROSS	45-degree crosshatch
HS_FDIAGONAL	A 45-degree downward, left-to-right hatch
HS_HORIZONTAL	Horizontal hatch
HS_VERTICAL	Vertical hatch
If lbStyle is BS_PATTERN, lbHatch is a handle to the bitmap that defines the pattern.

If lbStyle is BS_SOLID or BS_HOLLOW, lbHatch is ignored.

Comments

Although lbColor controls the foreground color of a hatch brush, the SetBkMode and SetBkColor functions control the background color.

See Also

»CreateBrushIndirect«, »ExtCreatePen«, »SetBkColor«, »SetBkMode«


  LOGFONT

typedef struct tagLOGFONT { /* lf */

   LONG lfHeight;

   LONG lfWidth;

   LONG lfEscapement;

   LONG lfOrientation;

   LONG lfWeight;

   BYTE lfItalic;

   BYTE lfUnderline;

   BYTE lfStrikeOut;

   BYTE lfCharSet;

   BYTE lfOutPrecision;

   BYTE lfClipPrecision;

   BYTE lfQuality;

   BYTE lfPitchAndFamily;

   CHAR lfFaceName[LF_FACESIZE];

} LOGFONT;

The LOGFONT structure defines the attributes of a font.

Members

lfHeight

Specifies the height, in logical units, of the font. The font height can be specified in one of three ways. If lfHeight is greater than zero, it is transformed into device units and matched against the cell height of the available fonts. If it is zero, a reasonable default size is used. If it is less than zero, it is transformed into device units and the absolute value is matched against the character height of the available fonts. For all height comparisons, the font mapper looks for the largest font that does not exceed the requested size; if there is no such font, it looks for the smallest font available. This mapping occurs when the font is actually used for the first time.

lfWidth

Specifies the average width, in logical units, of characters in the font. If lfWidth is zero, the aspect ratio of the device is matched against the digitization aspect ratio of the available fonts to find the closest match, determined by the absolute value of the difference.

lfEscapement

Specifies the angle, in tenths of degrees, of each line of text written in the font (relative to the bottom of the page).

lfOrientation

Specifies the angle, in tenths of degrees, of each character's base line (relative to the bottom of the page).

lfWeight

Specifies the weight of the font, in the range 0 through 1000 (for example, 400 is normal and 700 is bold). If lfWeight is zero, a default weight is used.

lfItalic

Specifies an italic font if set to TRUE.

lfUnderline

Specifies an underlined font if set to TRUE.

lfStrikeOut

Specifies a strikeout font if set to TRUE.

lfCharSet

Specifies the character set. The following values are predefined:

    ANSI_CHARSET
    OEM_CHARSET
    SYMBOL_CHARSET
    UNICODE_CHARSET

The OEM character set is system dependent.

Fonts with other character sets may exist in the system. If an application uses a font with an unknown character set, it should not attempt to translate or interpret strings that are to be rendered with that font.

lfOutPrecision

Specifies the output precision. The output precision defines how closely the output must match the requested font's height, width, character orientation, escapement, and pitch. It can be one of the following values:

    OUT_CHARACTER_PRECIS
    OUT_DEFAULT_PRECIS
    OUT_STRING_PRECIS
    OUT_STROKE_PRECIS

lfClipPrecision

Specifies the clipping precision. The clipping precision defines how to clip characters that are partially outside the clipping region. It can be one of the following values:

    CLIP_CHARACTER_PRECIS
    CLIP_DEFAULT_PRECIS
    CLIP_STROKE_PRECIS

lfQuality

Specifies the output quality. The output quality defines how carefully graphics device interface (GDI) must attempt to match the logical-font attributes to those of an actual physical font. It can be one of the following values:

Value	Meaning
DEFAULT_QUALITY	Appearance of the font does not matter.
DRAFT_QUALITY	Appearance of the font is less important than when PROOF_QUALITY is used. For GDI fonts, scaling is enabled, which means that more font sizes are available, but the quality may be lower. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
PROOF_QUALITY	Character quality of the font is more important than exact matching of the logical-font attributes. For GDI fonts, scaling is disabled and the font closest in size is chosen. Although the chosen font size may not be mapped exactly when PROOF_QUALITY is used, the quality of the font is high and there is no distortion of appearance. Bold, italic, underline, and strikeout fonts are synthesized if necessary.
lfPitchAndFamily

Specifies the pitch and family of the font. The two low-order bits specify the pitch of the font and can be one of the following values:

    DEFAULT_PITCH
    FIXED_PITCH
    VARIABLE_PITCH

Bits 4 through 7 of the member specify the font family and can be one of the following values:

    FF_DECORATIVE
    FF_DONTCARE
    FF_MODERN
    FF_ROMAN
    FF_SCRIPT
    FF_SWISS

The proper value can be obtained by using the Boolean OR operator to join one pitch constant with one family constant.

Font families describe the look of a font in a general way. They are intended for specifying fonts when the exact typeface desired is not available. The values for font families are as follows:

Value	Meaning
FF_DECORATIVE	Novelty fonts. Old English is an example.
FF_DONTCARE	Don't care or don't know.
FF_MODERN	Fonts with constant stroke width (fixed-pitch), with or without serifs. Fixed-pitch fonts are usually modern. Pica, Elite, and CourierNew® are examples.
FF_ROMAN	Fonts with variable stroke width (proportionally spaced) and with serifs. MS® Serif is an example.
FF_SCRIPT	Fonts designed to look like handwriting. Script and Cursive are examples.
FF_SWISS	Fonts with variable stroke width (proportionally spaced) and without serifs. MS® Sans Serif is an example.
lfFaceName

Points to a null-terminated string that specifies the typeface name of the font. The length of this string must not exceed 32 characters. The EnumFonts function can be used to enumerate the typeface names of all currently available fonts. If lfFaceName is NULL, GDI uses a default typeface.

See Also

»CreateFontIndirect«


  LOGPALETTE

typedef struct tagLOGPALETTE { /* lgpl */

    WORD         palVersion;

    WORD         palNumEntries;

    PALETTEENTRY palPalEntry[1];

} LOGPALETTE;

The LOGPALETTE structure defines a logical color palette.

Members

palVersion

Specifies the Windows version number for the structure (currently 0x300).

palNumEntries

Specifies the number of entries in the logical color palette.

palPalEntry

Specifies an array of PALETTEENTRY structures that define the color and usage of each entry in the logical palette. The PALETTEENTRY structure has the following form:

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

Comments

The colors in the palette-entry table should appear in order of importance because entries earlier in the logical palette are most likely to be placed in the system palette.

See Also

»CreatePalette«


  LOGPEN

typedef struct tagLOGPEN { /* lgpn */

    UINT     lopnStyle;

    POINT    lopnWidth;

    COLORREF lopnColor;

} LOGPEN;

The LOGPEN structure defines the style, width, and color of a pen, a drawing object used to draw lines and borders. The CreatePenIndirect function uses the LOGPEN structure.

Members

lopnStyle

Specifies the pen style, which can be one of the following values:

Value	Meaning
PS_SOLID	Pen is solid.
PS_DASH	Pen is dashed.
PS_DOT	Pen is dotted.
PS_DASHDOT	Pen has alternating dashes and dots.
PS_DASHDOTDOT	Pen has dashes and double dots.
PS_NULL	Pen is invisible.
PS_INSIDEFRAME	Pen is solid. When this pen is used in any graphics device interface (GDI) drawing function that takes a bounding rectangle, the dimensions of the figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to geometric pens.
lopnWidth

Specifies the POINT structure that contains the pen width, in logical units. If the pointer member is NULL, the pen is one pixel wide on raster devices. The y member in the POINT structure for lopnWidth is not used.

lopnColor

Specifies the pen color.

Comments

If the width of the pen is greater than 1 and the pen style is PS_INSIDEFRAME, the line is drawn inside the frame of all GDI objects except polygons and polylines. If the pen color does not match an available red, green, blue (RGB) value, the pen is drawn with a logical (dithered) color. If the pen width is less than or equal to 1, the PS_INSIDEFRAME style is identical to the PS_SOLID style.

See Also

»CreatePenIndirect«, »RGB«


  LUID

typedef LARGE_INTEGER LUID

An LUID is a 64-bit value guaranteed to be unique only on the system on which it was generated. The uniqueness of a locally unique identifier (LUID) is guaranteed only until the system is restarted.

An LUID is not for direct manipulation. Applications are to use functions and structures to manipulate LUID values.

See Also

»AllocateLocallyUniqueId«, »LookupPrivilegeName«, »LookupPrivilegeValue«, »PrivilegeCheck«, »LUID_AND_ATTRIBUTES«, »PRIVILEGE_SET«


  LUID_AND_ATTRIBUTES

typedef struct _LUID_AND_ATTRIBUTES { /* luaa */

    LUID  Luid;

    DWORD Attributes;

} LUID_AND_ATTRIBUTES;

The LUID_AND_ATTRIBUTES structure represents a locally unique identifier (LUID) and its attributes.

Members

Luid

Specifies an LUID value.

Attributes

Specifies attributes of the LUID. This value contains up to 32 one-bit flags. Its meaning is dependent on the definition and use of the LUID.

Comments

An LUID_AND_ATTRIBUTES structure can represent an LUID whose attributes change frequently, such as when it is used to represent privileges in the PRIVILEGE_SET structure. Privileges are represented by LUIDs and have attributes indicating whether they are currently enabled or disabled.

See Also

»AllocateLocallyUniqueId«, »LUID«, »PRIVILEGE_SET«, »TOKEN_PRIVILEGES«


  MAT2

typedef struct _MAT2 { /* mt2 */

    FIXED eM11;

    FIXED eM12;

    FIXED eM21;

    FIXED eM22;

} MAT2;

The MAT2 structure contains the values for a transformation matrix used by the GetGlyphOutline function.

Members

eM11

Specifies a fixed-point value for the M11 component of a 3 by 3 transformation matrix.

eM12

Specifies a fixed-point value for the M12 component of a 3 by 3 transformation matrix.

eM21

Specifies a fixed-point value for the M21 component of a 3 by 3 transformation matrix.

eM22

Specifies a fixed-point value for the M22 component of a 3 by 3 transformation matrix.

Comments

The identity matrix produces a transformation in which the transformed graphical object is identical to the source object. In the identity matrix, the value of eM11 is 1, the value of eM12 is zero, the value of eM21 is zero, and the value of eM22 is 1.

See Also

»GetGlyphOutline«


  MCI_ANIM_OPEN_PARMS

typedef struct {

    DWORD   dwCallback;

    MCIDEVICEID wDeviceID;

    LPCTSTR   lpstrDeviceType;

    LPCTSTR   lpstrElementName;

    LPCSTR   lpstrAlias;

    DWORD   dwStyle;

    HWND    hWndParent;

} MCI_ANIM_OPEN_PARMS;

The MCI_ANIM_OPEN_PARMS structure contains information for the MCI_OPEN command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

wDeviceID

Specifies the device identifier returned to the user.

lpstrDeviceType

Points to the name or constant identifier of the device type.

lpstrElementName

Points to the device-element name (usually a path).

lpstrAlias

Points to an optional device alias.

dwStyle

Specifies the window style.

hWndParent

Identifies the window to use as the parent window.

Comments

You can use the MCI_OPEN_PARMS structure in place of MCI_ANIM_OPEN_PARMS if you are not using the extended data members.

See Also

»MCI_OPEN«


  MCI_ANIM_PLAY_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

    DWORD  dwSpeed;

} MCI_ANIM_PLAY_PARMS;

The MCI_ANIM_PLAY_PARMS structure contains parameters for the MCI_PLAY command message for animation devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrom

Specifies the position to play from.

dwTo

Specifies the position to play to.

dwSpeed

Specifies the play rate, in frames per second.

Comments

You can use the MCI_PLAY_PARMS structure in place of MCI_ANIM_PLAY_PARMS if you are not using the extended data members.

See Also

»MCI_PLAY«


  MCI_ANIM_RECT_PARMS

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_ANIM_RECT_PARMS;

The MCI_ANIM_RECT_PARMS structure contains parameters for the MCI_PUT and MCI_WHERE command messages for animation devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

rc

Specifies a rectangle.

See Also

»MCI_PUT«, »MCI_WHERE«


  MCI_ANIM_STEP_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrames;

} MCI_ANIM_STEP_PARMS;

The MCI_ANIM_STEP_PARMS structure contains parameters for the MCI_STEP command message for animation devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrames

Specifies the number of frames to step.

See Also

»MCI_STEP«


  MCI_ANIM_UPDATE_PARMS

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

    HDC  hDC;

} MCI_ANIM_UPDATE_PARMS;

The MCI_ANIM_UPDATE_PARMS structure contains parameters for the MCI_UPDATE command message for animation devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

rc

Specifies a window rectangle.

hDC

Identifies the device context.


  MCI_ANIM_WINDOW_PARMS

typedef struct tagMCI_ANIM_WINDOW_PARMS {

    DWORD  dwCallback;

    DWORD  hWnd;

    UINT  nCmdShow;

    LPCTSTR  lpstrText;

} MCI_ANIM_WINDOW_PARMS;

The MCI_ANIM_WINDOW_PARMS structure contains parameters for the MCI_WINDOW command message for animation devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

hWnd

Identifies the display window.

nCmdShow

Specifies how the window is displayed.

lpstrText

Points to a null-terminated string containing the window caption.

See Also

»MCI_WINDOW«


  MCI_BREAK_PARMS

typedef struct {

    DWORD  dwCallback;

    int  nVirtKey;

    HWND  hwndBreak;

} MCI_BREAK_PARMS;

The MCI_BREAK_PARMS structure contains parameters for the MCI_BREAK command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

nVirtKey

Specifies the virtual-key code used for the break key.

hwndBreak

Identifies the window that must be the current window for break detection.

See Also

»MCI_BREAK«


  MCI_GENERIC_PARMS

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

The MCI_GENERIC_PARMS structure contains information for the Media Control Interface (MCI) command messages that have empty parameter lists. When assigning data to the members in this structure, set the corresponding MCI flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.


  MCI_GETDEVCAPS_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwReturn;

    DWORD  dwItem;

} MCI_GETDEVCAPS_PARMS;

The MCI_GETDEVCAPS_PARMS structure contains parameters for the MCI_GETDEVCAPS command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwReturn

Contains the return information on exit.

dwItem

Specifies the capability being queried.

See Also

»MCI_GETDEVCAPS«


  MCI_INFO_PARMS

typedef struct {

    DWORD  dwCallback;

    LPTSTR  lpstrReturn;

    DWORD  dwRetSize;

} MCI_INFO_PARMS;

The MCI_INFO_PARMS structure contains parameters for the MCI_INFO command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpstrReturn

Points to a user-defined buffer for the return string.

dwRetSize

Specifies the size, in bytes, of the buffer for the return string.

See Also

»MCI_INFO«


  MCI_LOAD_PARMS

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpfilename;

} MCI_LOAD_PARMS;

The MCI_LOAD_PARMS structure contains information for the MCI_LOAD command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpfilename

Points to a null-terminated string containing the filename of the device element to load.

See Also

»MCI_LOAD«


  MCI_OPEN_PARMS

typedef struct {

    DWORD  dwCallback;

    MCIDEVICEID  wDeviceID;

    LPCTSTR  lpstrDeviceType;

    LPCTSTR  lpstrElementName;

    LPCTSTR  lpstrAlias;

} MCI_OPEN_PARMS;

The MCI_OPEN_PARMS structure contains information for the MCI_OPEN command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

wDeviceID

Contains the device identifier returned to the user.

lpstrDeviceType

Points to the name or constant identifier of the device type.

lpstrElementName

Points to the device-element name (usually a path).

lpstrAlias

Points to an optional device alias.

See Also

»MCI_OPEN«


  MCI_OVLY_LOAD_PARMS

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpfilename;

    RECT  rc;

} MCI_OVLY_LOAD_PARMS;

The MCI_OVLY_LOAD_PARMS structure contains parameters for the MCI_LOAD command message for video overlay devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpfilename

Points to the buffer containing a null-terminated string.

rc

Specifies a rectangle.

See Also

»MCI_LOAD«


  MCI_OVLY_OPEN_PARMS

typedef struct {

    DWORD  dwCallback;

    MCIDEVICEID  wDeviceID;

    LPCTSTR  lpstrDeviceType;

    LPCTSTR  lpstrElementName;

    LPCTSTR  lpstrAlias;

    DWORD  dwStyle;

    HWND  hWndParent;

} MCI_OVLY_OPEN_PARMS;

The MCI_OVLY_OPEN_PARMS structure contains information for the MCI_OPEN command message for video overlay devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

wDeviceID

Specifies the device identifier returned to the user.

lpstrDeviceType

Points to the name or constant identifier of the device type obtained from the SYSTEM.INI file.

lpstrElementName

Points to the device-element name (usually a path).

lpstrAlias

Points to an optional device alias.

dwStyle

Specifies the window style.

hWndParent

Identifies the window to use as the parent window.

Comments

You can use the MCI_OPEN_PARMS structure in place of MCI_OVLY_OPEN_PARMS if you are not using the extended data members.

See Also

»MCI_OPEN«


  MCI_OVLY_RECT_PARMS

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_OVLY_RECT_PARMS;

The MCI_OVLY_RECT_PARMS structure contains parameters for the MCI_PUT and MCI_WHERE command messages for video overlay devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

rc

Specifies a rectangle.

See Also

»MCI_PUT«, »MCI_WHERE«


  MCI_OVLY_SAVE_PARMS

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpfilename;

    RECT  rc;

} MCI_OVLY_SAVE_PARMS;

The MCI_OVLY_SAVE_PARMS structure contains parameters for the MCI_SAVE command message for video overlay devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpfilename

Points to the buffer containing a null-terminated string.

rc

Specifies a rectangle.

See Also

»MCI_SAVE«


  MCI_OVLY_WINDOW_PARMS

typedef struct {

    DWORD  dwCallback;

    HWND   hWnd;

    UINT   nCmdShow;

    LPCTSTR  lpstrText;

} MCI_OVLY_WINDOW_PARMS;

The MCI_OVLY_WINDOW_PARMS structure contains parameters for the MCI_WINDOW command message for video overlay devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

hWnd

Identifies the display window.

nCmdShow

Specifies how the window is displayed.

lpstrText

Points to a null-terminated buffer containing the window caption.

See Also

»MCI_WINDOW«


  MCI_PLAY_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_PLAY_PARMS;

The MCI_PLAY_PARMS structure contains parameters for the MCI_PLAY command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrom

Specifies the position to play from.

dwTo

Specifies the position to play to.

See Also

»MCI_PLAY«


  MCI_RECORD_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_RECORD_PARMS;

The MCI_RECORD_PARMS structure contains parameters for the MCI_RECORD command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrom

Specifies the position to play from.

dwTo

Specifies the position to play to.

See Also

»MCI_RECORD«


  MCI_SAVE_PARMS

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpfilename;

} MCI_SAVE_PARMS;

The MCI_SAVE_PARMS structure contains information for the MCI_SAVE command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpfilename

Points to the buffer containing a null-terminated string.

See Also

»MCI_SAVE«


  MCI_SEEK_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTo;

} MCI_SEEK_PARMS;

The MCI_SEEK_PARMS structure contains parameters for the MCI_SEEK command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwTo

Specifies the position to seek to.

See Also

»MCI_SEEK«


  MCI_SEQ_SET_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTimeFormat;

    DWORD  dwAudio;

    DWORD  dwTempo;

    DWORD  dwPort;

    DWORD  dwSlave;

    DWORD  dwMaster;

    DWORD  dwOffset;

} MCI_SEQ_SET_PARMS;

The MCI_SEQ_SET_PARMS structure contains parameters for the MCI_SET command message for Musical Instrument Digital Interface (MIDI) sequencer devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwTimeFormat

Specifies the time format of the sequencer.

dwAudio

Specifies the audio output channel.

dwTempo

Specifies the tempo.

dwPort

Specifies the output port.

dwSlave

Specifies the type of synchronization used by the sequencer for slave operation.

dwMaster

Specifies the type of synchronization used by the sequencer for master operation.

dwOffset

Specifies the data offset.

See Also

»MCI_SET«


  MCI_SET_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTimeFormat;

    DWORD  dwAudio;

} MCI_SET_PARMS;

The MCI_SET_PARMS structure contains parameters for the MCI_SET command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwTimeFormat

Specifies the time format used by the device.

dwAudio

Specifies the audio output channel.

See Also

»MCI_SET«


  MCI_SOUND_PARMS

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpstrSoundName;

} MCI_SOUND_PARMS;

The MCI_SOUND_PARMS structure contains parameters for the MCI_SOUND command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpstrSoundName

Points to a null-terminated string containing the name of the sound or the name of the file containing the sound to be played.

See Also

»MCI_SOUND«


  MCI_STATUS_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwReturn;

    DWORD  dwItem;

    DWORD  dwTrack;

} MCI_STATUS_PARMS;

The MCI_STATUS_PARMS structure contains parameters for the MCI_STATUS command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwReturn

Contains the return information on exit.

dwItem

Specifies the capability being queried.

dwTrack

Specifies the length or number of tracks.

See Also

»MCI_STATUS«


  MCI_SYSINFO_PARMS

typedef struct {

    DWORD  dwCallback;

    LPTSTR  lpstrReturn;

    DWORD  dwRetSize;

    DWORD  dwNumber;

    UINT  wDeviceType;

} MCI_SYSINFO_PARMS;

The MCI_SYSINFO_PARMS structure contains parameters for the MCI_SYSINFO command message. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpstrReturn

Points to a user-defined buffer for the return string. When the MCI_SYSINFO_QUANTITY flag is used,  lpstrReturn is evaluated as a LPDWORD, and a doubleword value is stored.

dwRetSize

Specifies the size, in bytes, of the buffer for the return string.

dwNumber

Specifies a number indicating the device position in the MCI device table or in the list of open devices if the MCI_SYSINFO_OPEN flag is set.

wDeviceType

Specifies the type of device.

See Also

»MCI_SYSINFO«


  MCI_VD_ESCAPE_PARMS

typedef struct {

    DWORD  dwCallback;

    LPCTSTR  lpstrCommand;

} MCI_VD_ESCAPE_PARMS;

The MCI_VD_ESCAPE_PARMS structure contains parameters for the MCI_ESCAPE command message for videodisc devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

lpstrCommand

Points to a null-terminated buffer containing the command to send to the device.


  MCI_VD_PLAY_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

    DWORD  dwSpeed;

} MCI_VD_PLAY_PARMS;

The MCI_VD_PLAY_PARMS structure contains parameters for the MCI_PLAY command message for videodiscs. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrom

Specifies the position to play from.

dwTo

Specifies the position to play to.

dwSpeed

Specifies the playing speed, in frames per second.

Comments

You can use the MCI_PLAY_PARMS structure in place of MCI_VD_PLAY_PARMS if you are not using the extended data members.

See Also

»MCI_PLAY«


  MCI_VD_STEP_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrames;

} MCI_VD_STEP_PARMS;

The MCI_VD_STEP_PARMS structure contains parameters for the MCI_STEP command message for videodiscs. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrames

Specifies the number of frames to step.

See Also

»MCI_STEP«


  MCI_WAVE_DELETE_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_WAVE_DELETE_PARMS;

The MCI_WAVE_DELETE_PARMS structure contains parameters for the MCI_DELETE command message for waveform audio devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwFrom

Specifies the starting position for the delete operation.

dwTo

Specifies the end position for the delete operation.

See Also

»MCI_DELETE«


  MCI_WAVE_OPEN_PARMS

typedef struct {

    DWORD  dwCallback;

    MCIDEVICEID  wDeviceID;

    LPCTSTR  lpstrDeviceType;

    LPCTSTR  lpstrElementName;

    LPCTSTR  lpstrAlias;

    DWORD  dwBufferSeconds;

} MCI_WAVE_OPEN_PARMS;

The MCI_WAVE_OPEN_PARMS structure contains information for the MCI_OPEN command message for waveform audio devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

wDeviceID

Specifies the device identifier returned to the user.

lpstrDeviceType

Points to the name or constant identifier of the device type obtained.

lpstrElementName

Points to the device-element name (usually a path).

lpstrAlias

Points to an optional device alias.

dwBufferSeconds

Specifies the buffer length, in seconds.

Comments

You can use the MCI_OPEN_PARMS structure in place of MCI_WAVE_OPEN_PARMS if you are not using the extended data members.

See Also

»MCI_OPEN«


  MCI_WAVE_SET_PARMS

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTimeFormat;

    DWORD  dwAudio;

    UINT  wInput;

    UINT  wOutput;

    WORD  wFormatTag;

    WORD  wReserved2;

    WORD  nChannels;

    WORD  wReserved3;

    DWORD  nSamplesPerSec;

    DWORD  nAvgBytesPerSec;

    WORD  nBlockAlign;

    WORD  wReserved4;

    WORD  wBitsPerSample;

    WORD  wReserved5;

} MCI_WAVE_SET_PARMS;

The MCI_WAVE_SET_PARMS structure contains parameters for the MCI_SET command message for waveform audio devices. When assigning data to the members in this structure, set the corresponding Media Control Interface (MCI) flags in the fdwCommand parameter of the mciSendCommand function to validate the members.

Members

dwCallback

Specifies a window handle used for the MCI_NOTIFY flag.

dwTimeFormat

Specifies the time format used by the device.

dwAudio

Specifies the channel used for audio output.

wInput

Specifies the channel used for audio input.

wOutput

Specifies the channel used for output.

wFormatTag

Specifies the interpretation of the waveform data.

wReserved2

Reserved; do not use.

nChannels

Specifies monaural (1) or stereo data (2).

wReserved3

Reserved; do not use.

nSamplesPerSec

Specifies the samples per second used for the waveform.

nAvgBytesPerSec

Specifies the sample rate, in bytes per second.

nBlockAlign

Specifies the block alignment of the data.

wReserved4

Reserved; do not use.

wBitsPerSample

Specifies the number of bits per sample.

wReserved5

Reserved; do not use.

See Also

»MCI_SET«


  MDICREATESTRUCT

typedef struct tagMDICREATESTRUCT { /* mdic */

    LPCTSTR szClass;

    LPCTSTR szTitle;

    HANDLE  hOwner;

    int     x;

    int     y;

    int     cx;

    int     cy;

    DWORD   style;

    LPARAM  lParam;

} MDICREATESTRUCT;

The MDICREATESTRUCT structure contains information about the class, title, owner, location, and size of a multiple document interface (MDI) child window.

Members

szClass

Points to a null-terminated string specifying the name of the window class of the MDI child window. The class name must have been registered by a previous call to the RegisterClass function.

szTitle

Points to a null-terminated string that represents the title of the MDI child window. Windows displays the title in the child window's title bar.

hOwner

Identifies the instance of the application creating the MDI client window.

x

Specifies the initial horizontal position, in client coordinates, of the MDI child window. If this parameter is CW_USEDEFAULT, the MDI child window is assigned the default horizontal position.

y

Specifies the initial vertical position, in client coordinates, of the MDI child window. If this parameter is CW_USEDEFAULT, the MDI child window is assigned the default vertical position.

cx

Specifies the initial width, in device units, of the MDI child window. If this parameter is CW_USEDEFAULT, the MDI child window is assigned the default width.

cy

Specifies the initial height, in device units, of the MDI child window. If this parameter is set to CW_USEDEFAULT, the MDI child window is assigned the default height.

style

Specifies the style of the MDI child window. If the MDI client window was created with the MDIS_ALLCHILDSTYLES window style, this parameter can be any combination of the window styles listed in the description of the CreateWindow function. Otherwise, this parameter can be one or more of the following values:

Value	Description
WS_MINIMIZE	Creates an MDI child window that is initially minimized.
WS_MAXIMIZE	Creates an MDI child window that is initially maximized.
WS_HSCROLL	Creates an MDI child window that has a horizontal scroll bar.
WS_VSCROLL	Creates an MDI child window that has a vertical scroll bar.
lParam

Specifies an application-defined 32-bit value.

Comments

When the MDI child window is created, Windows sends the WM_CREATE message to the window. The lParam parameter of WM_CREATE contains a pointer to a CREATESTRUCT structure. The lpCreateParams member of this structure contains a pointer to the MDICREATESTRUCT structure passed with the WM_MDICREATE message that created the MDI child window.

See Also

»CLIENTCREATESTRUCT«, »CREATESTRUCT«


  MEASUREITEMSTRUCT

typedef struct tagMEASUREITEMSTRUCT {   /* mis */

    UINT  CtlType;

    UINT  CtlID;

    UINT  itemID;

    UINT  itemWidth;

    UINT  itemHeight;

    DWORD itemData;

} MEASUREITEMSTRUCT;

The MEASUREITEMSTRUCT structure informs Windows of the dimensions of an owner-drawn control. This allows Windows to process user interaction with the control correctly.

Members

CtlType

Specifies the control type. This member can be one of the following values:

Value	Description
ODT_BUTTON	Owner-drawn button
ODT_COMBOBOX	Owner-drawn combo box
ODT_LISTBOX	Owner-drawn list box
ODT_MENU	Owner-drawn menu
CtlID

Specifies the identifier of the combo box, list box, or button. This member is not used for a menu.

itemID

Specifies the menu item identifier for a menu item or the list box item identifier for a variable-height list box or combo box. This member is not used for a fixed-height list box or combo box, or for a button.

itemWidth

Specifies the width, in pixels, of a menu item. Before returning from the message, the owner of the owner-drawn menu item must fill this member.

itemHeight

Specifies the height, in pixels, of an individual item in a list box or a menu. Before returning from the message, the owner of the owner-drawn combo box, list box, or menu item must fill out this member.

itemData

Specifies the application-defined 32-bit value associated with the menu item. For a control, this parameter specifies the value last assigned to the list box or combo box by the LB_SETITEMDATA or CB_SETITEMDATA message. If the list box or combo box has the LB_HASSTRINGS or CB_HASSTRINGS style, this value is initially zero. Otherwise, this value is initially the value passed to the list box or combo box in the lParam parameter of one of the following messages:

CB_ADDSTRING
CB_INSERTSTRING
LB_ADDSTRING
LB_INSERTSTRING

Comments

The owner window of an owner-drawn control receives a pointer to the MEASUREITEMSTRUCT structure as the lParam parameter of a WM_MEASUREITEM message. The owner-drawn control sends this message to its owner window when the control is created. The owner then fills in the appropriate members in the structure for the control and returns. This structure is common to all owner-drawn controls.

If an application does not fill the appropriate members of MEASUREITEMSTRUCT, the control or menu item may not be drawn properly.

See Also

»WM_MEASUREITEM«


  MEDIA_TYPE

typedef enum _MEDIA_TYPE {

    Unknown,                // Format is unknown

    F5_1Pt2_512,            // 5.25", 1.2MB,  512 bytes/sector

    F3_1Pt44_512,           // 3.5",  1.44MB, 512 bytes/sector

    F3_2Pt88_512,           // 3.5",  2.88MB, 512 bytes/sector

    F3_20Pt8_512,           // 3.5",  20.8MB, 512 bytes/sector

    F3_720_512,             // 3.5",  720KB,  512 bytes/sector

    F5_360_512,             // 5.25", 360KB,  512 bytes/sector

    F5_320_512,             // 5.25", 320KB,  512 bytes/sector

    F5_320_1024,            // 5.25", 320KB,  1024 bytes/sector

    F5_180_512,             // 5.25", 180KB,  512 bytes/sector

    F5_160_512,             // 5.25", 160KB,  512 bytes/sector

    RemovableMedia,         // Removable media other than floppy

    FixedMedia              // Fixed hard disk media

} MEDIA_TYPE;

The MEDIA_TYPE enumerated type provides a set of enumerators to describe various forms of device media. The comments above explain the enumerators.

Comments

The MediaType member of the DISK_GEOMETRY data structure is of type MEDIA_TYPE. The DeviceIoControl function receives a DISK_GEOMETRY structure in response to an IOCTL_DISK_GET_DRIVE_GEOMETRY device i/o operation. The DeviceIoControl function receives an array of DISK_GEOMETRY structures in response to an IOCTL_DISK_GET_MEDIA_TYPES device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_GET_DRIVE_GEOMETRY«, »IOCTL_DISK_GET_MEDIA_TYPES«, »DISK_GEOMETRY«


  MEMORY_BASIC_INFORMATION

typedef struct _MEMORY_BASIC_INFORMATION { /* mbi */

    PVOID BaseAddress;            /* base address of region    */

    PVOID AllocationBase;         /* allocation base address   */

    DWORD AllocationProtect;      /* initial access protection */

    DWORD RegionSize;             /* size, in bytes, of region */

    DWORD State;                  /* committed, reserved, free */

    DWORD Protect;                /* current access protection */

    DWORD Type;                   /* type of pages             */

} MEMORY_BASIC_INFORMATION;

typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;

The MEMORY_BASIC_INFORMATION structure contains information about a range of pages in the process's virtual address space. The VirtualQuery and VirtualQueryEx functions use this structure.

Members

BaseAddress

Points to the base address of the region of pages.

AllocationBase

Points to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the BaseAddress member is contained within this allocation range.

AllocationProtect

Specifies the access protection given when the region was initially allocated. One of the following flags is specified:

Value	Meaning
PAGE_NOACCESS	Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_READONLY	Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execution access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE	Enables both read and write access to the committed region of pages.
RegionSize

Specifies the size, in bytes, of the region beginning at the base address in which all pages have identical attributes.

State

Specifies the state of the pages in the region. One of the following states is indicated:

State	Meaning
MEM_COMMIT	Indicates committed pages for which physical storage has been allocated, either in memory or in the paging file on disk.
MEM_RESERVE	Indicates reserved pages where a range of the process's virtual address space is reserved without allocating any physical storage. For reserved pages, the information in the Protect member is undefined.
MEM_FREE	Indicates free pages not accessible to the calling process and available to be allocated. For free pages, the information in the AllocationBase, AllocationProtect, Protect, and Type members is undefined.
Protect

Specifies the access protection of the pages in the region. One of the flags listed for the AllocationProtect member is specified.

Type

Specifies the type of pages in the region. This value is always the MEM_PRIVATE flag, indicating that the memory is not shared by other processes.

See Also

»VirtualQuery«, »VirtualQueryEx«


  MEMORYSTATUS

typedef struct _MEMORYSTATUS { /* mst */

    DWORD dwLength;        /* sizeof(MEMORYSTATUS)        */

    DWORD dwMemoryLoad;    /* percent of memory in use    */

    DWORD dwTotalPhys;     /* bytes of physical memory    */

    DWORD dwAvailPhys;     /* free physical memory bytes  */

    DWORD dwTotalPageFile; /* bytes of paging file        */

    DWORD dwAvailPageFile; /* free bytes of paging file   */

    DWORD dwTotalVirtual;  /* user bytes of address space */

    DWORD dwAvailVirtual;  /* free user bytes             */

} MEMORYSTATUS, *LPMEMORYSTATUS;

The MEMORYSTATUS structure contains information about current memory availability. The GlobalMemoryStatus function uses this structure.

Members

dwLength

Indicates the size of this structure. The calling process should set this member prior to calling the GlobalMemoryStatus function.

dwMemoryLoad

Specifies a number between 0 and 100 that gives a general idea of current memory utilization, in which 0 indicates no memory use and 100 indicates full memory use.

dwTotalPhys

Indicates the total number of bytes of physical memory.

dwAvailPhys

Indicates the number of bytes of physical memory available.

dwTotalPageFile

Indicates the total number of bytes that can be stored in the paging file. Note that this number does not represent the actual physical size of the paging file on disk.

dwAvailPageFile

Indicates the number of bytes available in the paging file.

dwTotalVirtual

Indicates the total number of bytes that can be described in the user mode portion of the virtual address space of the calling process.

dwAvailVirtual

Indicates the number of bytes of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process.


  MENU_EVENT_RECORD

typedef struct _MENU_EVENT_RECORD { /* mer */

    UINT dwCommandId;

} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;

The MENU_EVENT_RECORD structure reports menu events in a console INPUT_RECORD structure. These events are used internally and should be ignored.

Members

dwCommandId

Used internally.

See Also

»INPUT_RECORD«


  MENUITEMTEMPLATE

typedef struct {    /* mit */

    WORD mtOption;

    WORD mtID;

    WCHAR mtString[1];

} MENUITEMTEMPLATE;

The MENUITEMTEMPLATE structure defines a menu item in a menu template.

Members

mtOption

Specifies a mask of one or more of the following predefined menu options that control the appearance of the menu item.

Value	Meaning
MF_CHECKED	Indicates that the menu item has a check mark next to it.
MF_GRAYED	Indicates that the menu item is initially inactive and drawn with a gray effect.
MF_HELP	Indicates that the menu item has a vertical separator to its left.
MF_MENUBARBREAK	Indicates that the menu item is placed in a new column. The old and new columns are separated by a bar.
MF_MENUBREAK	Indicates that the menu item is placed in a new column.
MF_OWNERDRAW	Indicates that the owner window of the menu is responsible for drawing all visual aspects of the menu item, including highlighted, checked, and inactive states. This option is not valid for an item in a menu bar.
MF_POPUP	Indicates that the item is a pop-up item (a pop-up item invokes a pop-up menu when the user chooses the item).
mtID

Specifies the menu item identifier of a command item; a command item sends a command message to its owner window. The MENUITEMTEMPLATE structure for a pop-up menu item does not contain the mtID member.

mtString

Specifies the null-terminated string for the menu item.

See Also

»LoadMenuIndirect«, »MENUITEMTEMPLATEHEADER«


  MENUITEMTEMPLATEHEADER

typedef struct {    /* mith */

    WORD versionNumber;

    WORD offset;

} MENUITEMTEMPLATEHEADER;

The MENUITEMTEMPLATEHEADER structure defines the header for a menu template. A complete menu template consists of a header and one or more menu item lists.

Members

versionNumber

Specifies the version number. This member should be zero.

offset

Specifies the offset, in bytes, from the end of the header. The menu item list begins at this offset. Usually, this member is zero, and the menu item list follows immediately after the header.

Comments

One or more MENUITEMTEMPLATE structures are combined to form the menu item list.

See Also

»LoadMenuIndirect«, »MENUITEMTEMPLATE«


  METAFILEPICT

typedef struct tagMETAFILEPICT { /* mfp */

    LONG      mm;

    LONG      xExt;

    LONG      yExt;

    HMETAFILE hMF;

} METAFILEPICT;

The METAFILEPICT structure defines the metafile picture format used for exchanging metafile data through the clipboard.

Members

mm

Specifies the mapping mode in which the picture is drawn.

xExt

Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes. (For more information about these modes, see the Exit member.) The x-extent specifies the width of the rectangle within which the picture is drawn. The coordinates are in units that correspond to the mapping mode.

yExt

Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes. The y-extent specifies the height of the rectangle within which the picture is drawn. The coordinates are in units that correspond to the mapping mode.

For MM_ISOTROPIC and MM_ANISOTROPIC modes, which can be scaled, the xExt and yExt members contain an optional suggested size in MM_HIMETRIC units. For MM_ANISOTROPIC pictures, xExt and yExt can be zero when no suggested size is supplied. For MM_ISOTROPIC pictures, an aspect ratio must be supplied even when no suggested size is given. (If a suggested size is given, the aspect ratio is implied by the size.) To give an aspect ratio without implying a suggested size, set xExt and yExt to negative values whose ratio is the appropriate aspect ratio. The magnitude of the negative xExt and yExt values is ignored; only the ratio is used.

hMF

Identifies a memory metafile.

See Also

»SetClipboardData«


  METAHEADER

typedef struct tagMETAHEADER {  /* mh */

    WORD  mtType;

    WORD  mtHeaderSize;

    WORD  mtVersion;

    DWORD mtSize;

    WORD  mtNoObjects;

    DWORD mtMaxRecord;

    WORD  mtNoParameters;

} METAHEADER;

The METAHEADER structure contains information about a metafile.

Members

mtType

Specifies whether the metafile is in memory or recorded in a disk file. This member can be one of the following values:

Value	Meaning
1	Metafile is in memory.
2	Metafile is in a disk file.
mtHeaderSize

Specifies the size, in words, of the metafile header.

mtVersion

Specifies the Windows version number. The version number for metafiles that support device-independent bitmaps (DIBs) is 0x0300. Otherwise, the version number is 0x0100.

mtSize

Specifies the size, in words, of the file.

mtNoObjects

Specifies the maximum number of objects that exist in the metafile at the same time.

mtMaxRecord

Specifies the size, in words, of the largest record in the metafile.

mtNoParameters

Reserved.

See Also

»METARECORD«


  METARECORD

typedef struct tagMETARECORD {  /* mr */

    DWORD rdSize;

    WORD  rdFunction;

    WORD  rdParm[1];

} METARECORD;

The METARECORD structure contains a metafile record.

Members

rdSize

Specifies the size, in words, of the record.

rdFunction

Specifies the function number.

rdParm

Specifies an array of words containing the function parameters, in reverse of the order they are passed to the function.

See Also

»METAHEADER«


  MIDIHDR

typedef struct midihdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    struct midihdr_tag *lpNext;

    DWORD  reserved;

} MIDIHDR;

The MIDIHDR structure defines the header used to identify a Musical Instrument Digital Interface (MIDI) system-exclusive data buffer.

Members

lpData

Points to the system-exclusive data buffer.

dwBufferLength

Specifies the length of the data buffer.

dwBytesRecorded

Specifies the amount of data in the buffer, if the header is used in input.

dwUser

Specifies user data.

dwFlags

Specifies flags giving information about the data buffer. This member can be one of the following values:

Value	Meaning
MHDR_DONE	Set by the device driver to indicate that it is finished with the data buffer and is returning it to the application.
MHDR_PREPARED	Set by Windows to indicate that the data buffer has been prepared with midiInPrepareHeader or midiOutPrepareHeader.
lpNext

Reserved; do not use.

reserved

Reserved; do not use.


  MIDIINCAPS

typedef struct midiincaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

} MIDIINCAPS;

The MIDIINCAPS structure describes the capabilities of a Musical Instrument Digital Interface (MIDI) input device.

Members

wMid

Specifies a manufacturer identifier for the device driver for the MIDI input device. Manufacturer identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

wPid

Specifies a product identifier for the MIDI input device. Product identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

vDriverVersion

Specifies the version number of the device driver for the MIDI input device. The high-order byte is the major version number, and the low-order byte is the minor version number.

szPname

Specifies the product name in a null-terminated string.

See Also

»midiInGetDevCaps«


  MIDIOUTCAPS

typedef struct midioutcaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    WORD  wTechnology;

    WORD  wVoices;

    WORD  wNotes;

    WORD  wChannelMask;

    DWORD  dwSupport;

} MIDIOUTCAPS;

The MIDIOUTCAPS structure describes the capabilities of a Musical Instrument Digital Interface (MIDI) output device.

Members

wMid

Specifies a manufacturer identifier for the device driver for the MIDI output device. Manufacturer identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

wPid

Specifies a product identifier for the MIDI output device. Product identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

vDriverVersion

Specifies the version number of the device driver for the MIDI output device. The high-order byte is the major version number, and the low-order byte is the minor version number.

szPname

Specifies the product name in a null-terminated string.

wTechnology

Specifies the type of the MIDI output device. This member can be one of the following values:

Value	Meaning
MOD_MIDIPORT	MIDI hardware port
MOD_SQSYNTH	Square wave synthesizer
MOD_FMSYNTH	FM synthesizer
MOD_MAPPER	Microsoft MIDI Mapper
wVoices

Specifies the number of voices supported by an internal synthesizer device. If the device is a port, this member is not meaningful and is set to zero.

wNotes

Specifies the maximum number of notes that may be played simultaneously by an internal synthesizer device. If the device is a port, this member is not meaningful and is set to zero.

wChannelMask

Specifies the channels that an internal synthesizer device responds to, where the least significant bit refers to channel 0 and the most significant bit to channel 15. Port devices transmit on all channels; if the device is a port, this member is set to 0xFFFF.

dwSupport

Specifies optional functionality supported by the device. This member can be one or more of the following values:

Value	Meaning
MIDICAPS_VOLUME	Supports volume control.
MIDICAPS_LRVOLUME	Supports separate left and right volume control.
MIDICAPS_CACHE	Supports patch caching.
Comments

If a device supports volume changes, the MIDICAPS_VOLUME flag is set for the dwSupport member. If a device supports separate volume changes on the left and right channels, both the MIDICAPS_VOLUME and the MIDICAPS_LRVOLUME flags are set for this member.

See Also

»midiOutGetDevCaps«


  MINMAXINFO

typedef struct tagMINMAXINFO {  /* mmi */

    POINT ptReserved;

    POINT ptMaxSize;

    POINT ptMaxPosition;

    POINT ptMinTrackSize;

    POINT ptMaxTrackSize;

} MINMAXINFO;

The MINMAXINFO structure contains information about a window's maximized size and position and its minimum and maximum tracking size.

Members

ptReserved

Reserved for internal use.

ptMaxSize

Specifies the maximized width (point.x) and the maximized height (point.y) of the window.

ptMaxPosition

Specifies the position of the left side of the maximized window (point.x) and the position of the top of the maximized window (point.y).

ptMinTrackSize

Specifies the minimum tracking width (point.x) and the minimum tracking height (point.y) of the window.

ptMaxTrackSize

Specifies the maximum tracking width (point.x) and the maximum tracking height (point.y) of the window.

See Also

»POINT«, »WM_GETMINMAXINFO«


  MMCKINFO

typedef struct _MMCKINFO {

    FOURCC  ckid;

    DWORD  cksize;

    FOURCC  fccType;

    DWORD  dwDataOffset;

    DWORD  dwFlags;

} MMCKINFO;

The MMCKINFO structure contains information about a chunk in a Resource Interchange File Format (RIFF) file.

Members

ckid

Specifies the identifier of the chunk.

cksize

Specifies the size of the data member of the chunk. The size of the data member does not include the 4-byte chunk identifier, the 4-byte chunk size, or the optional pad byte at the end of the field.

fccType

Specifies the form type for RIFF chunks or the list type for LIST chunks.

dwDataOffset

Specifies the file offset of the beginning of the chunk's data member, relative to the beginning of the file.

dwFlags

Specifies flags giving additional information about the chunk. This value can be MMIO_DIRTY, which specifies that the length of the chunk may have changed and should be updated by the mmioAscend function. This flag is set when a chunk is created by the mmioCreateChunk function.


  MMIOINFO

typedef struct _MMIOINFO {

    DWORD  dwFlags;

    FOURCC  fccIOProc;

    LPMMIOPROC  pIOProc;

    UINT  wErrorRet;

    HANDLE  htask;

    LONG  cchBuffer;

    LPSTR  pchBuffer;

    LPSTR  pchNext;

    LPSTR  pchEndRead;

    LPSTR  pchEndWrite;

    LONG  lBufOffset;

    LONG  lDiskOffset;

    DWORD  adwInfo[3];

    DWORD  dwReserved1;

    DWORD  dwReserved2;

    HMMIO  hmmio;

} MMIOINFO;

This MMIOINFO structure contains the current state of a file opened by using the mmioOpen function.

Members

dwFlags

Specifies flags indicating how a file was opened. This member can be one of the following values:

Value	Meaning
MMIO_READ	The file was opened for reading only.
MMIO_WRITE	The file was opened for writing only.
MMIO_READWRITE	The file was opened for both reading and writing.
MMIO_COMPAT	The file was opened in compatibility mode, allowing any process on a given computer to open the file any number of times.
MMIO_EXCLUSIVE	The file was opened in exclusive mode, denying other processes both read and write access to the file.
MMIO_DENYWRITE	Other processes are denied write access to the file.
MMIO_DENYREAD	Other processes are denied read access to the file.
MMIO_DENYNONE	Other processes are not denied read or write access to the file.
MMIO_CREATE	The mmioOpen function was directed to create the file or truncate it to zero length if it already existed.
MMIO_ALLOCBUF	The file's input and output (I/O) buffer was allocated by the mmioOpen or mmioSetBuffer function.
fccIOProc

Specifies the four-character code identifying the file's I/O procedure. If the I/O procedure is not an installed I/O procedure, fccIOProc is NULL.

pIOProc

Points to the file's I/O procedure.

wErrorRet

Contains the extended error value from the mmioOpen function, if mmioOpen returns NULL. This member does not receive extended error information from any other functions.

htask

Identifies the task.

cchBuffer

Specifies the size of the file's I/O buffer, in characters. If the file does not have an I/O buffer, this member is zero.

pchBuffer

Points to the file's I/O buffer. If the file does not have an I/O buffer, pchBuffer is NULL.

pchNext

Points to the next location to be read from or written to in the I/O buffer. If no more bytes can be read without calling the mmioAdvance or mmioRead function, this member points to pchEndRead. If no more bytes can be written without calling the mmioAdvance or mmioWrite function, this member points to pchEndWrite.

pchEndRead

Points to the location that is one byte past the last location in the buffer that can be read from.

pchEndWrite

Points to the location that is one byte past the last location in the buffer that can be written to.

lBufOffset

Reserved for internal use by multimedia file I/O functions; do not use.

lDiskOffset

Specifies the current file position. The current file position is an offset, in bytes, from the beginning of the file. I/O procedures are responsible for maintaining this member.

adwInfo

Contains state information maintained by the I/O procedure. I/O procedures can also use this member to transfer information from the caller to the I/O procedure when the caller opens a file.

dwReserved1

Reserved for internal use by multimedia file I/O functions; do not use.

dwReserved2

Reserved for internal use by multimedia file I/O functions; do not use.

hmmio

Identifies the open file. File I/O procedures can use this type HMMIO handle when calling other multimedia file I/O functions.

See Also

»mmioGetInfo«


  MMTIME

typedef struct mmtime_tag {

    WORD  wType;

    union {

        DWORD  ms;

        DWORD  sample;

        DWORD  cb;

        struct {

            BYTE  hour;

            BYTE  min;

            BYTE  sec;

            BYTE  frame;

            BYTE  fps;

            BYTE  dummy;

        } smpte;

        struct {

            DWORD  songptrpos;

        } midi;

    } u;

} MMTIME;

The MMTIME structure is a general-purpose structure for timing information.

Members

wType

Specifies the type of the union. This member can be one of the following values:

Value	Meaning
TIME_MS	Time counted in milliseconds
TIME_SAMPLES	Number of wave samples
TIME_BYTES	Current byte offset
TIME_SMPTE	Society of Motion Picture and Television Engineers (SMPTE) time
TIME_MIDI	Musical Instrument Digital Interface (MIDI) time
u

Specifies the contents of the union. The following members are contained in the u union:

Member	Meaning
ms	Milliseconds. Used when the wType member of the MMTIME structure is TIME_MS.
sample	Samples. Used when wType is TIME_SAMPLES.
cb	Byte count. Used when wType is TIME_BYTES.
smpte	SMPTE time. Used when wType is TIME_SMPTE. The following members are contained in the smpte structure:
Member	Meaning
hour	Hours
min	Minutes
sec	Seconds
frame	Frames
fps	Frames per second (24, 25, 29[30 drop] or 30)
dummy	Dummy byte for alignment
midi	MIDI time. Used when wType is TIME_MIDI. The following member is contained in the midi structure:
Member	Meaning
songptrpos	Song pointer position


  MONCBSTRUCT

typedef struct tagMONCBSTRUCT { /* mcbst */

    UINT   cb;

    DWORD  dwTime;

    HANDLE hTask;

    DWORD  dwRet;

    UINT   wType;

    UINT   wFmt;

    HCONV  hConv;

    HSZ    hsz1;

    HSZ    hsz2;

    HDDEDATA hData;

    DWORD    dwData1;

    DWORD    dwData2;

    CONVCONTEXT cc;

    DWORD  cbData;

    DWORD  Data[8];

} MONCBSTRUCT;

The MONCBSTRUCT structure contains information about the current dynamic data exchange (DDE) transaction. A DDE debugging application can use this structure when monitoring transactions that the system passes to the DDE callback functions of other applications.

Members

cb

Specifies the length, in bytes, of the structure.

dwTime

Specifies the Windows time that the transaction occurred. Windows time is the number of milliseconds that have elapsed since the system was booted.

hTask

Identifies the task (application instance) containing the DDE callback function that received the transaction.

dwRet

Specifies the value returned by the DDE callback function that processed the transaction.

wType

Identifies the transaction type.

wFmt

Specifies the format of the data exchanged (if any) during the transaction.

hConv

Identifies the conversation in which the transaction took place.

hsz1

Identifies a string.

hsz2

Identifies a string.

hData

Identifies the data exchanged (if any) during the transaction.

dwData1

Specifies additional data.

dwData2

Specifies additional data.

cc

Specifies a CONVCONTEXT structure containing language information used to share data in different languages.

cbData

Specifies the amount, in bytes, of data being passed with the transaction. This value may be more than 32 bytes.

Data

Contains the first 32 bytes of data being passed with the transaction (8 * sizeof(DWORD)).

See Also

»CONVCONTEXT«, »MONERRSTRUCT«, »MONHSZSTRUCT«, »MONLINKSTRUCT«, »MONMSGSTRUCT«


  MONCONVSTRUCT

typedef struct tagMONCONVSTRUCT { /* mcvst */

    UINT   cb;

    BOOL   fConnect;

    DWORD  dwTime;

    HANDLE hTask;

    HSZ    hszSvc;

    HSZ    hszTopic;

    HCONV  hConvClient;

    HCONV  hConvServer;

} MONCONVSTRUCT;

The MONCONVSTRUCT structure contains information about a conversation. A DDE monitoring application can use this structure to obtain information about a conversation that has been established or has terminated.

Members

cb

Specifies the length, in bytes, of the structure.

fConnect

Indicates whether the conversation is currently established. A value of TRUE indicates the conversation is established; FALSE indicates it is not.

dwTime

Specifies the Windows time at which the conversation was established or terminated. Windows time is the number of milliseconds that have elapsed since the system was booted.

hTask

Identifies a task (application instance) that is a partner in the conversation.

hszSvc

Identifies the service name on which the conversation is established.

hszTopic

Identifies the topic name on which the conversation is established.

hConvClient

Identifies the client conversation handle.

hConvServer

Identifies the server conversation handle.

Comments

In Windows NT, string handles are local to the process; therefore, the hszSvc and hszTopic members are global atoms.

In Windows NT, conversation handles are local to the instance; therefore, the hConvClient and hConvServer members are window handles.

The hConvClient and hConvServer members of the MONCONVSTRUCT structure do not hold the same value as would be seen by the applications engaged in the conversation. Instead, they hold a globally unique pair of values that identify the conversation.

See Also

»MONCBSTRUCT«, »MONERRSTRUCT«, »MONHSZSTRUCT«, »MONLINKSTRUCT«, »MONMSGSTRUCT«


  MONERRSTRUCT

typedef struct tagMONERRSTRUCT { /* mest */

    UINT   cb;

    UINT   wLastError;

    DWORD  dwTime;

    HANDLE hTask;

} MONERRSTRUCT;

The MONERRSTRUCT structure contains information about the current dynamic data exchange (DDE) error. A DDE monitoring application can use this structure to monitor errors returned by DDE Management Library functions.

Members

cb

Specifies the length, in bytes, of the structure.

wLastError

Identifies the current error.

dwTime

Specifies the Windows time that the error occurred. Windows time is the number of milliseconds that have elapsed since the system was booted.

hTask

Identifies the task (application instance) that called the DDE function that caused the error.

See Also

»MONCBSTRUCT«, »MONCONVSTRUCT«, »MONHSZSTRUCT«, »MONLINKSTRUCT«, »MONMSGSTRUCT«


  MONHSZSTRUCT

typedef struct tagMONHSZSTRUCT { /* mhst */

    UINT   cb;

    BOOL   fsAction;

    DWORD  dwTime;

    HSZ    hsz;

    HANDLE hTask;

    char   str[1];

} MONHSZSTRUCT;

The MONHSZSTRUCT structure contains information about a DDE string handle. A DDE monitoring application can use this structure when monitoring the activity of the string manager component of the DDE Management Library.

Members

cb

Specifies the length, in bytes, of the structure.

fsAction

Specifies the action being performed on the string handle specified by the hsz member.

Value	Meaning
MH_CLEANUP	An application is freeing its DDE resources, causing the system to delete string handles the application had created. (The application called the DdeUninitialize function.)
MH_CREATE	An application is creating a string handle. (The application called the DdeCreateStringHandle function.)
MH_DELETE	An application is deleting a string handle. (The application called the DdeFreeStringHandle function.)
MH_KEEP	An application is increasing the use count of a string handle. (The application called the DdeKeepStringHandle function.)
dwTime

Specifies the Windows time when the action specified by the fsAction member takes place. Windows time is the number of milliseconds that have elapsed since the system was booted.

hsz

Identifies the string. In Windows NT, string handles are local to the process; therefore, this member is a global atom.

hTask

Identifies the task (application instance) performing the action on the string handle.

str

Points to the string identified by the hsz member.

See Also

»MONCBSTRUCT«, »MONCONVSTRUCT«, »MONERRSTRUCT«, »MONLINKSTRUCT«, »MONMSGSTRUCT«


  MONITOR_INFO_1

typedef struct _MONITOR_INFO_1 { /* mi1 */

    LPTSTR pName;

} MONITOR_INFO_1;

The MONITOR_INFO_1 structure identifies an installed monitor.

Members

pName

Points to a null-terminated string that identifies an installed monitor.

See Also

»EnumMonitors« »MONITOR_INFO_2«


  MONITOR_INFO_2

typedef struct _MONITOR_INFO_2 { /* mi2 */

    LPTSTR pName;

    LPTSTR pEnvironment ;

    LPTSTR pDLLName ;

} MONITOR_INFO_2;

The MONITOR_INFO_2 structure identifies a monitor.

Members

pName

Points to a null-terminated string that is the name of the monitor.

pEnvironment

Points to a null-terminated environment string specifying the environment this DLL is designed to run in.

pDLLName

Points to a null-terminated string that is the name of the monitor DLL.

See Also

»EnumMonitors«, »MONITOR_INFO_1«


  MONLINKSTRUCT

typedef struct tagMONLINKSTRUCT { /* mlst */

    UINT   cb;

    DWORD  dwTime;

    HANDLE hTask;

    BOOL   fEstablished;

    BOOL   fNoData;

    HSZ    hszSvc;

    HSZ    hszTopic;

    HSZ    hszItem;

    UINT   wFmt;

    BOOL   fServer;

    HCONV  hConvServer;

    HCONV  hConvClient;

} MONLINKSTRUCT;

The MONLINKSTRUCT structure contains information about a dynamic data exchange (DDE) advise loop. A DDE monitoring application can use this structure to obtain information about an advise loop that has started or ended.

Members

cb

Specifies the length, in bytes, of the structure.

dwTime

Specifies the Windows time when the advise loop was started or ended. Windows time is the number of milliseconds that have elapsed since the system was booted.

hTask

Identifies a task (application instance) that is a partner in the advise loop.

fEstablished

Indicates whether an advise loop was successfully established. A value of TRUE indicates an advise loop was established; FALSE indicates it was not.

fNoData

Indicates whether the XTYPF_NODATA flag is set for the advise loop. A value of TRUE indicates the flag is set; FALSE indicates it is not.

hszSvc

Identifies the service name of the server in the advise loop. In Windows NT, string handles are local to the process; therefore, this member is a global atom.

hszTopic

Identifies the topic name on which the advise loop is established. In Windows NT, string handles are local to the process; therefore, this member is a global atom.

hszItem

Identifies the item name that is the subject of the advise loop. In Windows NT, string handles are local to the process; therefore, this member is a global atom.

wFmt

Specifies the format of the data exchanged (if any) during the advise loop.

fServer

Indicates whether the link notification came from the server. A value of TRUE indicates the notification came from the server; FALSE indicates otherwise.

hConvServer

Identifies the server conversation.

hConvClient

Identifies the client conversation.

Comments

In Windows NT, string handles are local to the process; therefore, the hszSvc, hszTopic, and hszItem members are actually global atoms.

The hConvClient and hConvServer members of the MONCONVSTRUCT structure do not hold the same value as would be seen by the applications engaged in the conversation. Instead, they hold a globally unique pair of values that identify the conversation.

See Also

»MONCBSTRUCT«, »MONERRSTRUCT«, »MONHSZSTRUCT«, »MONMSGSTRUCT«


  MONMSGSTRUCT

typedef struct tagMONMSGSTRUCT { /* mmst */

    UINT   cb;

    HWND   hwndTo;

    DWORD  dwTime;

    HANDLE hTask;

    UINT   wMsg;

    WPARAM wParam;

    LPARAM lParam;

    DDEML_MSG_HOOK_DATA dmhd;

} MONMSGSTRUCT;

The MONMSGSTRUCT structure contains information about a DDE message. A DDE monitoring application can use this structure to obtain information about a DDE message that was sent or posted.

Members

cb

Specifies the length, in bytes, of the structure.

hwndTo

Identifies the window that receives the DDE message.

dwTime

Specifies the Windows time at which the message was sent or posted. Windows time is the number of milliseconds that have elapsed since the system was booted.

hTask

Identifies the task (application instance) containing the window that receives the DDE message.

wMsg

Specifies the identifier of the DDE message.

wParam

Specifies the wParam parameter of the DDE message.

lParam

Specifies the lParam parameter of the DDE message.

dmhd

Specifies a DDEML_MSG_HOOK_DATA structure that contains additional information about the DDE message.

See Also

»DDEML_MSG_HOOK_DATA«, »MONCBSTRUCT«, »MONCONVSTRUCT«, »MONERRSTRUCT«, »MONHSZSTRUCT«, »MONLINKSTRUCT«


  MOUSE_EVENT_RECORD

typedef struct _MOUSE_EVENT_RECORD { /* mer */

    COORD dwMousePosition;

    DWORD dwButtonState;

    DWORD dwControlKeyState;

    DWORD dwEventFlags;

} MOUSE_EVENT_RECORD;

The MOUSE_EVENT_RECORD structure is used in a console INPUT_RECORD structure to report mouse input events.

Members

dwMousePosition

Specifies the location of the cursor in terms of the screen buffer's character-cell coordinates.

dwButtonState

Indicates the status of the mouse buttons. The least significant bit corresponds to the leftmost mouse button. The next least significant bit corresponds to the rightmost mouse button. The next bit indicates the next-to-leftmost mouse button. The bits then correspond left-to-right to the mouse buttons. A bit is 1 if the button was pressed.

dwControlKeyState

Indicates the state of the control keys. This member can be a combination of the following values:

Value	Meaning
RIGHT_ALT_PRESSED	The right ALT key is pressed.
LEFT_ALT_PRESSED	The left ALT key is pressed.
RIGHT_CTRL_PRESSED	The right CTRL key is pressed.
LEFT_CTRL_PRESSED	The left CTRL key is pressed.
SHIFT_PRESSED	The SHIFT key is pressed.
NUMLOCK_ON	The NUM LOCK light is on.
SCROLLLOCK_ON	The SCROLL LOCK light is on.
CAPSLOCK_ON	The CAPS LOCK light is on.
ENHANCED_KEY	The key is enhanced.
dwEventFlags

Indicates the type of mouse event. If this value is zero, it indicates a mouse button being pressed or released. Otherwise, the value is one of the following:

Value	Meaning
MOUSE_MOVED	A change in mouse position occurred.
DOUBLE_CLICK	The second click (button press) of a double-click occurred. The first click is returned as a regular button-press event.
Comments

Mouse events are placed in the input buffer when the console is in mouse mode (ENABLE_MOUSE_INPUT).

Mouse events are generated whenever the user moves the mouse, or presses or releases one of the mouse buttons. Mouse events are placed in a console's input buffer only when the console group has the keyboard focus and the cursor is within the borders of the console's window.

See Also

»PeekConsoleInput«, »ReadConsoleInput«, »WriteConsoleInput«


  MOUSEHOOKSTRUCT

typedef struct tagMOUSEHOOKSTRUCT { /* ms */

    POINT pt;

    HWND  hwnd;

    UINT  wHitTestCode;

    DWORD dwExtraInfo;

} MOUSEHOOKSTRUCT;

The MOUSEHOOKSTRUCT structure contains information about a mouse event.

Members

pt

Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates.

hwnd

Identifies the window that will receive the mouse message corresponding to the mouse event.

wHitTextCode

Specifies the hit-test code. For a list of hit-test codes, see the description of the »WM_NCHITTEST« message.

dwExtraInfo

Specifies extra information associated with the message.

See Also

»GetMessageExtraInfo«, »SetWindowsHook«


  MSG

typedef struct tagMSG {     /* msg */

    HWND   hwnd;

    UINT   message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD  time;

    POINT  pt;

} MSG;

The MSG structure contains message information from a thread's message queue.

Members

hwnd

Identifies the window whose window procedure receives the message.

message

Specifies the message number.

wParam

Specifies additional information about the message. The exact meaning depends on the value of the message member.

lParam

Specifies additional information about the message. The exact meaning depends on the value of the message member.

time

Specifies the time at which the message was posted.

pt

Specifies the cursor position, in screen coordinates, when the message was posted.

See Also

»GetMessage«, »PeekMessage«


  MULTIKEYHELP

typedef struct tagMULTIKEYHELP { /* mkh */

    DWORD mkSize;

    BYTE  mkKeylist;

    TCHAR szKeyphrase[1];

} MULTIKEYHELP;

The MULTIKEYHELP structure specifies a keyword table and an associated keyword to be used by the Windows Help application.

Members

mkSize

Specifies the length, in bytes, of the MULTIKEYHELP structure.

mkKeylist

Specifies a single character that identifies the keyword table to be searched.

szKeyphrase[]

Contains a null-terminated text string that specifies the keyword to be located in the keyword table.

See Also

»WinHelp«


  NAME_BUFFER

typedef struct _NAME_BUFFER { /* nb */

    UCHAR name[NCBNAMSZ];

    UCHAR name_num;

    UCHAR name_flags;

} NAME_BUFFER;

The NAME_BUFFER structure contains information about a local network name. One or more NAME_BUFFER structures follows an ADAPTER_STATUS structure when an application specifies NCBASTAT in the ncb_command member of the NCB structure.

Members

name

Specifies the local network name. This is the value in the ncb_name member of the NCB structure.

name_num

Specifies the number for the local network name. This is the value in the ncb_num member of the NCB structure.

name_flags

Specifies the current state of the name table entry. This member can be one of the following values:

Value	Meaning
REGISTERING	The name specified by the name member is being added to the network.
REGISTERED	The name specified by the name member has been successfully added to the network.
DEREGISTERED	The name specified by the name member has an active session when an NCBDELNAME command is issued. The name will be removed from the name table when the session is closed.
DUPLICATE	A duplicate name was detected during registration.
DUPLICATE_DEREG	A duplicate name was detected with a pending deregistration.
GROUP_NAME	The name specified by the name member was created using the NCBADDGRNAME command.
UNIQUE_NAME	The name specified by the name member was created with using the NCBADDNAME command.
See Also

»ADAPTER_STATUS«, »NCB«


  NCB

typedef struct _NCB { /* ncb */

    UCHAR  ncb_command;

    UCHAR  ncb_retcode;

    UCHAR  ncb_lsn;

    UCHAR  ncb_num;

    PUCHAR ncb_buffer;

    WORD   ncb_length;

    UCHAR  ncb_callname[NCBNAMSZ];

    UCHAR  ncb_name[NCBNAMSZ];

    UCHAR  ncb_rto;

    UCHAR  ncb_sto;

    void (*ncb_post) (struct _NCB *);

    UCHAR  ncb_lana_num;

    UCHAR  ncb_cmd_cplt;

    UCHAR  ncb_reserve[10];

    HANDLE ncb_event;

} NCB;

The NCB structure describes a network-control block. A pointer to this structure is passed to the Netbios function.

Members

ncb_command

Specifies the command code and a flag that indicates whether the NCB is processed asynchronously. The most significant bit contains the flag. If the ASYNCH constant is combined with a command code (by using the OR operator), the NCB is processed asynchronously. The following command codes are supported:

Code	Meaning
NCBACTION	Enables extensions to the transport interface. NCBACTION commands are mapped to TdiAction. When this value is specified, the ncb_buffer member points to a buffer to be filled with an ACTION_HEADER structure, which is optionally followed by data. NCBACTION commands cannot be canceled by using NCBCANCEL.
NCBADDGRNAME	Add a group name to the local name table.
NCBADDNAME	Add a unique name to the local name table.
NCBASTAT	Retrieve the status of the adapter. When this value is specified, the ncb_buffer member points to a buffer to be filled with an ADAPTER_STATUS structure, followed by an array of NAME_BUFFER structures.
NCBCALL	Open a session with another name.
NCBCANCEL	Cancel a previous command.
NCBCHAINSEND	Send the contents of two data buffers to the specified session partner. For Windows NT, this is equivalent to the NCBCHAINSENDNA command.
NCBCHAINSENDNA	Send the contents of two data buffers to the specified session partner and do not wait for acknowledgment. For Windows NT, this is equivalent to the NCBCHAINSEND command.
NCBDELNAME	Delete a name from the local name table.
NCBDGRECV	Receive a datagram from any name.
NCBDGRECVBC	Receive broadcast datagram from any host.
NCBDGSEND	Send datagram to a specified name.
NCBDGSENDBC	Send a broadcast datagram to every host on the local area network (LAN).
NCBENUM	Enumerate LAN adapter (LANA) numbers. When this value is specified, the ncb_buffer member points to a buffer to be filled with a LANA_ENUM structure.
NCBFINDNAME	Determine the location of a name on the network. When this value is specified, the ncb_buffer member points to a buffer to be filled with a FIND_NAME_HEADER structure followed by one or more FIND_NAME_BUFFER structures.
NCBHANGUP	Close a specified session.
NCBLANSTALERT	Notify the user of LAN failures that last for more than one minute.
NCBLISTEN	Enable a session to be opened with another name.
NCBRECV	Receive data from the specified session partner.
NCBRECVANY	Receive data from any session corresponding to a specified name.
NCBRESET	Reset a LAN adapter. An adapter must be reset before any other NCB command that specifies the same number in the ncb_lana_num member will be accepted.
	The IBM Netbios 3.0 specification documents several NCB_RESET NCB's. Win32 implements the "NCB.RESET Using the Dynamic Link Routine Interface". Particular values can be passed in specific bytes of the NCB. More specifically:
•	If ncb_lsn is not 0x00, all resources associated with ncb_lana_num are to be freed.

•	If ncb_lsn is 0x00, all resources associated with ncb_lana_num are to be freed, and new resources are to be allocated. The byte ncb_callname[0] specifies the maximum number of sessions, and the byte ncb_callname[2] specifies the maximum number of names. A non-zero value for the byte ncb_callname[3] requests that the application use NAME_NUMBER_1.

NCBSEND	Send data to the specified session partner. For Windows NT, this is equivalent to the NCBSENDNA command.
NCBSENDNA	Send data to specified session partner and do not wait for an acknowledgment. For Windows NT, this is equivalent to the NCBSEND command.
NCBSSTAT	Retrieve the status of the session. When this value is specified, the ncb_buffer member points to a buffer to be filled with a SESSION_HEADER structure, followed by one or more SESSION_BUFFER structures.
NCBTRACE	Activate or deactivate NCB tracing. Support for this command in the system is optional and system-specific.
NCBUNLINK	Unlink the adapter.
ncb_retcode

Specifies the return code. This value is set to NRC_PENDING while an asynchronous operation is in progress. The return codes can be one of the following:

Return code	Meaning
NRC_GOODRET	The operation succeeded.
NRC_BUFLEN	An illegal buffer length was supplied.
NRC_ILLCMD	An illegal command was supplied.
NRC_CMDTMO	The command was timed out.
NRC_INCOMP	The message was incomplete. The application is to issue another command.
NRC_BADDR	The buffer address was illegal.
NRC_SNUMOUT	The session number was out of range.
NRC_NORES	No resource was available.
NRC_SCLOSED	The session was closed.
NRC_CMDCAN	The command was canceled.
NRC_DUPNAME	A duplicate name existed in the local name table.
NRC_NAMTFUL	The name table was full.
NRC_ACTSES	The command finished; the name has active sessions and is no longer registered.
NRC_LOCTFUL	The local session table was full.
NRC_REMTFUL	The remote session table was full. The request to open a session was rejected.
NRC_ILLNN	An illegal name number was specified.
NRC_NOCALL	The system did not find the name that was called.
NRC_NOWILD	Wildcards are not permitted in the ncb_name member.
NRC_INUSE	The name was already in use on the remote adapter.
NRC_NAMERR	The name was deleted.
NRC_SABORT	The session ended abnormally.
NRC_NAMCONF	A name conflict was detected.
NRC_IFBUSY	The interface was busy.
NRC_TOOMANY	Too many commands were outstanding; the application can retry the command later.
NRC_BRIDGE	The ncb_lana_num member did not specify a valid network number.
NRC_CANOCCR	The command finished while a cancel operation was occurring.
NRC_CANCEL	The NCBCANCEL command was not valid; the command was not canceled.
NRC_DUPENV	The name was defined by another local process.
NRC_ENVNOTDEF	The environment was not defined. A reset command must be issued.
NRC_OSRESNOTAV	Operating system resources were exhausted. The application can retry the command later.
NRC_MAXAPPS	The maximum number of applications was exceeded.
NRC_NOSAPS	No SAPs available for netbios.
NRC_NORESOURCES	The requested resources were not available.
NRC_INVADDRESS	The NCB address was not valid.
	This return code is not part of the IBM NetBIOS 3.0 specification. This return code is not returned in the NCB; instead, it is returned by the Netbios function.
NRC_INVDDID	The NCB DDID was invalid.
NRC_LOCKFAIL	The attempt to lock the user area failed.
NRC_OPENERR	An error occurred during an open operation being performed by the device driver. This return code is not part of the IBM NetBIOS 3.0 specification.
NRC_SYSTEM	A system error occurred.
NRC_PENDING	An asynchronous operation is not yet finished.
ncb_lsn

Specifies the local session number. This number uniquely identifies a session within an environment.

ncb_buffer

Points to the message buffer.

ncb_length

Specifies the size, in bytes, of the message buffer.

ncb_callname

Specifies the string that contains the remote name. Trailing space characters should be supplied to bring the length of the string specified by the NCBNAMSZ command.

ncb_name Specifies the string that contains the local name. Trailing space characters should be supplied to bring the length of the string specified by the NCBNAMSZ command.

ncb_rto

Specifies the receive time-out period, in 500-millisecond units, for the session. A value of 0 implies no timeout. Specified only for NCBRECV commands.

ncb_sto

Specifies the send time-out period, in 500-millisecond units, for the session. A value of 0 implies no timeout. Specified only for NCBSEND and NCBCHAINSEND commands.

ncb_post

Specifies the address of the routine to call when the asynchronous NCB finishes. The completion routine is passed a pointer to the completed network-control block.

ncb_lana_num

Specifies the LAN adapter number. This zero-based number corresponds to a particular transport provider using a particular LAN adapter board.

ncb_cmd_cplt

Specifies the command-complete flag. This value is the same as the ncb_retcode member.

ncb_reserve

Reserved. This member must be set to zero.

ncb_event

Specifies a handle to a Windows event that is set to the signaled state when the asynchronous network-control block finishes. The event is signaled if the Netbios function returns a nonzero value.

The ncb_event member must be zero if the ncb_command member does not have the ASYNCH value set or if ncb_post is non-zero. Otherwise, NRC_ILLCMD is returned.

The event specified by ncb_event is set to the non-signalled state by the system when an asynchronous NetBIOS command is accepted, and is set to the signalled state when the asynchronous NetBIOS command finishes.

Using ncb_event to submit asynchronous requests requires fewer system resources than using ncb_post. Also, when ncb_event is nonzero, the pending request is canceled if the thread terminates before the request is processed. This is not true for requests sent by using ncb_post.

Only manual reset events should be used with Netbios. A given event should not be associated with more than one active asynchronous NetBIOS command.

See Also

»ADAPTER_STATUS«, »FIND_NAME_BUFFER«, »FIND_NAME_HEADER«, »LANA_ENUM«, »NAME_BUFFER«, »Netbios«, »SESSION_HEADER«


  NCCALCSIZE_PARAMS

typedef struct tagNCCALCSIZE_PARAMS { /* nccp */

    RECT       rgrc[3];

    PWINDOWPOS lppos;

} NCCALCSIZE_PARAMS;

The NCCALCSIZE_PARAMS structure contains information that an application can use while processing the WM_NCCALCSIZE message to calculate the size, position, and valid contents of the client area of a window.

Members

rgrc

Specifies an array of rectangles. The first contains the new coordinates of a window that has been moved or resized. The second contains the coordinates of the window before it was moved or resized. The third contains the coordinates of the window's client area before the window was moved or resized. If the window is a child window, the coordinates are relative to the client area of the parent window. If the window is a top-level window, the coordinates are relative to the screen origin.

lppos

Points to a WINDOWPOS structure that contains the size and position values specified in the operation that moved or resized the window. The WINDOWPOS structure has the following form:

typedef struct tagWINDOWPOS { /* wp */

    HWND hwnd;

    HWND hwndInsertAfter;

    int  x;

    int  y;

    int  cx;

    int  cy;

    UINT flags;

} WINDOWPOS;

See Also

»MoveWindow«, »RECT«, »SetWindowPos«, »WINDOWPOS«, »WM_NCCALCSIZE«


  NETRESOURCE

typedef struct _NETRESOURCE {  /* nr */

    DWORD  dwScope;

    DWORD  dwType;

    DWORD  dwDisplayType;

    DWORD  dwUsage;

    LPTSTR lpLocalName;

    LPTSTR lpRemoteName;

    LPTSTR lpComment;

    LPTSTR lpProvider;

} NETRESOURCE;

The NETRESOURCE structure is returned during enumeration of resources on the network and during enumeration of currently connected resources.

Members

dwScope

Specifies the scope of the enumeration. Currently, this member can be one of the following values:

Value	Meaning
RESOURCE_CONNECTED	Currently connected resources (dwUsage is undefined)
RESOURCE_GLOBALNET	Resources on the network
RESOURCE_REMEMBERED	Remembered (persistent) connections (dwUsage is undefined)
dwType

Specifies a bitmask that gives the resource type. Currently, this member can be one of the following values:

Value	Meaning
RESOURCETYPE_ANY	All resources
RESOURCETYPE_DISK	Disk resources
RESOURCETYPE_PRINT	Print resources
dwDisplayType

Specifies how the network object should be displayed in a network browsing user interface. Currently, this member can be the following values:

Value	Meaning
RESOURCEDISPLAYTYPE_DOMAIN
	The object should be displayed as a domain.
RESOURCEDISPLAYTYPE_GENERIC
	The method used to display the object does not matter.
RESOURCEDISPLAYTYPE_SERVER
	The object should be displayed as a server.
RESOURCEDISPLAYTYPE_SHARE
	The object should be displayed as a sharepoint.
dwUsage

Specifies a bitmask that gives the resource usage. This member is defined only if dwScope is RESOURCE_GLOBALNET. Currently, this member can be one of the following values:

Value	Meaning
RESOURCEUSAGE_CONNECTABLE	This is a connectable resource; the name pointed to by the lpRemoteName member can be passed to the WNetAddConnection function to make a network connection.
RESOURCEUSAGE_CONTAINER	This is a container resource; the name pointed to by the lpRemoteName member can be passed to the WNetOpenEnum function to enumerate the resources in the container.
lpLocalName

Points to the name of a local device if the dwScope member is RESOURCE_CONNECTED or RESOURCE_REMEMBERED. This member is NULL if the connection does not use a device. Otherwise, it is undefined.

lpRemoteName

Points to a remote network name if the entry is a network resource.

If the entry is a current or remembered connection, lpRemoteName points to the network name associated with the name pointed to by the lpLocalName member.

lpComment

Points to a provider-supplied comment.

lpProvider

Points to the name of the provider owning this resource. This member can be NULL if the provider name is unknown.

See Also

»WNetCloseEnum«, »WNetEnumResource«, »WNetOpenEnum«


  NEWCPLINFO

typedef struct tagNEWCPLINFO {  /* ncpli */

    DWORD dwSize;

    DWORD dwFlags;

    DWORD dwHelpContext;

    LONG  lData;

    HICON hIcon;

    char  szName[32];

    char  szInfo[64];

    char  szHelpFile[128];

} NEWCPLINFO;

The NEWCPLINFO structure contains resource information and a user-defined value for a Control Panel application.

Members

dwSize

Specifies the length of the structure, in bytes.

dwFlags

Specifies Control Panel flags.

dwHelpContext

Specifies the context number for the topic in the help project (.HPJ) file that displays when the user selects help for the application.

lData

Specifies data defined by the application.

hIcon

Identifies an icon resource for the application icon. This icon is displayed in the Control Panel window.

szName

Specifies a null-terminated string that contains the application name. The name is the short string displayed below the application icon in the Control Panel window. The name is also displayed in the Settings menu of Control Panel.

szInfo

Specifies a null-terminated string containing the application description. The description displayed at the bottom of the Control Panel window when the application icon is selected.

szHelpFile

Specifies a null-terminated string that contains the path of the help file, if any, for the application.

See Also

»CPLINFO«, »CPL_NEWINQUIRE«


  NEWTEXTMETRIC

typedef struct tagNEWTEXTMETRIC { /* ntm */

    LONG  tmHeight;

    LONG  tmAscent;

    LONG  tmDescent;

    LONG  tmInternalLeading;

    LONG  tmExternalLeading;

    LONG  tmAveCharWidth;

    LONG  tmMaxCharWidth;

    LONG  tmWeight;

    LONG  tmOverhang;

    LONG  tmDigitizedAspectX;

    LONG  tmDigitizedAspectY;

    BYTE  tmFirstChar;

    BYTE  tmLastChar;

    BYTE  tmDefaultChar;

    BYTE  tmBreakChar;

    BYTE  tmItalic;

    BYTE  tmUnderlined;

    BYTE  tmStruckOut;

    BYTE  tmPitchAndFamily;

    BYTE  tmCharSet;

    DWORD ntmFlags;

    UINT  ntmSizeEM;

    UINT  ntmCellHeight;

    UINT  ntmAvgWidth;

} NEWTEXTMETRIC;

The NEWTEXTMETRIC structure contains data that describes a physical font.

Members

tmHeight

Specifies the height (ascent + descent) of characters.

tmAscent

Specifies the ascent (units above the base line) of characters.

tmDescent

Specifies the descent (units below the base line) of characters.

tmInternalLeading

Specifies the amount of leading (space) inside the bounds set by the tmHeight member. Accent marks and other diacritical characters may occur in this area. The designer may set this member to zero.

tmExternalLeading

Specifies the amount of extra leading (space) that the application adds between rows. Since this area is outside the font, it contains no marks and is not altered by text output calls in either OPAQUE or TRANSPARENT mode. The designer may set this member to zero.

tmAveCharWidth

Specifies the average width of characters in the font (generally defined as the width of the letter x). This value does not include overhang required for bold or italic characters.

tmMaxCharWidth

Specifies the width of the widest character in the font.

tmWeight

Specifies the weight of the font.

tmOverhang

Specifies the extra width per-string that may be added to some synthesized fonts. When synthesizing some attributes, such as bold or italic, graphics device interface (GDI) or a device may have to add width to a string on both a per-character and per-string basis. For example, GDI makes a string bold by expanding the spacing of each character and overstriking by an offset value; it italicizes a font by shearing the string. In either case, there is an overhang past the basic string. For bold strings, the overhang is the distance by which the overstrike is offset. For italic strings, the overhang is the amount the top of the font is sheared past the bottom of the font.

The tmOverhang member enables the application to determine how much of the character width returned by a GetTextExtentPoint function call on a single character is the actual character width and how much is the per-string extra width. The actual width is the extent minus the overhang.

tmDigitizedAspectX

Specifies the horizontal aspect of the device for which the font was designed.

tmDigitizedAspectY

Specifies the vertical aspect of the device for which the font was designed. The ratio of the tmDigitizedAspectX and tmDigitizedAspectY members is the aspect ratio of the device for which the font was designed.

tmFirstChar

Specifies the value of the first character defined in the font.

tmLastChar

Specifies the value of the last character defined in the font.

tmDefaultChar

Specifies the value of the character to be substituted for characters that are not in the font.

tmBreakChar

Specifies the value of the character to be used to define word breaks for text justification.

tmItalic

Specifies an italic font if it is nonzero.

tmUnderlined

Specifies an underlined font if it is nonzero.

tmStruckOut

Specifies a strikeout font if it is nonzero.

tmPitchAndFamily

Specifies the pitch and family of the selected font. The low-order bit (bit 0) specifies the pitch of the font. If it is 1, the font is variable pitch. If it is 0, the font is fixed pitch. Bits 1 and 2 specify the font type. If both bits are 0, the font is a raster font; if bit 1 is 1 and bit 2 is 0, the font is a vector font; if bit 1 is 0 and bit 2 is set, or if both bits are 1, the font is some other type. Bit 3 is 1 if the font is a device font; otherwise, it is 0.

The four high-order bits designate the font family. The tmPitchAndFamily member can be combined with the hexadecimal value 0xF0 by using the bitwise AND operator and can then be compared with the font family names for an identical match. For more information about the font families, see the »LOGFONT« structure.

tmCharSet

Specifies the character set of the font.

ntmFlags

Specifies whether the font is italic, underscored, outlined, bold, and so forth. The following list shows the bits corresponding to each font type:

Bit	Meaning
0	Italic
1	Underscore
2	Negative
3	Outline
4	Strikeout
5	Bold
ntmSizeEM

Specifies the size of the em square for the font. This value is in "notional units" (that is, the units for which the font was designed).

ntmCellHeight

Specifies the height, in notional units, of the font. This value should be compared with the value of the ntmSizeEM member.

ntmAvgWidth

Specifies the average width of characters in the font, in notional units. This value should be compared with the value of the ntmSizeEM member.

Comments

The last four members of the NEWTEXTMETRIC structure are not included in the TEXTMETRIC structure; in all other respects, the structures are identical.

The sizes in the NEWTEXTMETRIC structure are typically given in logical units; that is, they depend on the current mapping mode of the display context.

See Also

»EnumFonts«, »GetTextMetrics«


  OFSTRUCT

typedef struct _OFSTRUCT { /* of */

    BYTE cBytes;

    BYTE fFixedDisk;

    WORD nErrCode;

    WORD Reserved1;

    WORD Reserved2;

    BYTE szPathName[OFS_MAXPATHNAME];

} OFSTRUCT;

The OFSTRUCT structure contains information about a file that the OpenFile function opened or attempted to open.

Members

cBytes

Specifies the length, in bytes, of the OFSTRUCT structure.

fFixedDisk

Specifies whether the file is on a fixed disk. This member is nonzero if the file is on a fixed disk.

nErrCode

Specifies the MS-DOS error code if the OpenFile function failed.

Reserved1

Reserved; do not use.

Reserved2

Reserved; do not use.

szPathName

Specifies the path and filename of the file. This string consists of characters from the Windows character set.

See Also

»OpenFile«


  OPENFILENAME

typedef struct tagOFN { /* ofn */

    DWORD     lStructSize;

    HWND      hwndOwner;

    HINSTANCE hInstance;

    LPCSTR    lpstrFilter;

    LPSTR     lpstrCustomFilter;

    DWORD     nMaxCustFilter;

    DWORD     nFilterIndex;

    LPSTR     lpstrFile;

    DWORD     nMaxFile;

    LPSTR     lpstrFileTitle;

    DWORD     nMaxFileTitle;

    LPSTR     lpstrInitialDir;

    LPCSTR    lpstrTitle;

    DWORD     Flags;

    WORD      nFileOffset;

    WORD      nFileExtension;

    LPCSTR    lpstrDefExt;

    DWORD     lCustData;

    LPOFNHOOKPROC lpfnHook;

    LPCSTR    lpTemplateName;

} OPENFILENAME;

The OPENFILENAME structure contains information the operating system uses to initialize the system-defined Open or Save As dialog box. After the user closes the dialog box, the system returns information about the user's selection in this structure.

Members

lStructSize

Specifies the length, in bytes, of the structure.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, or NULL if the dialog box has no owner.

hInstance

Identifies a data block that contains a dialog box template specified by the lpstrTemplateName member. This member is used only if the Flags member specifies the OFN_ENABLETEMPLATE flag; otherwise, this member is ignored.

lpstrFilter

Points to a buffer containing pairs of null-terminated filter strings. The first string in each pair describes a filter (for example, "Text Files"), the second specifies the filter pattern (for example, "*.TXT"). Multiple filters can be specified for a single item by separating the filter-pattern strings with a semicolon (for example, "*.TXT;*.DOC;*.BAK"). The last string in the buffer must be terminated by two NULL characters. If this parameter is NULL, the dialog box will not display any filters. The filter strings are assumed to be in the proper order — the operating system does not change the order.

lpstrCustomFilter

Points to a buffer containing a pair of user-defined filter strings. The first string describes the filter, and the second specifies the filter pattern (for example "WinWord, *.docnn"). The buffer is terminated by two NULL characters. The operating system copies the strings to the buffer when the user closes the dialog box. The system uses the strings to initialize the user-defined file filter the next time the dialog box is created. If this parameter is NULL, the dialog box lists but does not save user-defined filter strings.

nMaxCustFilter

Specifies the size, in characters, of the buffer identified by the lpstrCustomFilter member. This buffer should be at least 40 characters long. This parameter is ignored if the lpstrCustomFilter member is NULL or points to a NULL string.

nFilterIndex

Specifies an index into the buffer pointed to by the lpstrFilter member. The operating system uses the index value to obtain a pair of strings to use as the initial filter description and filter pattern for the dialog box. The first pair of strings has an index value of 1. When the user closes the dialog box, the system copies the index of the selected filter strings into this location. If the nFilterIndex member is 0, the custom filter is used. If the nFilterIndex member is 0 and the lpstrCustomFilter member is NULL, the system uses the first filter in the buffer identified by the lpstrFilter member. If all three members are 0 or NULL, the system does not use any filters and does not show any files in the file list control of the dialog box.

lpstrFile

Points to a buffer that contains a filename used to initialize the File Name edit control. The first character of this buffer must be NULL if initialization is not necessary. When the GetOpenFileName or GetSaveFileName function returns, this buffer contains the drive designator, path, filename, and extension of the selected file.

If the buffer is too small, the dialog box procedure copies the required size into this member.

nMaxFile

Specifies the size, in characters, of the buffer pointed to by the lpstrFile member. The GetOpenFileName and GetSaveFileName functions return FALSE if the buffer is too small to contain the file information. The buffer should be at least 256 characters long. This member is ignored if the lpstrFile member is NULL.

lpstrFileTitle

Points to a buffer that receives the title of the selected file. For Windows versions 3.0 and 3.1, this buffer receives the filename and extension without path information. This application should use this string to display the file title. If this member is NULL, the function does not copy the file title.

nMaxFileTitle

Specifies the maximum length of the string that can be copied into the lpstrFileTitle buffer. This member is ignored if lpstrFileTitle is NULL.

lpstrInitialDir

Points to a string that specifies the initial file directory. If this member is NULL, the system uses the current directory as the initial directory.

lpstrTitle

Points to a string to be placed in the title bar of the dialog box. If this member is NULL, the system uses the default title (that is, "Save As" or "Open").

Flags

Specifies the dialog box creation flags. This member may be a combination of the following values:

Value	Meaning
OFN_ALLOWMULTISELECT
	Specifies that the File Name list box allows multiple selections. (If the dialog box is created by using a private template, the LBS_EXTENDEDSEL constant must appear in the definition of the File Name list box.)
OFN_CREATEPROMPT
	Specifies that the dialog box function should ask whether the user wants to create a file that does not currently exist. (This flag automatically sets the OFN_PATHMUSTEXIST and OFN_FILEMUSTEXIST flags.)
OFN_ENABLEHOOK
	Enables the hook function specified in the lpfnHook member.
OFN_ENABLETEMPLATE
	Causes the operating system to create the dialog box by using the dialog box template identified by the hInstance and lpTemplateName members.
OFN_ENABLETEMPLATEHANDLE
	Indicates that the hInstance member identifies a data block that contains a preloaded dialog box template. The operating system ignores the lpTemplateName member if this flag is specified.
OFN_EXTENSIONDIFFERENT
	Specifies that the user typed a filename extension that differs from the extension specified by the lpstrDefExt member. The function does not set this flag if lpstrDefExt is NULL.
OFN_FILEMUSTEXIST
	Specifies that the user can type only names of existing files in the File Name entry field. If this flag is set and the user enters an invalid filename in the File Name entry field, the dialog box function displays a warning in a message box. The setting of this flag causes the OFN_PATHMUSTEXIST flag to be set.
OFN_HIDEREADONLY
	Hides the Read Only check box.
OFN_NOCHANGEDIR
	Causes the dialog box to set the current directory back to what it was when the dialog box was called.
OFN_NONETWORKBUTTON
	Hides and disables the Network button.
OFN_NOREADONLYRETURN
	Specifies that the returned file does not have the Read Only check box checked and is not in a write-protected directory.
OFN_NOTESTFILECREATE
	Specifies that the file is not created before the dialog box is closed. This flag should be set if the application saves the file on a create-nonmodify network share point. When an application sets this flag, the library does not check for write protection, a full disk, an open drive door, or network protection. Applications using this flag must perform file operations carefully, because a file cannot be reopened once it is closed.
OFN_NOVALIDATE
	Specifies that the common dialog boxes allow invalid characters in the returned filename. Typically, the calling application uses a hook function that checks the filename by using the FILEOKSTRING registered message. If the text box in the edit control is empty or contains nothing but spaces, the lists of files and directories are updated. If the text box in the edit control contains anything else, the nFileOffset and nFileExtension members are set to values generated by parsing the text. No default extension is added to the text, nor is text copied to the lpstrFileTitle buffer.
	If the value specified by the nFileOffset member is negative, the filename is invalid. If the value specified by nFileOffset is not negative, the filename is valid, and the nFileOffset and nFileExtension members can be used as if the OFN_NOVALIDATE flag had not been set.
OFN_OVERWRITEPROMPT
	Causes the Save As dialog box to generate a message box if the selected file already exists. The user must confirm whether to overwrite the file.
OFN_PATHMUSTEXIST
	Specifies that the user can type only valid path and filenames. If this flag is set and the user types an invalid path and filename in the File Name entry field, the dialog box function displays a warning in a message box.
OFN_READONLY
	Causes the Read Only check box to be checked initially when the dialog box is created. Indicates the state of the Read Only check box when the dialog box is closed.
OFN_SHAREAWARE
	Specifies that if a call to the OpenFile function fails because of a network sharing violation, the error is ignored and the dialog box returns the given filename. If this flag is not set, the registered message for SHAREVISTRING is sent to the hook function, with a pointer to a null-terminated string for the path and filename in the lParam parameter. The hook function responds with one of the following values:
Value	Meaning
OFN_SHAREFALLTHROUGH	Specifies that the filename is returned by the dialog box.
OFN_SHARENOWARN	Specifies no further action.
OFN_SHAREWARN	Specifies that the user receives the standard warning message for this error, the same result as if there were no hook function.
OFN_SHOWHELP	Causes the dialog box to show the Help button. The hwndOwner member must not be NULL if this option is specified.
nFileOffset

Specifies a zero-based offset from the beginning of the path to the filename in the string to which the lpstrFile member points. For example, if lpstrFile points to the following string, "c:\dir1\dir2\file.ext", this member contains the value 13.

nFileExtension

Specifies a zero-based offset from the beginning of the path to the filename extension in the string pointed to by the lpstrFile member. For example, if lpstrFile points to the following string, "c:\dir1\dir2\file.ext", this member contains the value 18. If the user did not type an extension and lpstrDefExt is NULL, this member specifies an offset to the terminating null character. If the user typed "." as the last character in the filename, this member specifies 0.

lpstrDefExt

Points to a buffer that contains the default extension. The GetOpenFileName and GetSaveFileName functions append this extension to the filename if the user fails to type an extension. This string can be any length, but only the first three characters are appended. The string should not contain a period (.). If this member is NULL and the user fails to type an extension, no extension is appended.

lCustData

Specifies application-defined data that the operating system passes to the hook function identified by the lpfnHook member. The system passes the data in the lParam parameter of the WM_INITDIALOG message.

lpfnHook

Points to a hook function that processes messages intended for the dialog box. An application must specify the OFN_ENABLEHOOK flag in the Flags member to enable the function; otherwise, the operating system ignores this structure member. The hook function should return FALSE to pass a message to the standard dialog box procedure, or TRUE to discard the message.

lpstrTemplateName

Points to a null-terminated string that names the dialog box template resource to be substituted for the standard dialog box template. An application can use the MAKEINTRESOURCE macro for numbered dialog box resources. This member is used only if the Flags member specifies the OFN_ENABLETEMPLATE flag; otherwise, this member is ignored.

See Also

»GetOpenFileName«, »GetSaveFileName«


  OUTLINETEXTMETRIC

typedef struct _OUTLINETEXTMETRIC { /* otm */

    UINT   otmSize;

    TEXTMETRIC otmTextMetrics;

    BYTE   otmFiller;

    PANOSE otmPanoseNumber;

    UINT   otmfsSelection;

    UINT   otmfsType;

    UINT   otmsCharSlopeRise;

    UINT   otmsCharSlopeRun;

    UINT   otmItalicAngle;

    UINT   otmEMSquare;

    UINT   otmAscent;

    int    otmDescent;

    int    otmLineGap;

    UINT   otmsCapEmHeight;

    UINT   otmsXHeight;

    RECT   otmrcFontBox;

    int    otmMacAscent;

    int    otmMacDescent;

    UINT   otmMacLineGap;

    UINT   otmusMinimumPPEM;

    POINT  otmptSubscriptSize;

    POINT  otmptSubscriptOffset;

    POINT  otmptSuperscriptSize;

    POINT  otmptSuperscriptOffset;

    UINT   otmsStrikeoutSize;

    int    otmsStrikeoutPosition;

    int    otmsUnderscoreSize;

    UINT   otmsUnderscorePosition;

    PSTR   otmpFamilyName;

    PSTR   otmpFaceName;

    PSTR   otmpStyleName;

    PSTR   otmpFullName;

} OUTLINETEXTMETRIC;

The OUTLINETEXTMETRIC structure contains metrics describing a TrueType® font.

Members

otmSize

Specifies the size, in bytes, of the OUTLINETEXTMETRIC structure.

otmTextMetrics

Specifies a TEXTMETRIC structure containing further information about the font.

otmFiller

Specifies a value that causes the structure to be byte aligned.

otmPanoseNumber

Specifies the PANOSE number for this font.

otmfsSelection

Specifies the nature of the font pattern. This member can be a combination of the following bits:

Bit	Meaning
0	Italic
1	Underscore
2	Negative
3	Outline
4	Strikeout
5	Bold
otmfsType

Specifies whether the font is licensed. Licensed fonts must not be modified or exchanged. If bit 1 is set, the font may not be embedded in a document. If bit 1 is clear, the font can be embedded. If bit 2 is set, the embedding is read-only.

otmsCharSlopeRise

Specifies the slope of the cursor. This value is 1 if the slope is vertical. Applications can use this value and the value of the otmsCharSlopeRun member to create an italic cursor that has the same slope as the main italic angle (specified by the otmItalicAngle member).

otmsCharSlopeRun

Specifies the slope of the cursor. This value is zero if the slope is vertical. Applications can use this value and the value of the otmsCharSlopeRise member to create an italic cursor that has the same slope as the main italic angle (specified by the otmItalicAngle member).

otmItalicAngle

Specifies the main italic angle of the font, in counterclockwise degrees from vertical. Regular (roman) fonts have a value of zero. Italic fonts typically have a negative italic angle (that is, they lean to the right).

otmEMSquare

Specifies the number of logical units defining the x- or y-dimension of the em square for this font. (The number of units in the x- and y-directions are always the same for an em square.)

otmAscent

Specifies the maximum distance characters in this font extend above the base line. This is the typographic ascent for the font.

otmDescent

Specifies the maximum distance characters in this font extend below the base line. This is the typographic descent for the font.

otmLineGap

Specifies typographic line spacing.

otmsCapEmHeight

Not supported.

otmsXHeight

Not supported.

otmrcFontBox

Specifies the bounding box for the font.

otmMacAscent

Specifies the maximum distance characters in this font extend above the base line for the Macintosh® computer.

otmMacDescent

Specifies the maximum distance characters in this font extend below the base line for the Macintosh® computer.

otmMacLineGap

Specifies line-spacing information for the Macintosh® computer.

otmusMinimumPPEM

Specifies the smallest recommended size for this font, in pixels per em-square.

otmptSubscriptSize

Specifies the recommended horizontal and vertical size for subscripts in this font.

otmptSubscriptOffset

Specifies the recommended horizontal and vertical offset for subscripts in this font. The subscript offset is measured from the character origin to the origin of the subscript character.

otmptSuperscriptSize

Specifies the recommended horizontal and vertical size for superscripts in this font.

otmptSuperscriptOffset

Specifies the recommended horizontal and vertical offset for superscripts in this font. The superscript offset is measured from the character base line to the base line of the superscript character.

otmsStrikeoutSize

Specifies the width of the strikeout stroke for this font. Typically, this is the width of the em dash for the font.

otmsStrikeoutPosition

Specifies the position of the strikeout stroke relative to the base line for this font. Positive values are above the base line and negative values are below.

otmsUnderscoreSize

Specifies the thickness of the underscore character for this font.

otmsUnderscorePosition

Specifies the position of the underscore character for this font.

otmpFamilyName

Specifies the offset from the beginning of the structure to a string specifying the family name for the font.

otmpFaceName

Specifies the offset from the beginning of the structure to a string specifying the typeface name for the font. (This typeface name corresponds to the name specified in the LOGFONT structure.)

otmpStyleName

Specifies the offset from the beginning of the structure to a string specifying the style name for the font.

otmpFullName

Specifies the offset from the beginning of the structure to a string specifying the full name for the font. This name is unique for the font and often contains a version number or other identifying information.

Comments

The sizes returned in OUTLINETEXTMETRIC are given in logical units; that is, they depend on the current mapping mode of the specified display context.

See Also

»GetOutlineTextMetrics«


  OUTPUT_DEBUG_STRING_INFO

typedef struct _OUTPUT_DEBUG_STRING_INFO { /* odsi */

    LPSTR lpDebugStringData;

    WORD  fUnicode;

    WORD  nDebugStringLength;

} OUTPUT_DEBUG_STRING_INFO;

The OUTPUT_DEBUG_STRING_INFO structure contains the address, format, and length, in bytes, of a debugging string.

Members

lpDebugStringData

Points to the address of the debugging string in the calling process's address space. The debugger can use the ReadProcessMemory function to retrieve the value of the string.

fUnicode

Specifies the format of the debugging string. If this value is zero, the debugging string is 8-bit ASCII; if it is nonzero, the string is 16-bit Unicode™.

nDebugStringLength

Specifies the length, in bytes, of the debugging string. The length includes the string's terminating null character.

See Also

»DEBUG_EVENT«


  OVERLAPPED

typedef struct _OVERLAPPED { /* o */

    DWORD  Internal;

    DWORD  InternalHigh;

    DWORD  Offset;

    DWORD  OffsetHigh;

    HANDLE hEvent;

} OVERLAPPED;

The OVERLAPPED structure contains information used in asynchronous input and output.

Members

Internal

Reserved for operating system use. This member specifies a system-dependent status. This member is valid when the GetOverlappedResult function returns without setting the extended error information to ERROR_IO_PENDING.

InternalHigh

Reserved for operating system use. This member specifies the length of the data transferred. This member is valid when the GetOverlappedResult function returns TRUE.

Offset

Specifies a file position to start the transfer. The file position is a byte offset from the start of the file. The calling process sets this member before calling the ReadFile or WriteFile function. This member is ignored when the functions read from and write to named pipes and communication devices.

OffsetHigh

Specifies the high word of the byte offset at which to start the transfer. This member is ignored when the functions read from and write to named pipes and communication devices.

hEvent

Identifies an event set to the signaled state when the transfer has been completed. The calling process sets this member before calling the ReadFile, WriteFile, ConnectNamedPipe or TransactNamedPipe function.

See Also

»ConnectNamedPipe«, »CreateFile«, »GetOverlappedResult«, »ReadFile«, »ReadFileEx«, »WriteFile«, »WriteFileEx«


  PAINTSTRUCT

typedef struct tagPAINTSTRUCT { /* ps */

    HDC  hdc;

    BOOL fErase;

    RECT rcPaint;

    BOOL fRestore;

    BOOL fIncUpdate;

    BYTE rgbReserved[32];

} PAINTSTRUCT;

The PAINTSTRUCT structure contains information for an application. This information can be used to paint the client area of a window owned by that application.

Members

hdc

Identifies the display DC to be used for painting.

fErase

Specifies whether the background must be erased. This value is nonzero if the application should erase the background. The application is responsible for erasing the background if a window class is created without a background brush. For more information, see the description of the hbrBackground member of the »WNDCLASS« structure.

rcPaint

Specifies a RECT structure that specifies the upper-left and lower-right corners of the rectangle in which the painting is requested.

fRestore

Reserved; used internally by Windows.

fIncUpdate

Reserved; used internally by Windows.

rgbReserved

Reserved; used internally by Windows.

See Also

»BeginPaint«, »RECT«, »WNDCLASS«


  PALETTEENTRY

typedef struct tagPALETTEENTRY { /* pe */

    BYTE peRed;

    BYTE peGreen;

    BYTE peBlue;

    BYTE peFlags;

} PALETTEENTRY;

The PALETTEENTRY structure specifies the color and usage of an entry in a logical color palette. A logical palette is defined by a LOGPALETTE structure.

Members

peRed

Specifies a red intensity value for the palette entry.

peGreen

Specifies a green intensity value for the palette entry.

peBlue

Specifies a blue intensity value for the palette entry.

peFlags

Specifies how the palette entry is to be used. The peFlags member may be set to NULL or one of these values:

Value	Meaning
PC_EXPLICIT	Specifies that the low-order word of the logical palette entry designates a hardware palette index. This flag allows the application to show the contents of the display device palette.
PC_NOCOLLAPSE	Specifies that the color be placed in an unused entry in the system palette instead of being matched to an existing color in the system palette. If there are no unused entries in the system palette, the color is matched normally. Once this color is in the system palette, colors in other logical palettes can be matched to this color.
PC_RESERVED	Specifies that the logical palette entry be used for palette animation; this prevents other windows from matching colors to the palette entry since the color frequently changes. If an unused system-palette entry is available, this color is placed in that entry. Otherwise, the color is available for animation.
See Also

»LOGPALETTE«


  PANOSE

typedef struct tagPANOSE { /* pnse */

    DWORD ulCulture;

    BYTE bFamilyType;

    BYTE bSerifStyle;

    BYTE bWeight;

    BYTE bProportion;

    BYTE bContrast;

    BYTE bStrokeVariation;

    BYTE bArmStyle;

    BYTE bLetterform;

    BYTE bMidline;

    BYTE bXHeight;

} PANOSE

The PANOSE structure describes the PANOSE font-classification values for a TrueType® font. These characteristics are then used to associate the font with other fonts of similar appearance but different names.

Members

ulCulture

Specifies the culture-specific classification scheme of the PANOSE number. The culture number specifies how to interpret the subsequent ten members for Latin fonts. The culture number can have the following values:

Value	Meaning
PAN_ANY	Any
PAN_CULTURE_LATIN	Latin
bFamilyType

For Latin fonts, bFamilyType can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_FAMILY_TEXT_DISPLAY	Text and display
PAN_FAMILY_SCRIPT	Script
PAN_FAMILY_DECORATIVE	Decorative
PAN_FAMILY_PICTORIAL	Pictorial
bSerifStyle

Specifies the serif style. For Latin fonts, bSerifStyle can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_SERIF_COVE	Cove
PAN_SERIF_OBTUSE_COVE	Obtuse cove
PAN_SERIF_SQUARE_COVE	Square cove
PAN_SERIF_OBTUSE_SQUARE_COVE	Obtuse square cove
PAN_SERIF_SQUARE	Square
PAN_SERIF_THIN	Thin
PAN_SERIF_BONE	Bone
PAN_SERIF_EXAGGERATED	Exaggerated
PAN_SERIF_TRIANGLE	Triangle
PAN_SERIF_NORMAL_SANS	Normal sans serif
PAN_SERIF_OBTUSE_SANS	Obtuse sans serif
PAN_SERIF_PERP_SANS	Perp sans serif
PAN_SERIF_FLARED	Flared
PAN_SERIF_ROUNDED	Rounded
bWeight

For Latin fonts, bWeight can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_WEIGHT_VERY_LIGHT	Very light
PAN_WEIGHT_LIGHT	Light
PAN_WEIGHT_THIN	Thin
PAN_WEIGHT_BOOK	Book
PAN_WEIGHT_MEDIUM	Medium
PAN_WEIGHT_DEMI	Demibold
PAN_WEIGHT_BOLD	Bold
PAN_WEIGHT_HEAVY	Heavy
PAN_WEIGHT_BLACK	Black
PAN_WEIGHT_NORD	Nord
bProportion

For Latin fonts, bProportion can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_PROP_OLD_STYLE	Old style
PAN_PROP_MODERN	Modern
PAN_PROP_EVEN_WIDTH	Even width
PAN_PROP_EXPANDED	Expanded
PAN_PROP_CONDENSED	Condensed
PAN_PROP_VERY_EXPANDED	Very expanded
PAN_PROP_VERY_CONDENSED	Very condensed
PAN_PROP_MONOSPACED	Monospaced
bContrast

For Latin fonts, bContrast can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_CONTRAST_NONE	None
PAN_CONTRAST_VERY_LOW	Very low
PAN_CONTRAST_LOW	Low
PAN_CONTRAST_MEDIUM_LOW	Medium low
PAN_CONTRAST_MEDIUM	Medium
PAN_CONTRAST_MEDIUM_HIGH	Medium high
PAN_CONTRAST_HIGH	High
PAN_CONTRAST_VERY_HIGH	Very high
bStrokeVariation

For Latin fonts, bStrokeVariation can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_STROKE_GRADUAL_DIAG	Gradual/diagonal
PAN_STROKE_GRADUAL_TRAN	Gradual/transitional
PAN_STROKE_GRADUAL_VERT	Gradual/vertical
PAN_STROKE_GRADUAL_HORZ	Gradual/horizontal
PAN_STROKE_RAPID_VERT	Rapid/vertical
PAN_STROKE_RAPID_HORZ	Rapid/horizontal
PAN_STROKE_INSTANT_VERT	Instant/vertical
bArmStyle

For Latin fonts, bArmStyle can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_STRAIGHT_ARMS_HORZ	Straight arms/horizontal
PAN_STRAIGHT_ARMS_WEDGE	Straight arms/wedge
PAN_STRAIGHT_ARMS_VERT	Straight arms/vertical
PAN_STRAIGHT_ARMS_SINGLE_SERIF	Straight arms/single-serif
PAN_STRAIGHT_ARMS_DOUBLE_SERIF	Straight arms/double-serif
PAN_BENT_ARMS_HORZ	Non-straight arms/horizontal
PAN_BENT_ARMS_WEDGE	Non-straight arms/wedge
PAN_BENT_ARMS_VERT	Non-straight arms/vertical
PAN_BENT_ARMS_SINGLE_SERIF	Non-straight arms/single-serif
PAN_BENT_ARMS_DOUBLE_SERIF	Non-straight arms/double-serif
bLetterform

For Latin fonts, bLetterform can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_LETT_NORMAL_CONTACT	Normal/contact
PAN_LETT_NORMAL_WEIGHTED	Normal/weighted
PAN_LETT_NORMAL_BOXED	Normal/boxed
PAN_LETT_NORMAL_FLATTENED	Normal/flattened
PAN_LETT_NORMAL_ROUNDED	Normal/rounded
PAN_LETT_NORMAL_OFF_CENTER	Normal/off center
PAN_LETT_NORMAL_SQUARE	Normal/square
PAN_LETT_OBLIQUE_CONTACT	Oblique/contact
PAN_LETT_OBLIQUE_WEIGHTED	Oblique/weighted
PAN_LETT_OBLIQUE_BOXED	Oblique/boxed
PAN_LETT_OBLIQUE_FLATTENED	Oblique/flattened
PAN_LETT_OBLIQUE_ROUNDED	Oblique/rounded
PAN_LETT_OBLIQUE_OFF_CENTER	Oblique/off center
PAN_LETT_OBLIQUE_SQUARE	Oblique/square
bMidline

For Latin fonts, bMidline can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_MIDLINE_STANDARD_TRIMMED	Standard/trimmed
PAN_MIDLINE_STANDARD_POINTED	Standard/pointed
PAN_MIDLINE_STANDARD_SERIFED	Standard/serifed
PAN_MIDLINE_HIGH_TRIMMED	High/trimmed
PAN_MIDLINE_HIGH_POINTED	High/pointed
PAN_MIDLINE_HIGH_SERIFED	High/serifed
PAN_MIDLINE_CONSTANT_TRIMMED	Constant/trimmed
PAN_MIDLINE_CONSTANT_POINTED	Constant/pointed
PAN_MIDLINE_CONSTANT_SERIFED	Constant/serifed
PAN_MIDLINE_LOW_TRIMMED	Low/trimmed
PAN_MIDLINE_LOW_POINTED	Low/pointed
PAN_MIDLINE_LOW_SERIFED	Low/serifed
bXHeight

For Latin fonts, bXHeight can have one of the following values:

Value	Meaning
PAN_ANY	Any
PAN_NO_FIT	No fit
PAN_XHEIGHT_CONSTANT_SMALL	Constant/small
PAN_XHEIGHT_CONSTANT_STD	Constant/standard
PAN_XHEIGHT_CONSTANT_LARGE	Constant/large
PAN_XHEIGHT_DUCKING_SMALL	Ducking/small
PAN_XHEIGHT_DUCKING_STD	Ducking/standard
PAN_XHEIGHT_DUCKING_LARGE	Ducking/large


  PARTITION_INFORMATION

typedef struct _PARTITION_INFORMATION {

    BYTE PartitionType;

    BOOLEAN BootIndicator;

    BOOLEAN RecognizedPartition;

    BOOLEAN RewritePartition;

    LARGE_INTEGER StartingOffset;

    LARGE_INTEGER PartitionLength;

    LARGE_INTEGER HiddenSectors;

} PARTITION_INFORMATION ;

The PARTITION_INFORMATION function provides information about a disk partition.

Members

PartitionType

Specifies the type of partition. This member can take on one of the following values:

Value	Meaning
PARTITION_ENTRY_UNUSED	Entry unused.
PARTITION_FAT_12	Specifies a partition with 12-bit FAT entries.
PARTITION_XENIX_1	Specifies a Xenix type 1 partition.
PARTITION_XENIX_2	Specifies a Xenix type 2 partition.
PARTITION_FAT_16	Specifies a partition with 16-bit FAT entries.
PARTITION_EXTENDED	Specifies an extended partition entry.
PARTITION_HUGE	Specifies an MS-DOS V4 huge partition.
PARTITION_IFS	Specifies an IFS partition.
PARTITION_UNIX	Specifies a Unix partition.
VALID_NTFT	Specifies an NTFT partition.
BootIndicator

The boot sector of the disk.

RecognizedPartition

The partition is recognized.

RewritePartition

The rewrite partition.

StartingOffset

The starting offset.

PartitionLength

The partition length.

HiddenSectors

The number of hidden sectors.

Comments

The DeviceIoControl function receives a PARTITION_INFORMATION structure in response to an IOCTL_DISK_GET_PARTITION_INFO or IOCTL_DISK_GET_DRIVE_LAYOUT device i/o operation. The DeviceIoControl function uses a PARTITION_INFORMATION structure as input to an IOCTL_DISK_SET_DRIVE_LAYOUT device i/o operation.

See Also

»IOCTL_DISK_GET_DRIVE_LAYOUT«, »IOCTL_DISK_GET_PARTITION_INFO«, »IOCTL_DISK_SET_DRIVE_LAYOUT«


  PCMWAVEFORMAT

typedef struct pcmwaveformat_tag {

    WAVEFORMAT  wf;

    WORD  wBitsPerSample;

} PCMWAVEFORMAT;

The PCMWAVEFORMAT structure describes the data format for pulse code modulated (PCM) waveform data.

Members

wf

Specifies a WAVEFORMAT structure containing general information about the format of the waveform data.

wBitsPerSample

Specifies the number of bits per sample.

See Also

»WAVEFORMAT«


  PERF_COUNTER_BLOCK

typedef struct _PERF_COUNTER_BLOCK { /* pcd */

    DWORD ByteLength;

} PERF_COUNTER_BLOCK;

The PERF_COUNTER_BLOCK structure contains the length, in bytes, of the performance-counter data. This structure is followed by data for the number of counters specified in the PERF_OBJECT_TYPE structure.

Members

ByteLength

Specifies the length, in bytes, of this structure, including the counters that follow.

Comments

This structure is part of the performance data provided by the RegQueryValueEx function when the HKEY_PERFORMANCE_DATA key is used.

See Also

»RegQueryValueEx«


  PERF_COUNTER_DEFINITION

typedef struct _PERF_COUNTER_DEFINITION { /* pcd */

    DWORD  ByteLength;

    DWORD  CounterNameTitleIndex;

    LPWSTR CounterNameTitle;

    DWORD  CounterHelpTitleIndex;

    LPWSTR CounterHelpTitle;

    DWORD  DefaultScale;

    DWORD  DetailLevel;

    DWORD  CounterType;

    DWORD  CounterSize;

    DWORD  CounterOffset;

} PERF_COUNTER_DEFINITION;

The PERF_COUNTER_DEFINITION structure describes a performance counter. The Unicode names in this structure must appear in a message file.

Members

ByteLength

Contains the length, in bytes, of this structure.

CounterNameTitleIndex

Contains the index of the counter name in the title database of the registry.

CounterNameTitle

Points to the name of the counter. This member contains NULL, initially, but can contain a pointer to the actual string once the string is located.

CounterHelpTitleIndex

Contains the index to the counter's Help title in the title database of the registry.

CounterHelpTitle

Points to the title of Help. This member contains NULL, initially, but can contain a pointer to the actual string once the string is located.

DefaultScale

Specifies the power of 10 by which to scale a chart line, assuming the vertical axis is 100. If this value is zero, the scale value is 1; if this value is 1, the scale value is 10; if this value is −1, the scale value is .10, and so on.

DetailLevel

Specifies the level of detail for the counter. Applications use this value to control display complexity. This member can be one of the following values:

Detail level	Meaning
PERF_DETAIL_NOVICE	Data can be understood by the uninformed user.
PERF_DETAIL_ADVANCED	Data designed for the advanced user.
PERF_DETAIL_EXPERT	Data designed for the expert user.
PERF_DETAIL_WIZARD	Data designed for the system designer.
CounterType

Specifies the type of counter. This member is some combination of the following values.

The following values indicate the counter's data size:

Value	Meaning
PERF_SIZE_DWORD	The counter data is a doubleword.
PERF_SIZE_LARGE	The counter data is a large integer.
PERF_SIZE_ZERO	The counter data is a zero-length field.
PERF_SIZE_VARIABLE_LEN	The size of the counter data is in the CounterSize member.
The following values indicate the additional contents of this member:

Value	Meaning
PERF_TYPE_NUMBER	The counter data is a number value but not a counter.
PERF_TYPE_COUNTER	The counter data is an increasing numeric value.
PERF_TYPE_TEXT	The counter data is a text field.
PERF_TYPE_ZERO	The counter data is always zero.
If PERF_TYPE_NUMBER is specified, one of the following values is also specified to indicate the format of the number:

Value	Meaning
PERF_NUMBER_HEX	The counter data should be displayed as a hexadecimal value.
PERF_NUMBER_DECIMAL	The counter data should be displayed as a decimal value.
PERF_NUMBER_DEC_1000	The counter data should be divided by 1000 and displayed as a decimal value.
If PERF_TYPE_COUNTER is specified, one of the following values is also specified to indicate the type of counter:

Value	Meaning
PERF_COUNTER_VALUE	The counter value is valid without additional calculation. That is, it should be displayed as is.
PERF_COUNTER_RATE	The counter value should be divided by the elapsed time.
PERF_COUNTER_FRACTION	The counter value should be divided by the base value indicated by the next counter if it is of type PERF_COUNTER_BASE or by the value of the counter subtype.
PERF_COUNTER_BASE	The counter value is the base value to use in fractions.
PERF_COUNTER_ELAPSED	The counter value is a start time to be subtracted from the current time.
PERF_COUNTER_QUEUELEN	The performance application should use the Queuelen counter; that is, the Queue Length Space-Time Product formula. The next counter is the number currently in the queue. Multiply by the current time (units specified by this counter's subtype). Add the product to this counter. To obtain the average queue length, divide the result by the delta time.
PERF_COUNTER_HISTOGRAM	The counter value begins or ends a histogram.
If PERF_TYPE_COUNTER is specified, one of the following values is also specified to indicate the subtype of counter:

Value	Meaning
PERF_TIMER_TICK	Use the frequency of the high-resolution performance counter as the base.
PERF_TIMER_100NS	Use the time base units of the 100-nanosecond timer as the base.
PERF_OBJECT_TIMER	Use the object-timer frequency as the base unit. This value is system defined in this counter's PERF_OBJECT_TYPE definition.
If PERF_TYPE_TEXT is specified, one of the following values is also specified to indicate the type of text:

Value	Meaning
PERF_TEXT_UNICODE	The counter data contains Unicode text.
PERF_TEXT_ASCII	The counter data contains ASCII text.
The following values indicate how to use the counter data in a calculation:

Value	Meaning
PERF_DELTA_COUNTER	Compute the difference between the previous counter value and the current counter value before proceeding.
PERF_DELTA_BASE	Compute the difference between the previous base value and the current base value before proceeding.
PERF_INVERSE_COUNTER	After other calculations, the counter should be inverted before displaying or converting to a percentage.
PERF_MULTI_COUNTER	This is a sum of counters from several sources, the number of which is indicated by the next counter.
The following values indicate the display suffix of the counter data:

Value	Meaning
PERF_DISPLAY_NO_SUFFIX	There is no display suffix.
PERF_DISPLAY_PER_SEC	The display suffix is '/sec'.
PERF_DISPLAY_PERCENT	The display suffix is '%'.
PERF_DISPLAY_SECONDS	The display suffix is 'secs'.
PERF_DISPLAY_NOSHOW	The counter value should not be displayed.
CounterSize

Specifies the counter size, in bytes.

CounterOffset

Specifies the offset from the start of the PERF_COUNTER_BLOCK structure to the first byte of this counter.

Comments

This structure is part of the performance data provided by the RegQueryValueEx function when the HKEY_PERFORMANCE_DATA key is used.


  PERF_DATA_BLOCK

typedef struct _PERF_DATA_BLOCK { /* pdb */

    WCHAR         Signature[4];

    DWORD         LittleEndian;

    DWORD         Version;

    DWORD         Revision;

    DWORD         TotalByteLength;

    DWORD         HeaderLength;

    DWORD         NumObjectTypes;

    DWORD         DefaultObject;

    SYSTEMTIME    SystemTime;

    LARGE_INTEGER PerfTime;

    LARGE_INTEGER PerfFreq;

    LARGE_INTEGER PerfTime100nSec;

    DWORD         SystemNameLength;

    DWORD         SystemNameOffset;

} PERF_DATA_BLOCK;

The PERF_DATA_BLOCK structure describes the performance data provided by RegQueryValueEx function. The data starts with a PERF_DATA_BLOCK structure and is followed by a PERF_OBJECT_TYPE structure and other object-specific data for each type of object monitored.

Members

Signature

Contains the Unicode string PERF.

LittleEndian

Contains zero if the processor is big endian, one if little endian.

Version

Contains the version of the PERF_ structures. This value is greater than or equal to one.

Revision

Contains the revision of the PERF_ structures. This value is greater than or equal to zero.

TotalByteLength

Contains the total length, in bytes, of performance data.

HeaderLength

Contains the length, in bytes, of this structure.

NumObjectTypes

Contains the number of object types being monitored.

DefaultObject

Contains the object title index of the default object whose performance data is to be displayed. This value can be −1 to indicate that no data is to be displayed.

SystemTime

Contains the time when the system is monitored. This value is in Universal Time Convention (UTC) format.

PerfTime

Contains the performance-counter value for the system being monitored. This value is in counts.

PerfFreq

Contains the performance-counter frequency for the system being monitored. This value is in counts per second.

PerfTime100nSec

Contains the performance-counter value for the system being monitored. This value is in 100 nanosecond units.

SystemNameLength

Contains the length, in bytes, of the system name.

SystemNameOffset

Contains the offset, from the beginning of this structure, to the name of the system being monitored.


  PERF_INSTANCE_DEFINITION

typedef struct _PERF_INSTANCE_DEFINITION { /* pid */

    DWORD ByteLength;

    DWORD ParentObjectTitleIndex;

    DWORD ParentObjectInstance;

    DWORD UniqueID;

    DWORD NameOffset;

    DWORD NameLength;

} PERF_INSTANCE_DEFINITION;

The PERF_INSTANCE_DEFINITION structure contains the instance-specific information for a block of performance data. There is one PERF_INSTANCE_DEFINITION structure for each instance specified in the PERF_DATA_BLOCK structure.

Members

ByteLength

Specifies the length, in bytes, of this structure, including the subsequent name.

ParentObjectTitleIndex

Specifies the index of the name of the "parent" object in the title database. For example, if the object is a thread, the parent object type is a process; if the object is a logical drive, the parent is a physical drive.

ParentObjectInstance

Specifies the index to an instance of the parent object type that is the parent of this instance. This member may be zero or greater.

UniqueID

Specifies the unique identifier used instead of the instance name. This value is PERF_NO_UNIQUE_ID if there is no such identifier.

NameOffset

Specifies the offset from the beginning of this structure to the Unicode name of this instance.

NameLength

Specifies the length, in bytes, of the instance name. This value is zero if the instance does not have a name.


  PERF_OBJECT_TYPE

typedef struct _PERF_OBJECT_TYPE {  /* pot */

    DWORD  TotalByteLength;

    DWORD  DefinitionLength;

    DWORD  HeaderLength;

    DWORD  ObjectNameTitleIndex;

    LPWSTR ObjectNameTitle;

    DWORD  ObjectHelpTitleIndex;

    LPWSTR ObjectHelpTitle;

    DWORD  DetailLevel;

    DWORD  NumCounters;

    DWORD  DefaultCounter;

    DWORD  NumInstances;

    DWORD  CodePage;

    LARGE_INTEGER PerfTime;

    LARGE_INTEGER PerfFreq;

} PERF_OBJECT_TYPE;

The PERF_OBJECT_TYPE structure describes the object-specific performance information. This structure is followed by a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the type of object.

Members

TotalByteLength

Contains the length, in bytes, of the object-specific data. This value includes this structure, the PERF_COUNTER_DEFINITION structures, and the PERF_INSTANCE_DEFINITION and PERF_COUNTER_BLOCK for each instance. This member specifies the offset from the beginning of this structure to the next PERF_OBJECT_TYPE structure, if one exists.

DefinitionLength

Contains the length, in bytes, of the object-specific data. This value includes this structure and the PERF_COUNTER_DEFINITION structures for this object. This is the offset from the beginning of the PERF_OBJECT_TYPE structure to the first PERF_INSTANCE_DEFINITION structure or to the PERF_COUNTER_DEFINITION structures, if there is no instance data.

HeaderLength

Contains the length, in bytes, of this structure. This value is the offset to the first PERF_COUNTER_DEFINITION structure for this object.

ObjectNameTitleIndex

Contains the index to the object name in the title database.

ObjectNameTitle

Points to the name of the object. This member initially contains NULL, but can contain a pointer to the actual string once the string is located.

ObjectHelpTitleIndex

Contains the index to the object's Help title in the title database.

ObjectHelpTitle

Points to the title of Help. This member initially contains NULL, but can contain a pointer to the actual string once the string is located.

DetailLevel

Specifies the level of detail. Applications use this value to control display complexity. This value is the minimum detail level of all the counters for a given object. This member can be one of the following values:

Detail level	Meaning
PERF_DETAIL_NOVICE	No technical ability is required to understand the counter data.
PERF_DETAIL_ADVANCED	The counter data is provided for advanced users.
PERF_DETAIL_EXPERT	The counter data is provided for expert users.
PERF_DETAIL_WIZARD	The counter data is provided for system designers.
NumCounters

Specifies the number of counters in each counter block. There is one counter block per instance.

DefaultCounter

Specifies the default counter whose information is to be displayed when this object is selected. This value is typically greater than or equal to zero. However, this value may be −1 to indicate that there is no default.

NumInstances

Specifies the number of object instances for which counters are being provided.

CodePage

Specifies the code page. This value is zero if the instance strings are in Unicode. Otherwise, this value is the code-page identifier of the instance names.

PerfTime

Specifies the current value, in counts, of the high-resolution performance counter.

PerfFreq

Specifies the current frequency, in counts per second, of the high-resolution performance counter.

Comments

If there is only one instance of the object type, the counter definitions are followed by a single PERF_COUNTER_BLOCK structure. This structure is followed by data for each counter. (The PERF_COUNTER_BLOCK structure contains the total length of the structure and the counter data that follows it.)

If there is more than one instance of the object type, the list of counter definitions is followed by a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance. The PERF_INSTANCE_DEFINITION structure includes the name, the identifier, and the name of the parent of the instance.

Following the counter data, there is a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance specified in the PERF_DATA_BLOCK structure that begins the performance-data area.


  POINT

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

The POINT structure defines the x- and y- coordinates of a point.

Members

x

Specifies the x-coordinate of the point.

y

Specifies the y-coordinate of the point.

See Also

»ChildWindowFromPoint«, »GetBrushOrgEx«, »PtInRect«, »SetBrushOrgEx«, »WindowFromPoint«


  POINTFX

typedef struct tagPOINTFX { /* ptfx */

    FIXED x;

    FIXED y;

} POINTFX;

The POINTFX structure contains the coordinates of points that describe the outline of a character in a TrueType® font.

Members

x

Specifies the x-component of a point on the outline of a TrueType character.

y

Specifies the y-component of a point on the outline of a TrueType character.

Comments

The POINTFX structure is a member of the TTPOLYCURVE and TTPOLYGONHEADER structures.

See Also

»FIXED«, »TTPOLYCURVE«, »TTPOLYGONHEADER«


  POINTL

typedef struct _POINTL { /* ptl */

    LONG x;

    LONG y;

} POINTL;

The POINTL structure contains the coordinates of a point.

Members

x

Specifies the horizontal (x) coordinate of the point.

y

Specifies the vertical (y) coordinate of the point.


  POINTS

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

The POINTS structure defines the coordinates of a point.

Members

x

Specifies the x-coordinate of the point.

y

Specifies the y-coordinate of the point.

See Also

»ChildWindowFromPoint«, »PtInRect«, »WindowFromPoint«, »POINT«


  POLYTEXT

typedef struct _POLYTEXT { /* ptxt */

    int   x;

    int   y;

    UINT  n;

    TCHAR *lpwstr;

    UINT  uiFlags;

    RECT  rcl;

    int   *pdx;

} POLYTEXT;

The POLYTEXT structure describes how the PolyTextOut function should draw a string of text.

Members

x

Specifies the horizontal reference point for the string. The string is aligned to this point using the current text-alignment mode.

y

Specifies the vertical reference point for the string. The string is aligned to this point using the current text-alignment mode.

n

Specifies the number of characters in the string.

uiFlags

Specifies whether the string is to be opaque or clipped and whether the string is accompanied by an array of character-width values. This member can be one or more of the following values:

Value	Meaning
ETO_OPAQUE	The rectangles given for each string is to be opaqued with the current background color.
ETO_CLIPPED	Each string is to be clipped to its given rectangle.
ETO_DELTAVECTOR	Each string is accompanied by an array of character widths, as in ExtTextOut.
lpwstr

Points to a string of text to be drawn by the PolyTextOut function.

rcl

Specifies a rectangle structure that contains the dimensions of the opaquing or clipping rectangle. This member is ignored if neither of the ETO_OPAQUE nor the ETO_CLIPPED value is specified for the uiFlags member.

pdx

Specifies in an array the width value for each character in the string. This member is ignored unless the ETO_DELTAVECTOR value is specified for the uiFlags member.

See Also

»PolyTextOut«


  PORT_INFO_1

typedef struct _PORT_INFO_1 { /* pi1 */

    LPSTR pName;

} PORT_INFO_1;

The PORT_INFO_1 structure identifies a supported printer port.

Members

pName

Points to a null-terminated string that identifies a supported printer port (for example, "LPT1:").

See Also

»EnumPorts«


  PREVENT_MEDIA_REMOVAL

typedef struct _PREVENT_MEDIA_REMOVAL{

   BOOLEAN PreventMediaRemoval;

} PREVENT_MEDIA_REMOVAL ;

The PREVENT_MEDIA_REMOVAL structure provides removeable media locking data.

Members

PreventMediaRemoval

Specifies whether the media is to be locked (if TRUE) or not (if FALSE).

Comments

The DeviceIoControl function uses a PREVENT_MEDIA_REMOVAL structure as input to an IOCTL_DISK_MEDIA_REMOVAL device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_MEDIA_REMOVAL«


  PRINTDLG

typedef struct tagPD {  /* pd */

    DWORD     lStructSize;

    HWND      hwndOwner;

    HANDLE    hDevMode;

    HANDLE    hDevNames;

    HDC       hDC;

    DWORD     Flags;

    WORD      nFromPage;

    WORD      nToPage;

    WORD      nMinPage;

    WORD      nMaxPage;

    WORD      nCopies;

    HINSTANCE hInstance;

    DWORD     lCustData;

    LPPRINTHOOKPROC lpfnPrintHook;

    LPSETUPHOOKPROC lpfnSetupHook;

    LPCSTR    lpPrintTemplateName;

    LPCSTR    lpSetupTemplateName;

    HANDLE    hPrintTemplate;

    HANDLE    hSetupTemplate;

} PRINTDLG;

The PRINTDLG structure contains information the operating system uses to initialize the system-defined Print dialog boxes. After the user closes the dialog box, the system returns information about the user-defined print parameters in this structure.

Members

lStructSize

Specifies the length, in bytes, of the structure.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, or NULL if the dialog box has no owner.

hDevMode

Identifies a movable global memory object that contains a DEVMODE structure. Before the call to the PrintDlg function, the structure members may contain data used to initialize the dialog controls. When PrintDlg returns, the structure members specify the state of the dialog box controls.

If the application uses the structure to initialize the dialog box controls, it must allocate space for and create the DEVMODE structure. (The application should allocate a movable block of memory.)

If the application does not use the structure to initialize the dialog box controls, the hDevMode member may be NULL. In this case, PrintDlg allocates memory for the structure, initializes its members, and returns a handle that identifies it.

If the device driver for the specified printer does not support extended device modes, the hDevMode member is NULL when PrintDlg returns.

If the device name (specified by the dmDeviceName member of the DEVMODE structure) does not appear in the [devices] section of WIN.INI, PrintDlg returns an error.

Because this structure is a movable global memory object, the value of hDevMode may change during the execution of PrintDlg.

For a discussion of how the system resolves a possible data collision between an hDevMode value and an hDevNames value, see the Comments section.

hDevNames

Identifies a movable global memory object that contains a DEVNAMES structure. This structure contains three strings that specify the driver name, the printer name, and the output-port name. Before the call to PrintDlg, the structure members contain strings used to initialize dialog box controls. When PrintDlg returns, the structure members contain the strings typed by the user. The calling application uses these strings to create a device context or an information context.

If the application uses the structure to initialize the dialog box controls, it must allocate space for and create the DEVMODE structure. (The application should allocate a movable block of global memory.)

If the application does not use the structure to initialize the dialog box controls, the hDevNames member may be NULL. In this case, PrintDlg allocates memory for the structure, initializes its members (by using the printer name specified in the DEVMODE structure), and returns a handle that identifies it. PrintDlg uses the first port name that appears in the [devices] section of WIN.INI when it initializes the members in the DEVNAMES structure. For example, if the following string appears in the [devices] section:

PCL / HP LaserJet=HPPCL,LPT1:,LPT2:

The function uses "LPT1:" as the port name.

If both the hDevMode and hDevNames members are NULL, PrintDlg initializes hDevNames using the current default printer.

Because this structure is a movable global memory object, the value of hDevNames may change during the execution of PrintDlg.

Please refer to the Comments section below for a discussion of how the system resolves a possible data collision between an hDevNames value and an hDevMode value.

hDC

Identifies a device context or an information context, depending on whether the Flags member specifies the PD_RETURNDC or the PC_RETURNIC flag. If neither flag is specified, the value of this member is undefined. If both flags are specified, PD_RETURNDC has priority.

Flags

Specifies the dialog box initialization flags. This member may be a combination of the following values:

Value	Meaning
PD_ALLPAGES
	Indicates that the All radio button was selected when the user closed the dialog box. (This value is used as a placeholder, to indicate that the PD_PAGENUMS and PD_SELECTION flags are not set. This value can be set on input and on output.)
PD_COLLATE
	Causes the Collate check box to be in the checked state when the dialog box is created. When the PrintDlg function returns, this flag indicates the state the Collate check box was left in by the user.
PD_DISABLEPRINTTOFILE
	Disables the Print to File check box.
PD_ENABLEPRINTHOOK
	Enables the hook function specified in the lpfnPrintHook member of this structure.
PD_ENABLEPRINTTEMPLATE
	Causes the operating system to create the dialog box by using the dialog box template identified by the hInstance and lpPrintTemplateName members.
PD_ENABLEPRINTTEMPLATEHANDLE
	Indicates that the hInstance member identifies a data block that contains a preloaded dialog box template. The system ignores the lpPrintTemplateName member if this flag is specified.
PD_ENABLESETUPHOOK
	Enables the hook function specified in the lpfnSetupHook member of this structure.
PD_ENABLESETUPTEMPLATE
	Causes the operating system to create the dialog box by using the dialog template box identified by the hInstance and lpSetupTemplateName members.
PD_ENABLESETUPTEMPLATEHANDLE
	Indicates that the hInstance member identifies a data block that contains a preloaded dialog box template. The operating system ignores the lpSetupTemplateName member if this flag is specified.
PD_HIDEPRINTTOFILE
	Hides and disables the Print to File check box.
PD_NOPAGENUMS
	Disables the Pages radio button and the associated edit control.
PD_NOSELECTION
	Disables the Selection radio button.
PD_NOWARNING
	Prevents the warning message from being displayed when there is no default printer.
PD_PAGENUMS
	Causes the Pages radio button to be in the selected state when the dialog box is created. When the PrintDlg function returns, this flag is set if the Pages radio button is in the selected state.
PD_PRINTSETUP
	Causes the system to display the Print Setup dialog box rather than the Print dialog box.
PD_PRINTTOFILE
	Causes the Print to File check box to be in the checked state when the dialog box is created. When the PrintDlg function returns, the pOutput member of the DEVNAMES structure points to the "FILE:" string.
PD_RETURNDC
	Causes the PrintDlg function to return a device context matching the selections the user made in the dialog box. The device context is returned in the hDC member.
PD_RETURNDEFAULT
	Without displaying a dialog box the PrintDlg function to return DEVMODE and DEVNAME structures that are initialized for the system default printer. It is assumed that both the hDevNames and hDevMode members are NULL; otherwise, the function returns an error. If the system default printer is supported by an old printer driver (earlier than Windows 3.0), only the hDevNames member is returned — the hDevMode member is NULL.
PD_RETURNIC
	Similar to the PD_RETURNDC flag except that this flag returns an information context rather than a device context. If neither PD_RETURNDC nor PD_RETURNIC is specified, the hDC parameter is undefined on output.
PD_SELECTION
	Causes the Selection radio button to be in the selected state when the dialog box is created. When the PrintDlg function returns, this flag is set if the Selection radio button is in the selected state. If neither PD_PAGENUMS nor PD_SELECTION is specified, the All radio button is in the selected state.
PD_SHOWHELP
	Causes the dialog box to show the Help button. The hwndOwner member must not be NULL if this option is specified.
PD_USEDEVMODECOPIES
	If a printer driver does not support multiple copies, setting this flag disables the Copies edit control; if a driver does support multiple copies, setting this flag indicates the the PrintDlg function should store the requested number of copies in the dmCopies member of the DEVMODE structure and store the value 1 in the nCopies member of the PRINTDLG structure.
	If this flag is not set, the PrintDlg structure stores the value 1 in the dmCopies member of the DEVMODE structure and stores the requested number of copies in the nCopies member of the PRINTDLG structure.
nFromPage

Specifies the initial value for the starting page edit control. When the PrintDlg function returns, this member specifies the page to begin printing. This value is valid only if the PD_PAGENUMS flag is specified.

nToPage

Specifies the initial value for the ending page edit control. When the PrintDlg function returns, this member specifies the last page to print. This value is valid only if the PD_PAGENUMS flag is specified.

nMinPage

Specifies the minimum value for the range of pages specified in the From and To page edit controls.

nMaxPage

Specifies the maximum value for the range of pages specified in the From and To page edit controls.

nCopies

Before the call to the PrintDlg function, this member contains a value used to initialize the Copies edit control if the hDevMode member is NULL; otherwise, the dmCopies member of the DEVMODE structure contains the value used to initialize this control.

When the PrintDlg function returns, the value specified by this member depends on the printer-driver version. For printer drivers earlier than Windows version 3.0, this member specifies the number of copies requested by the user in the dialog box's Copies edit control. For Windows version 3.0 and later printer drivers, this member specifies the number of copies requested by the user if the PD_USEDEVMODECOPIES flag was not set; otherwise, this member specifies the value 1, and the actual requested copy count appears in the DEVMODE structure.

hInstance

Identifies a data block that contains the preloaded dialog box template specified by the lpstrTemplateName member. This member is used only if the Flags member specifies the PD_ENABLEPRINTTEMPLATE or PD_ENABLESETUPTEMPLATE flag; otherwise, this member is ignored.

lCustData

Specifies application-defined data that the operating system passes to the hook function pointed to by the lpfnHook member. The system passes the data in the lParam parameter of the WM_INITDIALOG message.

lpfnPrintHook

Points to the exported function that hooks dialog messages if the application alters the Print dialog box. This member is ignored unless the PD_ENABLEPRINTHOOK flag is specified in the Flags member.

lpfnSetupHook

Points to the exported function that hooks dialog messages if the application alters the Print Setup dialog box. This member is ignored unless the PD_ENABLESETUPHOOK flag is specified in the Flags member.

lpPrintTemplateName

Points to a hook function that processes messages intended for the dialog box. An application must specify the PD_ENABLEPRINTTEMPLATE or PD_ENABLEPRINTERTEMPLATEHANDLE constant in the Flags member to enable the function; otherwise, the system ignores this structure member. The hook function should return FALSE to pass a message to the standard dialog box procedure, or TRUE to discard the message.

lpSetupTemplateName

Points to a hook function that processes messages intended for the dialog box. An application must specify the PD_ENABLESETUPTEMPLATE or PD_ENABLESETUPTEMPLATEHANDLE constant in the Flags member to enable the function; otherwise, the system ignores this structure member. The hook function should return FALSE to pass a message to the standard dialog box procedure, or TRUE to discard the message.

hPrintTemplate

Identifies the global memory object that contains the preloaded dialog box template to be used instead of the default Print Dialog box.

hSetupTemplate

Identifies the global memory object that contains the preloaded dialog box template to be used instead of the default Setup dialog box.

Comments

There is the possibility of a data collision between an hDevNames value and an hDevMode value. That is because the wDeviceOffset member of the DEVNAMES structure is supposed to be identical to thedmDeviceName of the DEVMODE structure. If it is not, the system resolves the data collision by using the wDeviceOffset value.

See Also

»CreateDC«, »CreateIC«, »PrintDlg«, »DEVMODE«, »DEVNAMES«


  PRINTER_DEFAULTS

typedef struct _PRINTER_DEFAULTS {  /* pd */

    LPTSTR      pDatatype;

    LPDEVMODE   pDevMode;

    ACCESS_MASK DesiredAccess;

} PRINTER_DEFAULTS;

The PRINTER_DEFAULTS structure specifies the default data type, environment, initialization data, and acces rights for a printer.

Members

pDatatype

Points to a null-terminated string that specifies the default data type for a printer.

pDevMode

Points to a DEVMODE structure that identifies the default environment and initialization data for a printer.

DesiredAccess

Specifies desired access rights for a printer. The OpenPrinter function uses this member to set access rights to the printer. These rights can affect the operation of the SetPrinter and DeletePrinter functions.

This member can be set to PRINTER_ADMINISTER, PRINTER_USE, or any generic security value (for example, WRITE_DACL). If an application wishes to open a printer to perform administrative tasks, such as the SetPrinter function, it must open the printer with PRINTER_ADMINISTER access.

See Also

»OpenPrinter«, »DEVMODE«


  PRINTER_INFO_1

typedef struct _PRINTER_INFO_1 { /* pri1 */

    DWORD  Flags;

    LPTSTR pDescription;

    LPTSTR pName;

    LPTSTR pComment;

} PRINTER_INFO_1;

The PRINTER_INFO_1 structure specifies general printer information.

Members

Flags

Specifies whether or not the structure contains valid data. This member can be either of the following values:

PRINTER_ENUM_CONTAINER
NULL

pDescription

Points to a null-terminated string that describes the contents of the structure.

pName

Points to a null-terminated string that names the contents of the structure.

pComment

Points to a null-terminated string that contains additional data describing the structure.

See Also

»EnumPrinters«, »PRINTER_INFO_2«


  PRINTER_INFO_2

typedef struct _PRINTER_INFO_2 { /* pri2 */

    LPTSTR    pServerName;

    LPTSTR    pPrinterName;

    LPTSTR    pShareName;

    LPTSTR    pPortName;

    LPTSTR    pDriverName;

    LPTSTR    pComment;

    LPTSTR    pLocation;

    LPDEVMODE pDevMode;

    LPTSTR    pSepFile;

    LPTSTR    pPrintProcessor;

    LPTSTR    pDatatype;

    LPTSTR    pParameters;

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

    DWORD     Attributes;

    DWORD     Priority;

    DWORD     DefaultPriority;

    DWORD     StartTime;

    DWORD     UntilTime;

    DWORD     Status;

    DWORD     cJobs;

    DWORD     AveragePPM;

} PRINTER_INFO_2;

The PRINTER_INFO_2 structure specifies detailed printer information.

Members

pServerName

Points to a null-terminated string identifying the server that controls the printer. If this string is NULL, the printer is controlled locally.

pPrinterName

Points to a null-terminated string that specifies the name of the printer.

pShareName

Points to a null-terminated string that identifies the sharepoint for the printer. (This string is used only if the PRINTER_ATTRIBUTE_SHARED constant was set for the Attributes member.)

pPortName

Points to a null-terminated string that identifies the port(s) used to transmit data to the printer. If a printer is connected to more than one port, the names of each port must be separated by commas (for example, "LPT1:,LPT2:,LPT3:").

pDriverName

Points to a null-terminated string that specifies the name of the printer driver.

pComment

Points to a null-terminated string that provides a brief description of the printer.

pLocation

Points to a null-terminated string that specifies the physical location of the printer (for example, "Bldg. 38, Room 1164").

pDevMode

Points to a DEVMODE structure that defines default printer data such as the paper orientation and the resolution.

pSepFile

Points to a null-terminated string that specifies the name of the file used to create the separator page. This page is used to separate print jobs sent to the printer.

pPrintProcessor

Points to a null-terminated string that specifies the name of the print processor used by the printer.

pDatatype

Points to a null-terminated string that specifies the data type used to record the print job.

pParameters

Points to a null-terminated string that specifies the default print-processor parameters.

pSecurityDescriptor

Points to a SECURITY_DESCRIPTOR structure that defines the print job's owner and group as well as other access-related data.

Attributes

Specifies the printer attributes. This member can be one of the following values:

PRINTER_ATTRIBUTE_QUEUED
PRINTER_ATTRIBUTE_DIRECT
PRINTER_ATTRIBUTE_DEFAULT
PRINTER_ATTRIBUTE_SHARED

Priority

Specifies a priority value that the spooler uses to route print jobs.

DefaultPriority

Specifies the default priority value assigned to each print job.

StartTime

Specifies the earliest time at which the printer will print a job. (This value is specified in minutes elapsed since 12:00 A.M.)

UntilTime

Specifies the latest time at which the printer will print a job. (This value is specified in minutes elapsed since 12:00 A.M.)

Status

Specifies the printer status. This member can be one of the following values:

PRINTER_STATUS_PAUSED
PRINTER_STATUS_PENDING_DELETION

cJobs

Specifies the number of print jobs that have been queued for the printer.

AveragePPM

Specifies the average number of pages-per-minute that have been printed on the printer.

See Also

»EnumPrinters«, »PRINTER_INFO_1«


  PRINTPROCESSOR_INFO_1

typedef struct _PRINTPROCESSOR_INFO_1 { /* ppi1 */

    LPSTR pName;

} PRINTPROCESSOR_INFO_1;

The PRINTPROCESSOR_INFO_1 structure specifies the name of an installed print processor.

Members

pName

Points to a null-terminated string that specifies the name of an installed print processor.

See Also

»EnumPrintProcessors«


  PRIVILEGE_SET

typedef struct _PRIVILEGE_SET { /* ps */

    DWORD PrivilegeCount;

    DWORD Control;

    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];

} PRIVILEGE_SET;

The PRIVILEGE_SET structure specifies a set of privileges. It is also used to indicate which, if any, privileges are held by a user or group requesting access to an object.

Members

PrivilegeCount

Specifies the number of privileges in the privilege set.

Control

Specifies a control flag related to the privileges. The PRIVILEGE_SET_ALL_NECESSARY control flag is currently defined. It indicates that all of the specified privileges must be held by the process requesting access. If this flag is not set, the presence of any privileges in the user's access token grants the access.

Privilege[]

Specifies an array of LUID_AND_ATTRIBUTES structures describing the set's privileges. The following attributes are defined for privileges:

Attribute	Description
SE_PRIVILEGE_ENABLED_BY_DEFAULT
	The privilege is enabled by default.
SE_PRIVILEGE_ENABLED
	The privilege is enabled.
SE_PRIVILEGE_USED_FOR_ACCESS
	The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.
Comments

A privilege is used to control access to an object or service more strictly than is typical with discretionary access control. A system manager uses privileges to control which users are able to manipulate system resources. An application uses privileges when it changes a system-wide resource, such as when it changes the system time or shuts down the system.

See Also

»PrivilegeCheck«, »LUID«, »LUID_AND_ATTRIBUTES«


  PROCESS_INFORMATION

typedef struct _PROCESS_INFORMATION { /* pi */

    HANDLE hProcess;

    HANDLE hThread;

    DWORD dwProcessId;

    DWORD dwThreadId;

} PROCESS_INFORMATION;

The PROCESS_INFORMATION structure is filled in by the CreateProcess function with information about a newly created process and its primary thread.

Members

hProcess

Returns a handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the process object.

hThread

Returns a handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that perform operations on the thread object.

dwProcessId

Returns a global process identifiers that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated.

dwThreadId

Returns a global thread identifiers that can be used to identify a thread. The value is valid from the time the thread is created until the time the thread is terminated.

See Also

»CreateProcess«


  PROVIDOR_INFO_1

typedef struct _PROVIDOR_INFO_1 { /* pi1 */

    LPTSTR pName;

    LPTSTR pEnvironment ;

    LPTSTR pDLLName ;

} PROVIDOR_INFO_1;

The PROVIDOR_INFO_1 structure identifies a print provider.

Members

pName

Points to a null-terminated string that is the name of the print provider.

pEnvironment

Points to a null-terminated environment string specifying the environment this DLL is designed to run in.

pDLLName

Points to a null-terminated string that is the name of the provider DLL.

See Also

»MONITOR_INFO_2«


  QUERY_SERVICE_CONFIG

typedef struct _QUERY_SERVICE_CONFIG { /* qsc */

    DWORD dwServiceType;

    DWORD dwStartType;

    DWORD dwErrorControl;

    LPTSTR lpBinaryPathName;

    LPTSTR lpLoadOrderGroup;

    DWORD dwTagId;

    LPTSTR lpDependencies;

    LPTSTR lpServiceStartName;

    LPTSTR lpDisplayName;

} QUERY_SERVICE_CONFIG, LPQUERY_SERVICE_CONFIG;

The QUERY_SERVICE_CONFIG structure is used by the QueryServiceConfig function to return configuration information about an installed service.

Members

dwServiceType

Indicates the type of service. One of the following values is specified.

Type	Meaning
SERVICE_WIN32_OWN_PROCESS	Specifies a service that runs in its own Win32 process.
SERVICE_WIN32_SHARE_PROCESS	Specifies a service that shares a Win32 process with other services.
SERVICE_KERNEL_DRIVER	Specifies a Windows NT device driver.
SERVICE_FILE_SYSTEM_DRIVER	Specifies a Windows NT file system driver.
dwStartType

Specifies when to start the service. One of the following values is specified.

Value	Meaning
SERVICE_BOOT_START	Specifies a device driver started by the operating system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_SYSTEM_START	Specifies a device driver started by the IoInitSystem function. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_AUTO_START	Specifies a device driver or Win32 service started by the service control manager automatically during system startup.
SERVICE_DEMAND_START	Specifies a device driver or Win32 service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED	Specifies a device driver or Win32 service that can no longer be started.
dwErrorControl

Specifies the severity of the error if this service fails to start during system startup and determines the action taken by the startup program if failure occurs. This value should be the SERVICE_ERROR_NORMAL flag, which causes the startup program to log the error but continue the startup process. The SERVICE_ERROR_SEVERE and SERVICE_ERROR_CRITICAL flags are not currently supported.

lpBinaryPathName

Points to a null-terminated string that contains the fully qualified path to the service binary file.

lpLoadOrderGroup

Points to a null-terminated string that names the load ordering group of which this service is a member. If the pointer is NULL or if it points to an empty string, the service does not belong to a group. The registry has a list of load ordering groups at HKEY_LOCAL_MACHINE\System\ CurrentControlSet\Control\ServiceGroupOrder. The startup program uses this list to load groups of services in a specified order with respect to the other groups in the list. You can place a service in a group so that another service can depend on the group.

The order in which a service starts is determined by these criteria:

1.	The order of groups in the registry's load-ordering group list. Services in groups in the load-ordering group list are started first, followed by services in groups not in the load-ordering group list and then services that do not belong to a group.

2.	The service's dependencies listed in the lpszDependencies parameter and the dependencies of other services dependent on the service.

dwTagId

Specifies a unique tag value for this service in the group specified by the lpLoadOrderGroup parameter. A value of zero indicates that the service has not been assigned a tag. You can use a tag for ordering service startup within a load order group by specifying a tag order vector in the registry at HKEY_LOCAL_MACHINE\System\ CurrentControlSet\Control\GroupOrderList. Tags are only evaluated for SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER type services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.

lpDependencies

Points to an array of null-separated names of services or load ordering groups that must start before this service. The array is doubly null-terminated. If the pointer is NULL or if it points to an empty string, the service has no dependencies. If a group name is specified, it must be prefixed by the SC_GROUP_IDENTIFIER (defined in the WINSVC.H file) character to differentiate it from a service name, because services and service groups share the same name space. Dependency on a service means that this service can only run if the service it depends on is running. Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.

lpServiceStartName

Points to a null-terminated string. If the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, this name is the account name in the form of "DomainName\Username", which the service process will be logged on as when it runs. If the account belongs to the built-in domain, ".\Username" can be specified. If NULL is specified, the service will be logged on as the LocalSystem account.

If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this name is the Windows NT driver object name (that is, \FileSystem\Rdr or \Driver\Xns) which the input and output (I/O) system uses to load the device driver. If NULL is specified, the driver is run with a default object name created by the I/O system based on the service name.

lpDisplayName

Points to a NULL-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the Service Control Manager. Display name comparisons are always case-insensitive.

Comments

The configuration information for a service is initially specified when the service is created by a call to the CreateService function. The information can be modified by calling the ChangeServiceConfig function.

See Also

»ChangeServiceConfig«, »CreateService«, »QueryServiceConfig«


  QUERY_SERVICE_LOCK_STATUS

typedef struct _QUERY_SERVICE_LOCK_STATUS { /* qsls */

    DWORD fIsLocked;

    LPTSTR lpLockOwner;

    DWORD dwLockDuration;

} QUERY_SERVICE_LOCK_STATUS, * LPQUERY_SERVICE_LOCK_STATUS ;

The QUERY_SERVICE_LOCK_STATUS structure is used by the QueryServiceLockStatus function to return information about the lock status of a Service Control Manager database.

Members

fIsLocked

Specifies whether the database is locked. If this member is nonzero, the database is locked. If it is zero, the database is unlocked.

lpLockOwner

Points to a null-terminated string containing the name of the user who acquired the lock.

dwLockDuration

Specifies the time, in seconds, since the lock was first acquired.

See Also

»QueryServiceLockStatus«


  RASTERIZER_STATUS

typedef struct _RASTERIZER_STATUS {    /* rs */

    short nSize;

    short wFlags;

    short nLanguageID;

} RASTERIZER_STATUS;

The RASTERIZER_STATUS structure contains information about whether TrueType® is installed. This structure is filled when an application calls the GetRasterizerCaps function.

Members

nSize

Specifies the size, in bytes, of the RASTERIZER_STATUS structure.

wFlags

Specifies whether at least one TrueType font is installed and whether TrueType is enabled. This value is TT_AVAILABLE and/or TT_ENABLED if TrueType is on the system.

nLanguageID

Specifies the language in the system's SETUP.INF file.

See Also

»GetRasterizerCaps«


  REASSIGN_BLOCKS

typedef struct _REASSIGN_BLOCKS {

    WORD   Reserved;

    WORD   Count;

    DWORD BlockNumber[1];

} REASSIGN_BLOCKS ;

The REASSIGN_BLOCKS structure provides disk block reassignment data. It is a variable-length structure whose last member is an array of block numbers to be reassigned.

Members

Reserved

This member is reserved. Do not use it. Set it to zero.

Count

Specifies the number of blocks to be reassigned. This is the number of elements that are in the BlockNumber member array.

BlockNumber[1]

An array of Count block numbers, one for each block to be reassigned.

Comments

The DeviceIoControl function uses a REASSIGN_BLOCKS structure as input to an IOCTL_DISK_REASSIGN_BLOCKS device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_REASSIGN_BLOCKS«


  RECT

typedef struct tagRECT {    /* rc */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECT;

The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle.

Members

left

Specifies the x-coordinate of the upper-left corner of the rectangle.

top

Specifies the y-coordinate of the upper-left corner of the rectangle.

right

Specifies the x-coordinate of the lower-right corner of the rectangle.

bottom

Specifies the y-coordinate of the lower-right corner of the rectangle.

Comments

When the RECT structure is passed to the FillRect function, the rectangle is filled up to, but not including, the right column and bottom row of pixels.

See Also

»RECTL«, »SMALL_RECT«


  RECTL

typedef struct _RECTL { /* rcl */

    LONG left;

    LONG top;

    LONG right;

    LONG bottom;

} RECTL;

The RECTL structure defines the coordinates of the upper-left and lower-right corners of a rectangle.

Members

left

Specifies the x-coordinate of the upper-left corner of the rectangle.

top

Specifies the y-coordinate of the upper-left corner of the rectangle.

right

Specifies the x-coordinate of the lower-right corner of the rectangle.

bottom

Specifies the y-coordinate of the lower-right corner of the rectangle.

Comments

When the RECTL structure is passed to the FillRect function, the rectangle is filled up to, but not including, the right column and bottom row of pixels.

See Also

»RECT«, »SMALL_RECT«


  RGBQUAD

typedef struct tagRGBQUAD { /* rgbq */

    BYTE    rgbBlue;

    BYTE    rgbGreen;

    BYTE    rgbRed;

    BYTE    rgbReserved;

} RGBQUAD;

The RGBQUAD structure describes a color consisting of relative intensities of red, green, and blue.

Members

rgbBlue

Specifies the intensity of blue in the color.

rgbGreen

Specifies the intensity of green in the color.

rgbRed

Specifies the intensity of red in the color.

rgbReserved

Reserved; must be zero.

Comments

The bmiColors member of the BITMAPINFO structure consists of an array of RGBQUAD structures.

See Also

»CreateDIBitmap«, »CreateDIBSection«, »GetDIBits«, »SetDIBits«, »SetDIBitsToDevice«, »StretchDIBits«


  RGBTRIPLE

typedef struct tagRGBTRIPLE { /* rgbt */

    BYTE rgbtBlue;

    BYTE rgbtGreen;

    BYTE rgbtRed;

} RGBTRIPLE;

The RGBTRIPLE structure describes a color consisting of relative intensities of red, green, and blue. The bmciColors member of the BITMAPCOREINFO structure consists of an array of RGBTRIPLE structures.

Members

rgbtBlue

Specifies the intensity of blue in the color.

rgbtGreen

Specifies the intensity of green in the color.

rgbtRed

Specifies the intensity of red in the color.


  RGNDATA

typedef struct _RGNDATA { /* rgnd */

    RGNDATAHEADER rdh;

    char          Buffer[1];

} RGNDATA;

The RGNDATA structure contains a header and an array of rectangles that compose a region. These rectangles, sorted top to bottom left to right, do not overlap.

Members

rdh

Specifies a RGNDATAHEADER structure. The members of this structure specify the type of region (whether it is rectangular or trapezoidal), the number of rectangles that make up the region, the size of the buffer that contains the rectangle structures, and so on.

Buffer

Specifies an arbitrary-size buffer that contains the RECT structures that make up the region.

See Also

»RECT«, »RGNDATAHEADER«


  RGNDATAHEADER

typedef struct _RGNDATAHEADER { /* rgndh */

    DWORD dwSize;

    DWORD iType;

    DWORD nCount;

    DWORD nRgnSize;

    RECT  rcBound;

} RGNDATAHEADER;

The RGNDATAHEADER structure describes the data returned by the GetRegionData function.

Members

dwSize

Specifies the size, in bytes, of the header.

iType

Specifies the type of region. This value must be RDH_RECTANGLES.

nCount

Specifies the number of rectangles that make up the region.

nRgnSize

Specifies the size of the buffer required to receive the RECT structure that specifies the coordinates of the rectangles that make up the region. If the size is not known, this member can be zero.

rcBound

Specifies a bounding rectangle for the region.

See Also

»RECT«, »RGNDATA«


  RIP_INFO

typedef struct _RIP_INFO { /* ri */

    DWORD  dwError;

    DWORD  dwType;

} RIP_INFO;

The RIP_INFO structure contains the error and address, format, and length, in bytes, of a debugging string.

Members

dwError

Specifies the error that caused the RIP debug event. For more information about exception handling, see Chapter 63, "Errors."

dwType

Specifies additional information about the type of error that caused the RIP debug event. This may be one of the following values:

Value	Meaning
SLE_ERROR	Indicates that invalid data was passed to the function that failed. This caused the application to fail.
SLE_MINORERROR	Indicates that invalid data was passed to the function, but the error probably will not cause the application to fail.
SLE_WARNING	Indicates that potentially invalid data was passed to the function, but the function completed processing.
0	Indicates that only dwError was set.
See Also

»DEBUG_EVENT«


  SECURITY_ATTRIBUTES

typedef struct _SECURITY_ATTRIBUTES { /* sa */

    DWORD  nLength;

    LPVOID lpSecurityDescriptor;

    BOOL   bInheritHandle;

} SECURITY_ATTRIBUTES;

The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable.

Members

nLength

Specifies the length, in bytes, of this structure. This value is to be set to the size of the SECURITY_ATTRIBUTES structure.

lpSecurityDescriptor

Points to a security descriptor for the object that controls the sharing of it. If NULL is specified for this member, the object may be assigned the default security descriptor of the calling process.

bInheritHandle

Specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.

Comments

A pointer to a SECURITY_ATTRIBUTES structure is used as a parameter in most kernel and window-management functions in the Win32 API that return a handle of an object.

See Also

»SECURITY_DESCRIPTOR«


  SECURITY_DESCRIPTOR

typedef PVOID PSECURITY_DESCRIPTOR;

The SECURITY_DESCRIPTOR structure contains the security information associated with an object. Applications use this structure to set and query an object's security status.

Applications are not to modify the SECURITY_DESCRIPTOR structure directly. For creating and manipulating a security descriptor, use the functions listed in the See Also section.

Comments

A security descriptor includes information that specifies the following components of an object's security:

•	An owner (SID)

•	A primary group (SID)

•	A discretionary ACL

•	A system ACL

•	Qualifiers for the preceding items

Security descriptors use access-control lists (ACLs) and security identifiers (SIDs) to specify the information in this list.

A security descriptor can be in absolute or self-relative form. In self-relative form, all members of the structure are located contiguously in memory. In absolute form, the structure only contains pointers to the members.

See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorLength«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »InitializeSecurityDescriptor«, »IsValidSecurityDescriptor«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorOwner«, »SetSecurityDescriptorSacl«


  SECURITY_DESCRIPTOR_CONTROL

typedef WORD SECURITY_DESCRIPTOR_CONTROL;

The SECURITY_DESCRIPTOR_CONTROL structure contains a set of bit flags that qualify the meaning of a security descriptor or its individual members.

Each security descriptor has an associated SECURITY_DESCRIPTOR_CONTROL structure. Applications can use the Win32 API functions to set and retrieve a security descriptor's SECURITY_DESCRIPTOR_CONTROL values. These functions are listed in the See Also section.

The following constants are defined for setting and retrieving SECURITY_DESCRIPTOR_CONTROL bit flags:

Value	Meaning
SE_OWNER_DEFAULTED	Instead of the original provider of the security descriptor, a default mechanism provided the security descriptor's owner security identifier (SID). This can affect the treatment of the SID with respect to inheritance of an owner. This flag is ignored if the owner member is NULL. The SetSecurityDescriptorOwner function sets this flag.
SE_GROUP_DEFAULTED	Instead of the the original provider of the security descriptor, a default mechanism provided the security descriptor's group SID. This can affect the treatment of the SID with respect to inheritance of a primary group. This flag is ignored if the group member is NULL. The SetSecurityDescriptorGroup function sets this flag.
SE_DACL_PRESENT	The security descriptor contains a discretionary access-control list (ACL). If this flag is set and the discretionary ACL is NULL, an empty ACL is being explicitly specified. An empty ACL has a size but no access-control entries (ACEs). A NULL ACL has no pointer to an ACL. This flag allows functions to determine whether a security descriptor points to a NULL ACL or no ACL at all. The SetSecurityDescriptorDacl function sets this flag.
SE_DACL_DEFAULTED	Instead of the the original provider of the security descriptor, a default mechanism provided the discretionary ACL. This can affect the treatment of the ACL with respect to inheritance of an ACL. If the SE_DACL_PRESENT flag is not set, this flag is ignored. The SetSecurityDescriptorDacl function sets this flag.
SE_SACL_PRESENT	The security descriptor contains a system ACL. If this flag is set and the Sacl member is NULL, an empty ACL is being explicitly specified. This flag allows functions to determine whether a security descriptor points to a NULL ACL or no ACL at all. The SetSecurityDescriptorSacl function sets this flag.
SE_SACL_DEFAULTED	Instead of the the original provider of the security descriptor, a default mechanism provided the ACL. This can affect the treatment of the ACL with respect to inheritance of an ACL. If the SE_SACL_PRESENT flag is not set, this flag is ignored. The SetSecurityDescriptorSacl function sets this flag.
SE_SELF_RELATIVE	The security descriptor is in self-relative form and all members of the security descriptor are contiguous in memory. All pointer members are expressed as offsets from the beginning of the security descriptor. This form is useful for treating security descriptors as opaque structures for transmission in a communications protocol or for storage on secondary media.
See Also

»GetSecurityDescriptorControl«, »GetSecurityDescriptorDacl«, »GetSecurityDescriptorGroup«, »GetSecurityDescriptorOwner«, »GetSecurityDescriptorSacl«, »SetSecurityDescriptorDacl«, »SetSecurityDescriptorGroup«, »SetSecurityDescriptorOwner«, »SetSecurityDescriptorSacl«


  SECURITY_IMPERSONATION_LEVEL

typedef enum tagSECURITY_IMPERSONATION_LEVEL { /* sil */

    SecurityAnonymous,

    SecurityIdentification,

    SecurityImpersonation,

    SecurityDelegation

} SECURITY_IMPERSONATION_LEVEL;

The SECURITY_IMPERSONATION_LEVEL enumerated type specifies impersonation levels. Security impersonation levels govern the degree to which a server process can act on behalf of a client process.

Value	Meaning
SecurityAnonymous	The server process cannot obtain identification information about the client and it cannot impersonate the client. It is defined with no value given, and thus, by ANSI C rules, defaults to a value of 0.
SecurityIdentification	The server process can obtain information about the client, such as security identifiers and privileges, but it cannot use kernel functions. This is useful for servers that export their own objects — for example, tables and views exported by a database product. Using the retrieved client-security information, the server can make access-validation decisions without being able to utilize other services using the client's security context.
SecurityImpersonation	The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.
SecurityDelegation	This impersonation level is not supported in the current version of Windows NT.
Comments

Impersonation is the ability of a process to take on the security attributes of another process.

See Also

»CreatePrivateObjectSecurity«, »DuplicateToken«, »GetTokenInformation«, »ImpersonateSelf«, »OpenThreadToken«


  SECURITY_INFORMATION

typedef DWORD SECURITY_INFORMATION;

The SECURITY_INFORMATION structure identifies the object-related security information being set or queried. This security information includes:

•	The owner of an object

•	The primary group of an object

•	The discretionary access-control list (ACL) of an object

•	The system ACL of an object

Each item of security information is designated by a bit flag. The following values specify the bits:

Value	Meaning
OWNER_SECURITY_INFORMATION	Indicates the owner identifier of the object is being referenced.
GROUP_SECURITY_INFORMATION	Indicates the primary group identifier of the object is being referenced.
DACL_SECURITY_INFORMATION	Indicates the discretionary ACL of the object is being referenced.
SACL_SECURITY_INFORMATION	Indicates the system ACL of the object is being referenced.
See Also

»GetFileSecurity«, »GetKernelObjectSecurity«, »GetPrivateObjectSecurity«, »GetUserObjectSecurity«, »SetFileSecurity«, »SetKernelObjectSecurity«, »SetPrivateObjectSecurity«, »SetUserObjectSecurity«


  SECURITY_QUALITY_OF_SERVICE

typedef struct _SECURITY_QUALITY_OF_SERVICE { /* sqos */

    DWORD Length;

    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;

    SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;

    BOOLEAN EffectiveOnly;

} SECURITY_QUALITY_OF_SERVICE;

The SECURITY_QUALITY_OF_SERVICE data structure contains information used to support client impersonation. A client can specify this information when it connects to a server; the information determines whether or not the server may impersonate the client, and if so, to what extent.

Members

Length

Specifies the size, in bytes, of this structure.

ImpersonationLevel

Specifies what the server may be told about the client, and how the server may represent, or impersonate, the client. Security impersonation levels govern the degree to which a server process can act on behalf of a client process. This member is a SECURITY_IMPERSONATION_LEVEL enumerated type value. The SECURITY_IMPERSONATION_LEVEL enumerated type is defined as follows :

typedef enum tagSECURITY_IMPERSONATION_LEVEL { /* sil */

    SecurityAnonymous,

    SecurityIdentification,

    SecurityImpersonation,

    SecurityDelegation

} SECURITY_IMPERSONATION_LEVEL;

ContextTracking Mode

Specifies whether the server is to be given a snapshot of the client's security context (called static tracking), or is to be continually updated to track changes to the client's security context (called dynamic tracking). The value SECURITY_STATIC_TRACKING specifies static tracking, and the value SECURITY_DYNAMIC_TRACKING specifies dynamic tracking. Not all communications mechanisms support dynamic tracking; those that do not will default to static tracking.

Effective Only

Specifies whether or not the server may enable or disable privileges and groups that the client's security context may include.

See Also

»SECURITY_IMPERSONATION_LEVEL«


  SERVICE_STATUS

typedef struct _SERVICE_STATUS { /* ss */

    DWORD dwServiceType;

    DWORD dwCurrentState;

    DWORD dwControlsAccepted;

    DWORD dwWin32ExitCode;

    DWORD dwServiceSpecificExitCode;

    DWORD dwCheckPoint;

    DWORD dwWaitHint;

} SERVICE_STATUS, *LPSERVICE_STATUS;

The SERVICE_STATUS structure contains information about a service. The ControlService, EnumDependentServices, EnumServicesStatus, and QueryServiceStatus functions use this structure to return information about a service. A service uses this structure in the SetServiceStatus function to report its current status to the service control manager.

Members

dwServiceType

Indicates the type of service. One of the following values is specified.

Type	Meaning
SERVICE_WIN32_OWN_PROCESS	Specifies a service that runs in its own Win32 process.
SERVICE_WIN32_SHARE_PROCESS	Specifies a service that shares a Win32 process with other services.
SERVICE_KERNEL_DRIVER	Specifies a Windows NT device driver.
SERVICE_FILE_SYSTEM_DRIVER	Specifies a Windows NT file system driver.
dwCurrentState

Indicates the current state of the service. One of the following values is specified.

Value	Meaning
SERVICE_STOPPED	The service is not running.
SERVICE_START_PENDING	The service is starting.
SERVICE_STOP_PENDING	The service is stopping.
SERVICE_RUNNING	The service is running.
SERVICE_CONTINUE_PENDING	The service continue is pending.
SERVICE_PAUSE_PENDING	The service pause is pending.
SERVICE_PAUSED	The service is paused.
dwControlsAccepted

Specifies the control codes that the service will accept and process. A user interface process can control a service by specifying a control command in the ControlService function. By default, all services accept the SERVICE_CONTROL_INTERROGATE command. Any or all of the following flags can be specified to enable the other control codes.

Value	Meaning
SERVICE_ACCEPT_STOP
	The service can be stopped. This enables the SERVICE_CONTROL_STOP command.
SERVICE_ACCEPT_PAUSE_CONTINUE
	The service can be paused and continued. This enables the SERVICE_CONTROL_PAUSE and SERVICE_CONTROL_CONTINUE commands.
SERVICE_ACCEPT_SHUTDOWN
	The service is notified when system shutdown occurs. This enables the system to send a SERVICE_CONTROL_SHUTDOWN command to the service. The ControlService function cannot send this control code.
dwWin32ExitCode

Specifies a Win32 error code that the service uses to report an error that occurs when it is starting or stopping. To return an error code specific to the service, the service must set this value to ERROR_SERVICE_SPECIFIC_ERROR to indicate that the dwServiceSpecificExitCode member contains the error code. The service should set this value to NO_ERROR when it is running and on normal termination.

dwServiceSpecificExitCode

Specifies a service specific error code that the service returns when an error occurs while the service is starting or stopping. This value is ignored unless the dwWin32ExitCode member is set to ERROR_SERVICE_SPECIFIC_ERROR.

dwCheckPoint

Specifies a value that the service increments periodically to report its progress during a lengthy start, stop, or continue operation. For example, the service should increment this value as it completes each step of its initialization when it is starting up. The user interface program that invoked the operation on the service uses this value to track the progress of the service during a lengthy operation. This value is not valid and should be zero when the service does not have a start, stop, or continue operation pending .

dwWaitHint

Specifies the amount of time, in milliseconds, that the service expects a pending start, stop, or continue operation to take before completion. The user interface program that invoked the operation waits this amount of time before calling QueryServiceStatus to see if the operation has been completed. If the operation has not been completed but dwCheckPoint has been incremented indicating that the service is making progress, the user interface program should wait this amount of time again. When the service does not have a start, stop, or continue operation pending, this value is not valid and should be zero.

See Also

»ControlService«, »EnumDependentServices«, »EnumServicesStatus«, »QueryServiceStatus«, »SetServiceStatus«


  SERVICE_TABLE_ENTRY

typedef struct _SERVICE_TABLE_ENTRY { /* ste */

    LPTSTR lpServiceName;

    LPSERVICE_MAIN_FUNCTION lpServiceProc;

} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY;

The SERVICE_TABLE_ENTRY structure is used by the StartServiceCtrlDispatcher function to specify the SERVICE_MAIN_FUNCTION function for a Win32 service that can run in the calling process.

Members

lpServiceName

Points to a null-terminated string that names a service that can run in this service process. This string is ignored if the service is installed in the service control manager database as a SERVICE_WIN32_OWN_PROCESS service type. For a SERVICE_WIN32_SHARE_PROCESS service process, this string names the service that uses the ServiceMain function pointed to by the lpServiceProc member.

lpServiceProc

Points to a ServiceMain function.

See Also

»ServiceMain«, »StartServiceCtrlDispatcher«


  SESSION_BUFFER

typedef struct _SESSION_BUFFER { /* sb */

    UCHAR lsn;

    UCHAR state;

    UCHAR local_name[NCBNAMSZ];

    UCHAR remote_name[NCBNAMSZ];

    UCHAR rcvs_outstanding;

    UCHAR sends_outstanding;

} SESSION_BUFFER;

The SESSION_BUFFER structure contains information about a local network session. One or more SESSION_BUFFER structures follows a SESSION_HEADER structure when an application specifies NCBSSTAT in the ncb_command member of the NCB structure.

Members

lsn

Specifies the local session number.

state

Specifies the state of the session. This member can be one of the following values:

Value	Meaning
LISTEN_OUTSTANDING	The session is waiting for a call from a remote computer.
CALL_PENDING	The session is attempting to connect to a remote computer.
SESSION_ESTABLISHED	The session connected and is able to transfer data.
HANGUP_PENDING	The session is being deleted due to a command by the local user.
HANGUP_COMPLETE	The session was deleted due to a command by the local user.
SESSION_ABORTED	The session was abandoned due to a network or user problem.
local_name

Specifies the 16-byte NetBIOS name on the local computer used for this session.

remote_name

Specifies the 16-byte NetBIOS name on the remote computer used for this session.

rcvs_outstanding

Specifies the number of pending NCBRECV commands.

sends_outstanding

Specifies the number of pending NCBSEND and NCBCHAINSEND commands.

See Also

»NCB«, »SESSION_HEADER«


  SESSION_HEADER

typedef struct _SESSION_HEADER { /* sh */

    UCHAR sess_name;

    UCHAR num_sess;

    UCHAR rcv_dg_outstanding;

    UCHAR rcv_any_outstanding;

} SESSION_HEADER;

The SESSION_HEADER structure contains information about a network session. This structure is pointed to by the ncb_buffer member of the NCB structure. SESSION_HEADER is followed by as many SESSION_BUFFER structures as are required to describe the current network sessions.

Members

sess_name

Specifies the name number of the session. This value corresponds to the ncb_num member of the NCB structure.

num_sess

Specifies the number of sessions that have the name specified by the sess_name member.

rcv_dg_outstanding

Specifies the number of outstanding NCBDGRECV and NCBDGRECVBC commands.

rcv_any_outstanding

Specifies the number of outstanding NCBRECVANY commands.

See Also

»NCB«, »SESSION_BUFFER«


  SET_PARTITION_INFORMATION

typedef struct _SET_PARTITION_INFORMATION {

   BYTE PartitionType;

} SET_PARTITION_INFORMATION ;

The SetPartitionInformation structure provides information used to set a disk partition's type.

Members

PartitionType

Specifies the type of partition. This member can take on one of the following values:

Value	Meaning
PARTITION_ENTRY_UNUSED	Entry unused.
PARTITION_FAT_12	Specifies a partition with 12-bit FAT entries.
PARTITION_XENIX_1	Specifies a Xenix type 1 partition.
PARTITION_XENIX_2	Specifies a Xenix type 2 partition.
PARTITION_FAT_16	Specifies a partition with 16-bit FAT entries.
PARTITION_EXTENDED	Specifies an extended partition entry.
PARTITION_HUGE	Specifies an MS-DOS V4 huge partition.
PARTITION_IFS	Specifies an IFS partition.
PARTITION_UNIX	Specifies a Unix partition.
VALID_NTFT	Specifies an NTFT partition.
Comments

The DeviceIoControl function  uses a SET_PARTITION_INFORMATION structure as input to an IOCTL_DISK_SET_PARTITION_INFO device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_SET_PARTITION_INFO«, »IOCTL_DISK_GET_PARTITION_INFO«, »PARTITION_INFORMATION«


  SID

typedef PVOID PSID;

The SID structure is a variable-length structure used to uniquely identify users or groups. SID stands for security identifier.

Applications are not to modify the SID structure directly. To create and manipulate a security identifier, use the functions listed in the See Also section.

See Also

»AllocateAndInitializeSid«, »CopySid«, »EqualSid«, »FreeSid«, »GetLengthSid«, »GetSidIdentifierAuthority«, »GetSidLengthRequired«, »GetSidSubAuthority«, »GetSidSubAuthorityCount«, »InitializeSid«, »IsValidSid«, »LookupAccountName«, »LookupAccountSid«


  SID_AND_ATTRIBUTES

typedef struct _SID_AND_ATTRIBUTES { /* saa */

    PSID  Sid;

    DWORD Attributes;

} SID_AND_ATTRIBUTES ;

The SID_AND_ATTRIBUTES structure represents a security identifier (SID) and its attributes. SIDs are used to uniquely identify users or groups.

Members

Sid

Points to an SID structure.

Attributes

Specifies attributes of the SID. This value contains up to 32 one-bit flags. Its meaning depends on the definition and use of the SID.

Comments

A group is represented by an SID. SIDs have attributes that indicate whether they are currently enabled, disabled, or mandatory, and how they are used. An SID_AND_ATTRIBUTES structure can represent an SID whose attributes change frequently. For example, it is used to represent groups in the TOKEN_GROUPS structure.

See Also

»SID«, »TOKEN_GROUPS«, »TOKEN_USER«


  SID_IDENTIFIER_AUTHORITY

typedef struct _SID_IDENTIFIER_AUTHORITY { /* sia */

    BYTE Value[6];

} SID_IDENTIFIER_AUTHORITY ;

The SID_IDENTIFIER_AUTHORITY structure represents the top-level authority of a security identifier (SID).

Members

Value

An array of six bytes specifying a SID's top-level authority.

Comments

The identifier authority value identifies the agency that issued the SID. Some identifier authorities are predefined:

Identifier authority	Value
SECURITY_NULL_SID_AUTHORITY	0
SECURITY_WORLD_SID_AUTHORITY	1
SECURITY_LOCAL_SID_AUTHORITY	2
SECURITY_CREATOR_SID_AUTHORITY	3
SECURITY_NT_AUTHORITY	5
An SID must contain a top-level authority and at least one relative identifier (RID) value.

See Also

»AllocateAndInitializeSid«, »GetSidIdentifierAuthority«, »InitializeSid«, »SID«


  SID_NAME_USE

typedef enum tagSID_NAME_USE {

    SidTypeUser = 1,

    SidTypeGroup,

    SidTypeDomain,

    SidTypeAlias,

    SidTypeWellKnownGroup,

    SidTypeDeletedAccount,

    SidTypeInvalid,

    SidTypeUnknown

} SID_NAME_USE;

The SID_NAME_USE enumerated type lists the uses of security identifiers (SIDs). The enumerators indicate what a SID represents.

Value	Meaning
SidTypeUser	Indicates a user SID.
SidTypeGroup	Indicates a group SID.
SidTypeDomain	Indicates a domain SID.
SidTypeAlias	Indicates an alias SID.
SidTypeWellKnownGroup	Indicates an SID for a well-known group.
SidTypeDeletedAccount	Indicates an SID for a deleted account.
SidTypeInvalid	Indicates an invalid SID.
SidTypeUnknown	Indicates an unknown SID type.
See Also

»LookupAccountName«, »LookupAccountSid«


  SINGLE_LIST_ENTRY

typedef struct _SINGLE_LIST_ENTRY { /* sle */

    struct _SINGLE_LIST_ENTRY *Next;

} SINGLE_LIST_ENTRY;

The SINGLE_LIST_ENTRY structure is available for any entry in a single-linked list.

Members

Next

Points to the next entry in a single-linked list.

Comments

This structure can be used as the beginning of a single-linked list or as any subsequent entry in the list.


  SIZE

typedef struct tagSIZE { /* siz */

    LONG cx;

    LONG cy;

} SIZE;

The SIZE structure specifies the width and height of a rectangle.

Members

cx

Specifies the rectangle's width.

cy

Specifies the rectangle's height.

Comments

The rectangle dimensions stored in this structure may correspond to viewport extents, window extents, text extents, bitmap dimensions, or the aspect-ratio filter for some extended functions.

See Also

»GetAspectRatioFilterEx«, »GetBitmapDimensionEx«, »GetTextExtentPoint«, »GetViewportExtEx«, »GetWindowExtEx«, »ScaleViewportExtEx«, »ScaleWindowExtEx«, »SetBitmapDimensionEx«, »SetViewportExtEx«, »SetWindowExtEx«


  SMALL_RECT

typedef struct _SMALL_RECT { /* srct */

    SHORT Left;

    SHORT Top;

    SHORT Right;

    SHORT Bottom;

} SMALL_RECT;

The SMALL_RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle. This structure is used by console functions to specify rectangular areas of console screen buffers, where the coordinates specify the rows and columns of screen buffer character cells.

Members

Left

Specifies the x-coordinate of the upper-left corner of the rectangle.

Top

Specifies the y-coordinate of the upper-left corner of the rectangle.

Right

Specifies the x-coordinate of the lower-right corner of the rectangle.

Bottom

Specifies the y-coordinate of the lower-right corner of the rectangle.

See Also

»RECT«, »RECTL«


  STARTUPINFO

typedef struct _STARTUPINFO { /* si */

    DWORD   cb;

    LPTSTR  lpReserved;

    LPTSTR  lpDesktop;

    LPTSTR  lpTitle;

    DWORD   dwX;

    DWORD   dwY;

    DWORD   dwXSize;

    DWORD   dwYSize;

    DWORD   dwXCountChars;

    DWORD   dwYCountChars;

    DWORD   dwFillAttribute;

    DWORD   dwFlags;

    WORD    wShowWindow;

    WORD    cbReserved2;

    LPBYTE  lpReserved2;

    HANDLE  hStdInput;

    HANDLE  hStdOutput;

    HANDLE  hStdError;

} STARTUPINFO, *LPSTARTUPINFO;

The STARTUPINFO structure is used in the CreateProcess function to specify main window properties if a new window is created for the new process. For graphical user interface (GUI) processes, this affects the first window created by the CreateWindow function. For console processes, this affects the console window if a new console is created for the process. A process can use the GetStartupInfo function to retrieve the STARTUPINFO structure specified when it was created.

Members

cb

Specifies the size, in bytes, of the structure.

lpReserved

Reserved. Set this member to NULL before passing the structure to CreateProcess.

lpDesktop

If non-NULL, this parameter refers to the name of a desktop to start the process in. If the desktop exists, the new process is associated with this desktop. If the desktop does not exist, a desktop with default attributes is created by this name for the new process.

lpTitle

For console processes, this is the title displayed in the title bar if a new console window is created. If NULL, the name of the executable file is used as the window title instead. This parameter must be NULL for GUI or console processes that do not create a new console window.

dwX, dwY

Ignored unless dwFlags specifies STARTF_USEPOSITION. Specifies the x and y offsets, in pixels, of the upper left corner of a window if a new window is created. The offsets are from the upper left corner of the screen. For GUI processes, the specified position is used the first time CreateWindow is called to create an overlapped window if the x parameter of CreateWindow is CW_USEDEFAULT.

dwXSize, dwYSize

Ignored unless dwFlags specifies STARTF_USESIZE. Specifies the width (dwXSize) and height (dwYSize), in pixels, of the window if a new window is created. For GUI processes, this is used only the first time CreateWindow is called to create an overlapped window if the nWidth parameter of CreateWindow is CW_USEDEFAULT.

dwXCountChars, dwYCountChars

Ignored unless dwFlags specifies STARTF_USECOUNTCHARS. For console processes, specifies the screen buffer width (dwXCountChars) and height (dwYCountChars), in character columns and rows, if a new console window is created. These values are ignored in GUI processes.

dwFillAttribute

Ignored unless dwFlags specifies STARTF_USEFILLATTRIBUTE. For console processes, specifies the initial text and background colors if a new console window is created. These values are ignored in GUI processes.

dwFlags

This is a bit field that determines whether certain STARTUPINFO members are used when the process creates a window. Any combination of the following values can be specified:

Value	Meaning
STARTF_USESHOWWINDOW
	If not specified, the wShowWindow member is ignored.
STARTF_USEPOSITION
	If not specified, the dwX and dwY members are ignored.
STARTF_USESIZE
	If not specified, the dwXSize and dwYSize members are ignored.
STARTF_USECOUNTCHARS
	If not specified, the dwXCountChars and dwYCountChars members are ignored.
STARTF_USEFILLATTRIBUTE
	If not specified, the dwFillAttribute member is ignored.
STARTF_FORCEONFEEDBACK
	If specified, the cursor is in feedback mode for two seconds after CreateProcess is called. If during those two seconds, the process makes the first GUI call, the system gives five more seconds to the process. If during those five seconds, the process shows a window, the system gives five more seconds to the process to finish drawing the window.
	The system turns the feedback cursor off after the first call to GetMessage, regardless of whether the process is drawing.
	For more information on feedback, see the Comments section.
STARTF_FORCEOFFFEEDBACK
	If specified, the feedback cursor is forced off while the process is starting. The normal cursor is displayed. For more information on feedback, see the Comments section.
STARTF_SCREENSAVER
	If specified, the system will treat this application as a screen saver. To wit:
•	The system allows the application to initialize at the foreground priority of the priority class passed to the CreateProcess function.

•	When the application looks for input via the GetMessage or PeekMessage function for the first time, the system changes it to the idle priority class. That lets background applications get priority over it.

•	When the user moves the mouse or hits a key, the system gives the application the foreground priority of the priority class originally passed to the CreateProcess function.

	Creating a screen saver with NORMAL_PRIORITY_CLASS lets the screen saver initialize and terminate over other normal priority applications.
STARTF_USESTDHANDLES
	If specified, sets the process' standard input, standard output, and standard error handles to the handles specified in the hStdInput, hStdOutput, and hStdError fields of the STARTUPINFO structure. The CreateProcess function's fInheritHandles flag must be set to TRUE for this to work properly.
	If not specified, any handles specified in the aforementioned standard handle fields of the STARTUPINFO structure are ignored.
wShowWindow

Ignored unless dwFlags specifies STARTF_USESHOWWINDOW. For GUI processes, specifies the default value the first time ShowWindow is called, if the nCmdShow parameter of ShowWindow is SW_SHOWDEFAULT. Can be any of the SW_ constants defined in WINUSER.H.

In previous versions of Windows, the WinMain function had an nCmdShow parameter that applications were encouraged to pass to the CreateWindow or ShowWindow function. The nCmdShow parameter is no longer available through WinMain. Now applications are encouraged to use SW_SHOWDEFAULT as the default ShowWindow command, in which case, ShowWindow uses the wShowWindow member of the process's STARTUPINFO structure.

cbReserved2

Reserved; must be zero.

lpReserved2

Reserved; must be NULL.

hStdInput

Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the process' standard input handle if STARTF_USESTDHANDLES is specified.

hStdOutput

Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the process' standard output handle if STARTF_USESTDHANDLES is specified.

hStdError

Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the process' standard error handle if STARTF_USESTDHANDLES is specified.

Comments

If a GUI process is being started and neither STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK is specified, the process feedback cursor is used. A GUI process is one whose subsystem is specified as "windows".


  WIN32_STREAM_ID

struct WIN32_STREAM_ID {

    DWORD dwStreamId;

    DWORD dwStreamAttributes;

    DWORD dwStreamSizeLow;

    DWORD dwStreamSizeHigh;

    DWORD dwStreamNameSize ;

    CHAR  cStreamName[ ] ;

}

Members

dwStreamId

Specifies the type of data. This member can be one of the following values:

Value	Meaning
BACKUP_DATA	Standard data
BACKUP_EA_DATA	Extended attribute data
BACKUP_SECURITY_DATA	Windows NT security descriptor data
BACKUP_ALTERNATE_DATA	Alternative data streams
BACKUP_LINK	Hard link information
dwStreamAttributes

Specifies the attributes of data to facilitate cross-operating system transfer. This member must be one or more of the following values:

Value	Description
STREAM_MODIFIED_WHEN_READ	Attribute set if the stream contains data that is modified when read. Allows the backup application to know that verification of data will fail.
STREAM_CONTAINS_SECURITY	Stream contains security data (general attributes). Allows the stream to be ignored on cross-operations restore.
STREAM_USER_ATTRIBUTE_ONE	Unused by the BackupRead and BackupWrite functions, but can be used by an application.
STREAM_USER_ATTRIBUTE_TWO	Unused by BackupRead and BackupWrite, but can be used by an application.
dwStreamSizeLow

Specifies the low-order 32 bits of the size, in bytes, of data.

dwStreamSizeHigh

Specifies the high-order 32 bits of the size needed to support large files.

dwStreamNameSize

Specifies the length of the name of the alternative data stream.

cStreamName

Specifies the name of the alternative data stream, in Unicode™.

See Also

»BackupRead«, »BackupSeek«, »BackupWrite«


  String

String {

    WCHAR  szKey[];

    BYTE   Padding[];

    String Value[];

} String;

The String structure depicts the organization of data in a file-version resource. This structure is not a true C data structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft® Win32™ Software Development Kit (SDK).

The String structure contains a string that describes a specific aspect of a file.

Members

szKey

Specifies an arbitrary 7-bit ASCII English string. The szKey member can be one of the following values:

String	Description
Comments	Value contains any additional information that should be displayed for diagnostic purposes. This string is optional and can be of an arbitrary length.
CompanyName	Value identifies the company that produced the file. For example, "Microsoft Corporation" or "Standard Microsystems Corporation, Inc." This string is required.
FileDescription	Value describes the file in such a way that it can be presented to users. This string may be presented in a list box when the user is choosing files to install. For example, "Keyboard driver for AT-style keyboards" or "Microsoft Word for Windows". This string is required.
FileVersion	Value identifies the version of this file. For example, Value could be "3.00A" or "5.00.RC2". This string is required.
InternalName	Value identifies the file's internal name, if one exists. For example, this string would contain the module name for Windows dynamic-link libraries (DLLs), a virtual device name for Windows virtual devices, or a device name for MS-DOS device drivers. This string is required.
LegalCopyright	Value describes all copyright notices, trademarks, and registered trademarks that apply to the file. This should include the full text of all notices, legal symbols, copyright dates, trademark numbers, and so on. This string is optional. In English, this string should be in the format "Copyright Microsoft Corp. 1990−1992".
LegalTrademarks	Value describes all trademarks and registered trademarks that apply to the file. This should include the full text of all notices, legal symbols, trademark numbers, and so on. This string is optional. In English, this string should be in the format "Windows is a trademark of Microsoft Corporation".
OriginalFilename	Value identifies the original name of the file, not including a path. This enables an application to determine whether a file has been renamed by a user. This name may not be MS-DOS 8.3-format if the file is specific to a non-FAT file system. This string is required.
PrivateBuild	Value describes by whom, where, and why this private version of the file was built. This string should only be present if the VS_FF_PRIVATEBUILD flag is set in the dwFileFlags member of the VS_FIXEDFILEINFO structure. For example, Value could be "Built by OSCAR on \OSCAR2".
ProductName	Value identifies the name of the product with which this file is distributed. For example, this string could be "Microsoft Windows". This string is required.
ProductVersion	Value identifies the version of the product with which this file is distributed. For example, Value could be "3.00A" or "5.00.RC2". This string is required.
SpecialBuild	Value describes how this version of the file differs from the normal version. This entry should only be present if the VS_FF_SPECIALBUILD flag is set in the dwFileFlags member of the VS_FIXEDFILEINFO structure. For example, Value could be "Private build for Olivetti solving mouse problems on M250 and M250E computers".
Padding

Contains as many zero bytes as necessary to align the Value member on a 32-bit boundary.

Value

Specifies a zero-terminated string formatted in the language and code page indicated by the current StringTable structure. See the szKey description for more information.

Comments

For example, a String structure may have an szKey value of "CompanyName" and a Value of "Microsoft Corporation". Another String structure with the same szKey value could contain a Value of "Microsoft GmbH". This might occur if the second String structure were associated with a StringTable structure whose szKey value is 04070000, that is, German/ASCII.

See Also

»StringTable«, »VS_VERSION_INFO«


  StringFileInfo

StringFileInfo {

    WCHAR       szKey[];

    BYTE        Padding[];

    StringTable Children[];

};

The StringFileInfo structure depicts the organization of data in a file-version resource. This structure is not a true C data structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft® Win32™ Software Development Kit (SDK).

The StringFileInfo structure contains version information that must be displayed in a particular language and code page. A code page is an ordered character set.

Members

szKey

Contains "StringFileInfo".

Padding

Contains as many zero bytes as necessary to align the Children member on a 32-bit boundary.

Children

Specifies a list of one or more StringTable structures. Each StringTable structure's szKey member indicates the appropriate language and code-page formatting.

Comments

The Children member of the VS_VERSION_INFO structure may contain zero or more StringFileInfo structures.

See Also

»StringTable«, »VS_VERSION_INFO«


  StringTable

StringTable {

    WCHAR  szKey[];

    BYTE   Padding[];

    String Children[];

};

The StringTable structure depicts the organization of data in a file-version resource. This structure is not a true C data structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft® Win32™ Software Development Kit (SDK).

The StringTable structure contains language and code-page formatting information for the strings specified by the Children member. A code page is an ordered character set.

An executable file or dynamic-link library (DLL) that supports multiple languages should have a version resource for each language, rather than a single version resource that contains strings in several languages.

Members

szKey

Specifies an 8-digit hexadecimal number stored as a string. The four most significant digits represent the language identifier, and the four least significant digits represent the code page for which the data is formatted.

Each Microsoft Standard Language identifier contains two parts: the low-order 10 bits specify the major language and the high-order 6 bits specify the sublanguage. The following language identifiers are valid:

Identifier	Language
0x0401	Arabic
0x0402	Bulgarian
0x0403	Catalan
0x0404	Traditional Chinese
0x0804	Simplified Chinese
0x0405	Czech
0x0406	Danish
0x0407	German
0x0807	Swiss German
0x0408	Greek
0x0409	U.S. English
0x0809	U.K. English
0x040A	Castilian Spanish
0x080A	Mexican Spanish
0x040B	Finnish
0x040C	French
0x080C	Belgian French
0x0C0C	Canadian French
0x100C	Swiss French
0x040D	Hebrew
0x040E	Hungarian
0x040F	Icelandic
0x0410	Italian
0x0810	Swiss Italian
0x0411	Japanese
0x0412	Korean
0x0413	Dutch
0x0813	Belgian Dutch
0x0414	Norwegian — Bokmål
0x0814	Norwegian — Nynorsk
0x0415	Polish
0x0416	Brazilian Portuguese
0x0816	Portuguese
0x0417	Rhaeto-Romanic
0x0418	Romanian
0x0419	Russian
0x041A	Croato-Serbian (Latin)
0x081A	Serbo-Croatian (Cyrillic)
0x041B	Slovak
0x041C	Albanian
0x041D	Swedish
0x041E	Thai
0x041F	Turkish
0x0420	Urdu
0x0421	Bahasa
The code-page value can be one of the following or any IBM-registered code page:

Code page	Description
0	7-bit ASCII
932	Windows, Japan (Shift — JIS X-0208)
949	Windows, Korea (Shift — KSC 5601)
950	Windows, Taiwan (GB5)
1200	Unicode
1250	Windows, Latin-2 (Eastern European)
1251	Windows, Cyrillic
1252	Windows, Multilingual (ANSI)
1253	Windows, Greek
1254	Windows, Turkish
1255	Windows, Hebrew
1256	Windows, Arabic
Files designed for the English version of Windows would normally be marked with a code-page value of 1252.

Padding

Contains as many zero bytes as necessary to align the Children member on a 32-bit boundary.

Children

Specifies a list of zero or more String structures.

Comments

The Children member of the StringFileInfo structure contains at least one StringTable structure with an szKey value of "04090000". This value indicates that the language is U.S. English and the code page is generic 7-bit ASCII.

See Also

»String«, »StringFileInfo«, »VS_VERSION_INFO«


  SYSTEM_ALARM_ACE

Reserved for future use.


  SYSTEM_AUDIT_ACE

typedef struct _SYSTEM_AUDIT_ACE { /* sada */

    ACE_HEADER  Header;

    ACCESS_MASK Mask;

    DWORD       SidStart;

} SYSTEM_AUDIT_ACE;

The SYSTEM_AUDIT_ACE structure defines an access-control entry (ACE) for the system access-control list (ACL) specifying what types of access cause system-level notifications. A system-audit ACE causes an audit message to be logged when a specified user or group attempts to gain access to an object. The user or group is identified by a security identifier (SID).

Members

Header

Specifies an ACE_HEADER structure.

Mask

Specifies an ACCESS_MASK structure that gives the access rights causing audit messages to be generated. The SUCCESSFUL_ACCESS_ACE_FLAG and FAILED_ACCESS_ACE_FLAG flags in the AceFlags member of the ACE_HEADER structure indicate whether messages are generated for successful access attempts, unsuccessful access attempts, or both.

SidStart

Specifies an SID. An access attempt of a kind specified by the Mask member by any user or group whose SID matches the SidStart member causes the system to generate an audit message. If an application does not specify an SID for this member, audit messages are generated for the specified access rights for all users and groups.

Comments

Audit messages are stored in an event log that can be manipulated by using the Win32 API event-logging functions or by using Windows NT Event Viewer (EVENTVWR.EXE).

ACE structures should be aligned on doubleword boundaries. All Windows memory-management functions return doubleword-aligned handles to memory.

See Also

»ACCESS_ALLOWED_ACE«, »ACCESS_DENIED_ACE«, »ACCESS_MASK«, »ACE_HEADER«, »ACL«, »SYSTEM_ALARM_ACE«


  SYSTEM_INFO

typedef struct _SYSTEM_INFO { /* sinf */

    DWORD  dwOemId;

    DWORD  dwPageSize;

    LPVOID lpMinimumApplicationAddress;

    LPVOID lpMaximumApplicationAddress;

    DWORD  dwActiveProcessorMask;

    DWORD  dwNumberOfProcessors;

    DWORD  dwProcessorType;

    DWORD  dwReserved1;

    DWORD  dwReserved2;

} SYSTEM_INFO;

The SYSTEM_INFO structure contains information about the current computer system. This information includes the processor type, page size, original equipment manufacturer (OEM) identifier, and other such information.

Members

dwOemId

Returns a computer identifier that is specific to a particular OEM.

dwPageSize

Returns the page size and specifies the granularity of page protection and commitment.

lpMinimumApplicationAddress

Returns the lowest memory address accessible to applications and dynamic-link libraries (DLLs).

lpMaximumApplicationAddress

Returns the highest memory address accessible to applications and DLLs.

dwActiveProcessorMask

Returns a mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31.

dwNumberOfProcessors

Returns the number of processors in the system.

dwProcessorType

Returns the type of the current processors in the system. All processors are assumed to be of the same type, have the same stepping, and are configured with the same options.

The following processor type constants are currently defined :

PROCESSOR_INTEL_386
PROCESSOR_INTEL_486
PROCESSOR_INTEL_860
PROCESSOR_MIPS_R2000
PROCESSOR_MIPS_R3000
PROCESSOR_MIPS_R4000
PROCESSOR_ALPHA_21064

dwReserved1

Reserved.

dwReserved2

Reserved.


  SYSTEMTIME

typedef struct _SYSTEMTIME {  /* st */

    WORD wYear;

    WORD wMonth;

    WORD wDayOfWeek;

    WORD wDay;

    WORD wHour;

    WORD wMinute;

    WORD wSecond;

    WORD wMilliseconds;

} SYSTEMTIME;

The SYSTEMTIME structure represents a date and time using individual members for the month, day, year, weekday, hour, minute, second, and millisecond.

Members

wYear

Specifies the current year.

wMonth

Specifies the current month; January = 1.

wDayOfWeek

Specifies the current day of the week; Sunday = 0, Monday = 1, etc.

wDay

Specifies the current day of the month.

wHour

Specifies the current hour.

wMinute

Specifies the current minute.

wSecond

Specifies the current second.

wMilliseconds

Specifies the current millisecond.

See Also

»GetLocalTime«, »GetSystemTime«, »SetLocalTime«, »SetSystemTime«, »FILETIME«


  TAPE_CREATE_PARTITION

typedef struct _TAPE_CREATE_PARTITION {  /* tcp */

    ULONG Method;

    ULONG Count;

    ULONG Size;

} TAPE_CREATE_PARTITION;

The TAPE_CREATE_PARTITION structure describes the size and number of tape partitions of a specified type.

Members

Method

Specifies the type of partition. This member must have one of the following values:

Value	Meaning
TAPE_PARTITION_FIXED	Indicates that the partition parameters are fixed by the device.
TAPE_PARTITION_INITIATOR	Indicates that the number of partitions is specified by Count and the partition sizes are specified in the Size array.
TAPE_PARTITION_SELECT	Indicates that the number of partitions is specified by Count and the partition sizes are defined by the device.
Count

Specifies the number of partitions to create and the number of elements in the Size array.

Size

Specifies the size, in megabytes, of each partition. If this value is zero, the partition is the size of the rest of the storage space on the tape.


  TAPE_ERASE

typedef struct _TAPE_ERASE { /* ter */

    ULONG Type;

} TAPE_ERASE;

The TAPE_ERASE structure describes the partition to be erased.

Members

Type

Specifies how to erase the tape. This member must have one of the following values:

Value	Description
TAPE_ERASE_LONG	Erases the entire partition.
TAPE_ERASE_SHORT	Erases only the partition's header block.


  TAPE_GET_DRIVE_PARAMETERS

typedef struct _TAPE_GET_DRIVE_PARAMETERS { /* tgdp */

    BOOLEAN ECC;

    BOOLEAN Compression;

    BOOLEAN DataPadding;

    BOOLEAN ReportSetmarks;

    ULONG   DefaultBlockSize;

    ULONG   MaximumBlockSize;

    ULONG   MinimumBlockSize;

    ULONG   MaximumPartitionCount;

    ULONG   FeaturesLow;

    ULONG   FeaturesHigh;

    ULONG   EOTWarningZoneSize;

} TAPE_GET_DRIVE_PARAMETERS;

The TAPE_GET_DRIVE_PARAMETERS structure describes the tape drive.

Members

ECC

Specifies whether the device supports hardware error correction. This member is TRUE if hardware error correction is supported.

Compression

Specifies whether hardware data compression is enabled or disabled. This member is TRUE if hardware data compression is enabled.

DataPadding

Specifies whether data padding is enabled or disabled. Data padding keeps the tape streaming at a constant speed. This member is TRUE if data padding is enabled.

ReportSetmarks

Specifies whether setmark reporting is enabled or disabled. This member is TRUE if setmark reporting is enabled.

DefaultBlockSize

Specifies the device's default fixed block size.

MaximumBlockSize

Specifies the device's maximum block size.

MinimumBlockSize

Specifies the device's minimum block size.

MaximumPartitionCount

Specifies the maximum number of partitions that can be created on the device.

FeaturesLow

Specifies the low-order 32 bits of the device features flag. This member can have one or more of following bits set:

Value	Meaning
TAPE_DRIVE_COMPRESSION	Device supports hardware data compression.
TAPE_DRIVE_ECC	Device supports hardware error correction.
TAPE_DRIVE_ERASE_BOP_ONLY	Device performs the erase operation from the beginning-of-partition marker only.
TAPE_DRIVE_ERASE_LONG	Device performs a long erase operation.
TAPE_DRIVE_ERASE_IMMEDIATE	Device performs an immediate erase operation —  that is, it returns when the erase operation begins.
TAPE_DRIVE_ERASE_SHORT	Device performs a short erase operation.
TAPE_DRIVE_FIXED	Device creates fixed data partitions.
TAPE_DRIVE_FIXED_BLOCK	Device supports fixed-length block mode.
TAPE_DRIVE_INITIATOR	Device creates initiator-defined partitions.
TAPE_DRIVE_PADDING	Device supports data padding.
TAPE_DRIVE_GET_ABSOLUTE_BLK	Device provides the current device-specific block address.
TAPE_DRIVE_GET_LOGICAL_BLK	Device provides the current logical block address (and logical tape partition).
TAPE_DRIVE_REPORT_SMKS	Device supports setmark reporting.
TAPE_DRIVE_SELECT	Device creates select data partitions.
TAPE_DRIVE_SET_EOT_WT_SIZE	Device supports setting the end-of-medium warning size.
TAPE_DRIVE_TAPE_CAPACITY	Device returns the maximum capacity of the tape.
TAPE_DRIVE_TAPE_REMAINING	Device returns the remaining capacity of the tape.
TAPE_DRIVE_VARIABLE_BLOCK	Device supports variable-length block mode.
TAPE_DRIVE_WRITE_PROTECT	Device returns an error if the tape is write-enabled or write-protected.
FeaturesHigh

Contains the high-order 32 bits of the device features flag. This member can have one or more of the following bits set:

Value	Meaning
TAPE_DRIVE_ABS_BLK_IMMED	Device moves the tape to a device-specific block address and returns as soon as the move begins.
TAPE_DRIVE_ABSOLUTE_BLK	Device moves the tape to a device specific block address.
TAPE_DRIVE_END_OF_DATA	Device moves the tape to the end-of-data marker in a partition.
TAPE_DRIVE_FILEMARKS	Device moves the tape forward (or backward) a specified number of filemarks.
TAPE_DRIVE_LOAD_UNLOAD	Device enables and disables the device for further operations.
TAPE_DRIVE_LOAD_UNLOAD_IMMED	Device supports immediate load and unload operations.
TAPE_DRIVE_LOCK_UNLOCK	Device enables and disables the tape ejection mechanism.
TAPE_DRIVE_LOCK_UNLK_IMMED	Device supports immediate lock and unlock operations.
TAPE_DRIVE_LOG_BLK_IMMED	Device moves the tape to a logical block address in a partition and returns as soon as the move begins.
TAPE_DRIVE_LOGICAL_BLK	Device moves the tape to a logical block address in a partition.
TAPE_DRIVE_RELATIVE_BLKS	Device moves the tape forward (or backward) a specified number of blocks.
TAPE_DRIVE_REVERSE_POSITION	Device moves the tape backward over blocks, filemarks, or setmarks.
TAPE_DRIVE_REWIND_IMMEDIATE	Device supports immediate rewind operation.
TAPE_DRIVE_SEQUENTIAL_FMKS	Device moves the tape forward (or backward) to the first occurrence of a specified number of consecutive filemarks.
TAPE_DRIVE_SEQUENTIAL_SMKS	Device moves the tape forward (or backward) to the first occurrence of a specified number of consecutive setmarks.
TAPE_DRIVE_SET_BLOCK_SIZE	Device supports setting the size of a fixed-length logical block or setting the variable-length block mode.
TAPE_DRIVE_SET_COMPRESSION	Device enables and disables hardware data compression.
TAPE_DRIVE_SET_ECC	Device enables and disables hardware error correction.
TAPE_DRIVE_SET_PADDING	Device enables and disables data padding.
TAPE_DRIVE_SET_REPORT_SMKS	Device enables and disables the reporting of setmarks.
TAPE_DRIVE_SETMARKS	Device moves the tape forward (or reverse) a specified number of setmarks.
TAPE_DRIVE_SPACE_IMMEDIATE	Device supports immediate spacing.
TAPE_DRIVE_TENSION	Device supports tape tensioning.
TAPE_DRIVE_TENSION_IMMED	Device supports immediate tape tensioning.
TAPE_DRIVE_WRITE_FILEMARKS	Device writes filemarks.
TAPE_DRIVE_WRITE_LONG_FMKS	Device writes long filemarks.
TAPE_DRIVE_WRITE_MARK_IMMED	Device supports immediate writing of short and long filemarks.
TAPE_DRIVE_WRITE_SETMARKS	Device writes setmarks.
TAPE_DRIVE_WRITE_SHORT_FMKS	Device writes short filemarks.
EOTWarningZoneSize

Indicates the number of bytes between the end-of-tape warning and the physical end of the tape.


  TAPE_GET_MEDIA_PARAMETERS

typedef struct _TAPE_GET_MEDIA_PARAMETERS {  /* tgmp */

    LARGE_INTEGER   Capacity;

    LARGE_INTEGER   Remaining;

    DWORD   BlockSize;

    DWORD   PartitionCount;

    BOOLEAN WriteProtected;

} TAPE_GET_MEDIA_PARAMETERS;

The TAPE_GET_MEDIA_PARAMETERS structure describes the tape in the tape drive.

Members

Capacity

Specifies the total number of bytes on the tape.

Remaining

Specifies the number of bytes between the current position and the end of the tape.

BlockSize

Specifies the number of bytes per block. Block sizes are typically multiples of 512 bytes, in the range 512 bytes through 32 kilobytes.

PartitionCount

Specifies the number of partitions on the tape.

WriteProtected

Specifies whether the tape is write-protected. If this member is TRUE, the tape is write-protected.

Comments

The GetTapeParameters function fills the RemainingLow, RemainingHigh, CapacityLow, and CapacityHigh members with estimates of the tape remaining and the total capacity.


  TAPE_GET_POSITION

typedef struct _TAPE_GET_POSITION { /* tgpos */

    ULONG Type;

    ULONG Partition;

    ULONG OffsetLow;

    ULONG OffsetHigh;

} TAPE_GET_POSITION;

The TAPE_GET_POSITION structure describes the position of the tape.

Members

Type

Specifies the type of position. This member must be one of the following values:

Value	Description
TAPE_ABSOLUTE_POSITION	Position specified by the OffsetLow and OffsetHigh members is an absolute number of blocks from the beginning of the partition specified by the Partition member.
TAPE_LOGICAL_POSITION	Position specified by OffsetLow and OffsetHigh is relative to the current position in the partition specified by Partition.
Partition

Specifies the partition to position within. If this member is zero, the current partition is assumed.

OffsetLow

Specifies the low-order 32 bits of the block address.

OffsetHigh

Specifies the high-order 32 bits of the block address. If the high-order 32 bits are not required, this parameter should be zero.


  TAPE_SET_POSITION

typedef struct _TAPE_SET_POSITION { /* tspos */

    ULONG Method;

    ULONG Partition;

    ULONG OffsetLow;

    ULONG OffsetHigh;

} TAPE_SET_POSITION;

The TAPE_SET_POSITION structure describes how and where to position the tape.

Members

Method

Specifies the type of positioning. This member must be one of the following values:

Value	Description
TAPE_ABSOLUTE_BLOCK	Moves the tape to the device-specific block address specified by the OffsetLow and OffsetHigh members. The the Partition member is ignored.
TAPE_LOGICAL_BLOCK	Moves the tape to the block address specified by OffsetLow and OffsetHigh in the partition specified by Partition.
TAPE_REWIND	Moves the tape to the beginning of the current partition. The Partition, OffsetLow, and OffsetHigh members are ignored.
TAPE_SPACE_END_OF_DATA	Moves the tape to the end of the data on the partition specified by Partition.
TAPE_SPACE_FILEMARKS	Moves the tape forward (or backward) the number of filemarks specified by OffsetLow and OffsetHigh in the current partition. The Partition member is ignored.
TAPE_SPACE_RELATIVE_BLOCKS	Moves the tape forward (or backward) the number of blocks specified by OffsetLow and OffsetHigh in the current partition. The Partition members is ignored.
TAPE_SPACE_SEQUENTIAL_FMKS	Moves the tape forward (or backward) to the first occurrence of n filemarks in the current partition, where n is the number specified by OffsetLow and OffsetHigh. The Partition parameter is ignored.
TAPE_SPACE_SEQUENTIAL_SMKS	Moves the tape forward (or backward) to the first occurrence of n setmarks in the current partition, where n is the number specified by OffsetLow and OffsetHigh. The Partition member is ignored.
TAPE_SPACE_SETMARKS	Moves the tape forward (or backward) the number of setmarks specified by OffsetLow and OffsetHigh in the current partition. The Partition member is ignored.
Partition

Specifies the partition to position within. If this member is zero, the current partition is assumed.

OffsetLow

Specifies the low-order 32 bits of the block address or count for the position operation specified by the Method member.

OffsetHigh

Specifies the high-order 32 bits of the block address or count for the position operation specified by the Method member. If the high-order 32 bits are not required, this parameter should be zero.

Comments

If the positioning is relative, a positive offset moves the tape forward (toward the end of the tape) and a negative offset moves the tape backward (toward the beginning of the tape).


  TAPE_PREPARE

typedef struct _TAPE_PREPARE { /* tp */

    ULONG Operation;

} TAPE_PREPARE;

The TAPE_PREPARE structure describes how to prepare the tape.

Members

Operation

Specifies how to prepare the tape. This member must be one of the following values:

Value	Description
TAPE_LOCK	Locks the tape ejection mechanism. This prevents the tape from being ejected accidentally during a tape operation.
TAPE_TENSION	Moves to the end of the tape and rewinds to the beginning of the tape. This value is ignored if the tape device does not support this action.
TAPE_UNLOAD	Rewinds and unloads the tape.
TAPE_UNLOCK	Unlocks the tape ejection mechanism.


  TAPE_SET_DRIVE_PARAMETERS

typedef struct _TAPE_SET_DRIVE_PARAMETERS {  /* tsdp */

    BOOLEAN ECC;

    BOOLEAN Compression;

    BOOLEAN DataPadding;

    BOOLEAN ReportSetmarks;

    ULONG   EOTWarningZoneSize;

} TAPE_SET_DRIVE_PARAMETERS;

The TAPE_SET_DRIVE_PARAMETERS structure describes the tape drive.

Members

ECC

Specifies whether the device supports hardware error correction. This member is TRUE if hardware error correction is supported.

Compression

Specifies whether hardware data compression is enabled or disabled. This member is TRUE if hardware data compression is enabled.

DataPadding

Specifies whether data padding is enabled or disabled. Data padding keeps the tape streaming at a constant speed. This member is TRUE if data padding is enabled.

ReportSetmarks

Specifies whether setmark reporting is enabled or disabled. This member is TRUE if setmarks are enabled.

EOTWarningZoneSize

Specifies the number of bytes between the end-of-tape warning and the physical end of the tape.


  TAPE_SET_MEDIA_PARAMETERS

typedef struct _TAPE_SET_MEDIA_PARAMETERS { /* tsmp */

    ULONG BlockSize;

} TAPE_SET_MEDIA_PARAMETERS;

The TAPE_SET_MEDIA_PARAMETERS structure describes the tape in the tape drive.

Members

BlockSize

Specifies the number of bytes per block. Block sizes should be powers of 2 : values like 256, 512, 1024, and 204k. Maximum and minimum block sizes can be obtained by calling the GetTapeParameters function.

See Also

»GetTapeParameters«, »SetTapeParameters«


  TAPE_WRITE_MARKS

typedef struct _TAPE_WRITE_MARKS { /* twm */

    ULONG Type;

    ULONG Count;

} TAPE_WRITE_MARKS;

The TAPE_WRITE_MARKS structure describes the type and number of tapemarks to write.

Members

Type

Specifies the type of tapemark to write. This member can be one of the following values:

Value	Description
TAPE_LONG_FILEMARKS	Writes long filemarks.
TAPE_SEQUENTIAL_FILEMARKS	Writes sequential filemarks.
TAPE_SETMARKS	Writes setmarks.
TAPE_SHORT_FILEMARKS	Writes short filemarks.
Count

Specifies the number of tapemarks to write.


  TEXTMETRIC

typedef struct tagTEXTMETRIC { /* tm */

    LONG tmHeight;

    LONG tmAscent;

    LONG tmDescent;

    LONG tmInternalLeading;

    LONG tmExternalLeading;

    LONG tmAveCharWidth;

    LONG tmMaxCharWidth;

    LONG tmWeight;

    LONG tmOverhang;

    LONG tmDigitizedAspectX;

    LONG tmDigitizedAspectY;

    BYTE tmFirstChar;

    BYTE tmLastChar;

    BYTE tmDefaultChar;

    BYTE tmBreakChar;

    BYTE tmItalic;

    BYTE tmUnderlined;

    BYTE tmStruckOut;

    BYTE tmPitchAndFamily;

    BYTE tmCharSet;

} TEXTMETRIC;

The TEXTMETRIC structure contains basic information about a physical font. All sizes are given in logical units; that is, they depend on the current mapping mode of the display context.

Members

tmHeight

Specifies the height (ascent + descent) of characters.

tmAscent

Specifies the ascent (units above the base line) of characters.

tmDescent

Specifies the descent (units below the base line) of characters.

tmInternalLeading

Specifies the amount of leading (space) inside the bounds set by the tmHeight member. Accent marks and other diacritical characters may occur in this area. The designer may set this member to zero.

tmExternalLeading

Specifies the amount of extra leading (space) that the application adds between rows. Since this area is outside the font, it contains no marks and is not altered by text output calls in either OPAQUE or TRANSPARENT mode. The designer may set this member to zero.

tmAveCharWidth

Specifies the average width of characters in the font (generally defined as the width of the letter x). This value does not include overhang required for bold or italic characters.

tmMaxCharWidth

Specifies the width of the widest character in the font.

tmWeight

Specifies the weight of the font.

tmOverhang

Specifies the extra width per string that may be added to some synthesized fonts. When synthesizing some attributes, such as bold or italic, graphics device interface (GDI) or a device may have to add width to a string on both a per-character and per-string basis. For example, GDI makes a string bold by expanding the spacing of each character and overstriking by an offset value; it italicizes a font by shearing the string. In either case, there is an overhang past the basic string. For bold strings, the overhang is the distance by which the overstrike is offset. For italic strings, the overhang is the amount the top of the font is sheared past the bottom of the font.

The tmOverhang member enables the application to determine how much of the character width returned by a GetTextExtentPoint function call on a single character is the actual character width and how much is the per-string extra width. The actual width is the extent minus the overhang.

tmDigitizedAspectX

Specifies the horizontal aspect of the device for which the font was designed.

tmDigitizedAspectY

Specifies the vertical aspect of the device for which the font was designed. The ratio of the tmDigitizedAspectX and tmDigitizedAspectY members is the aspect ratio of the device for which the font was designed.

tmFirstChar

Specifies the value of the first character defined in the font.

tmLastChar

Specifies the value of the last character defined in the font.

tmDefaultChar

Specifies the value of the character to be substituted for characters not in the font.

tmBreakChar

Specifies the value of the character that will be used to define word breaks for text justification.

tmItalic

Specifies an italic font if it is nonzero.

tmUnderlined

Specifies an underlined font if it is nonzero.

tmStruckOut

Specifies a strikeout font if it is nonzero.

tmPitchAndFamily

Specifies the pitch and family of the selected font. The low-order bit specifies the pitch of the font. If it is 1, the font is variable pitch. If it is 0, the font is fixed pitch.

The four high-order bits designate the font family. The tmPitchAndFamily member can be combined with the hexadecimal value 0xF0 by using the bitwise AND operator and can then be compared with the font family names for an identical match. For information about the font families, see the description of the »LOGFONT« structure.

tmCharSet

Specifies the character set of the font.

See Also

»GetTextMetrics«, »LOGFONT«


  TIME_ZONE_INFORMATION

typedef struct _TIME_ZONE_INFORMATION { /* tzi */

    LONG       Bias;

    WCHAR      StandardName[ 32 ];

    SYSTEMTIME StandardDate;

    LONG       StandardBias;

    WCHAR      DaylightName[ 32 ];

    SYSTEMTIME DaylightDate;

    LONG       DaylightBias;

} TIME_ZONE_INFORMATION;

The TIME_ZONE_INFORMATION structure specifies information specific to the time zone.

Members

Bias

Specifies the current bias, in minutes, for local time translation on this computer. The bias is the difference, in minutes, between Universal Time Convention (UTC) time and local time. All translations between UTC time and local time are based on the following formula:

UTC = local time + bias

This member is required.

StandardName

Specifies a null-terminated string associated with standard time on this operating system. For example, this parameter could contain "EST" to indicate Eastern Standard Time. This string is not used by the operating system, so anything stored there by using the SetTimeZoneInformation function is returned unchanged by the GetTimeZoneInformation function. This string can be empty.

StandardDate

Specifies a SYSTEMTIME structure that contains a date and UTC time when the transition from daylight time to standard time occurs on this operating system. If this date is not specified, the wMonth member in the SYSTEMTIME structure must be zero. If this date is specified, the DaylightDate value in the TIME_ZONE_INFORMATION structure must also be specified. Local time translations done during the standard-time range are relative to the supplied StandardBias value.

This member supports two date formats. Absolute format specifies an exact date and time when standard time begins. In this form, the wYear, wMonth, wDay, wHour, wMinute, wSecond, and wMilliseconds members of the SYSTEMTIME structure are used to specify an exact date.

Day-in-month format is specified by setting the wYear member to zero, setting the wDayOfWeek member to an appropriate weekday, and using a wDay value in the range 1 through 5 to select the correct day in the month. Using this notation, the first Sunday in April can be specified, as can the last Thursday in October (5 is equal to "the last").

StandardBias

Specifies a bias value to be used during local time translations that occur during standard time. This member is ignored if a value for the StandardDate member is not supplied.

This value is added to the value of the Bias member to form the bias used during standard time. In most time zones, the value of this member is zero.

DaylightName

Specifies a null-terminated string associated with daylight time on this operating system. For example, this parameter could contain "PDT" to indicate Pacific Daylight Time. This string is not used by the operating system, so anything stored there by using the SetTimeZoneInformation function is returned unchanged by the GetTimeZoneInformation function. This string can be empty.

DaylightDate

Specifies a SYSTEMTIME structure that contains a date and UTC time when the transition from standard time to daylight time occurs on this operating system. If this date is not specified, the wMonth member in the SYSTEMTIME structure must be zero. If this date is specified, the StandardDate value in the TIME_ZONE_INFORMATION structure must also be specified. Local time translations during the daylight-time range are relative to the supplied DaylightBias value. This member supports the absolute and day-in-month time formats described for the StandardDate member.

DaylightBias

Specifies a bias value to be used during local time translations that occur during daylight time. This member is ignored if a value for the DaylightDate member is not supplied.

This value is added to the value of the Bias member to form the bias used during daylight time. In most time zones, the value of this member is −60.

See Also

»GetTimeZoneInformation«, »SetTimeZoneInformation«


  TIMECAPS

typedef struct timecaps_tag {

    UINT  wPeriodMin;

    UINT  wPeriodMax;

} TIMECAPS;

The TIMECAPS structure contains information about the resolution of the timer.

Members

wPeriodMin

Minimum period supported by the timer, in milliseconds.

wPeriodMax

Maximum period supported by the timer, in milliseconds.

See Also

»timeGetDevCaps«


  TOKEN_CONTROL

typedef struct _TOKEN_CONTROL { /* tc */

    LUID TokenId;

    LUID AuthenticationId;

    LUID ModifiedId;

    TOKEN_SOURCE TokenSource;

} TOKEN_CONTROL ;

The TOKEN_CONTROL structure contains information that identifies an access token.

Members

TokenId

Specifies a locally unique identifier (LUID) identifying this instance of the token object.

AuthenticationId

Specifies an LUID assigned to the session this token represents. There can be many tokens representing a single logon session.

ModifiedId

Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a security context has changed since it was last used.

TokenSource

Specifies a TOKEN_SOURCE structure identifying the agency that issued the token. This information is used in audit logging.

See Also

»LUID«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_DEFAULT_DACL

typedef struct _TOKEN_DEFAULT_DACL {  /* tdd */

    PACL DefaultDacl;

} TOKEN_DEFAULT_DACL;

The TOKEN_DEFAULT_DACL structure specifies a discretionary access-control list (ACL).

Members

DefaultDacl

Points to an ACL structure assigned by default to any objects created by the user represented by the access token.

Comments

The GetTokenInformation function retrieves the default discretionary ACL for an access token, in the form of a TOKEN_DEFAULT_DACL structure. This structure is also used with the SetTokenInformation function to set the default discretionary ACL.

See Also

»GetTokenInformation«, »SetTokenInformation«, »ACL«, »TOKEN_CONTROL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_GROUPS

typedef struct _TOKEN_GROUPS { /* tg */

    DWORD GroupCount;

    SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];

} TOKEN_GROUPS;

The TOKEN_GROUPS structure contains information about a set of groups in an access token.

Members

GroupCount

Specifies the number of groups in the access token.

Groups

Specifies an array of SID_AND_ATTRIBUTES structures containing a token's group security identifiers (SIDs) and corresponding attributes.

The following attributes can be used with this parameter:

Value	Meaning
SE_GROUP_MANDATORY	The group cannot be disabled.
SE_GROUP_ENABLED_BY_DEFAULT	The group is enabled by default.
SE_GROUP_ENABLED	The group is enabled.
SE_GROUP_OWNER	The user is the owner of the group or the SID can be assigned as the owner of the token or objects.
SE_GROUP_LOGON_ID	The group is a logon identifier.
See Also

»AdjustTokenGroups«, »SID_AND_ATTRIBUTES«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_INFORMATION_CLASS

typedef enum tagTOKEN_INFORMATION_CLASS { /* tic */

    TokenUser = 1,

    TokenGroups,

    TokenPrivileges,

    TokenOwner,

    TokenPrimaryGroup,

    TokenDefaultDacl,

    TokenSource,

    TokenType,

    TokenImpersonationLevel,

    TokenStatistics

} TOKEN_INFORMATION_CLASS;

The TOKEN_INFORMATION_CLASS enumerated type is used to indicate the type of information being assigned to or retrieved from an access token.

See Also

»GetTokenInformation«, »SetTokenInformation«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_OWNER

typedef struct _TOKEN_OWNER { /* to */

    PSID Owner;

} TOKEN_OWNER;

The TOKEN_OWNER structure contains information about the owner of an access token.

Members

Owner

Points to an SID structure representing a user who will become the owner of any objects created by a process using this access token. The security identifier (SID) must be one of the user or group SIDs already in the token.

See Also

»GetTokenInformation«, »SetTokenInformation«, »SID« »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_PRIMARY_GROUP

typedef struct _TOKEN_PRIMARY_GROUP { /* tpg */

    PSID PrimaryGroup;

} TOKEN_PRIMARY_GROUP;

The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID) for an access token.

Members

PrimaryGroup

Points to an SID structure representing a group that will become the primary group of any objects created by a process using this access token. The security identifier (SID) must be one of the group SIDs already in the token.

See Also

»GetTokenInformation«, »SetTokenInformation«, »SID« »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_PRIVILEGES

typedef struct _TOKEN_PRIVILEGES { /* tp */

    DWORD PrivilegeCount;

    LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];

} TOKEN_PRIVILEGES;

The TOKEN_PRIVILEGES structure contains information about the set of privileges for an access token.

Members

PrivilegeCount

Specifies the number of privileges in the token.

Privileges

Specifies an array of LUID_AND_ATTRIBUTES structures describing the token's privileges.

The following attributes can be used with this parameter:

Attribute	Description
SE_PRIVILEGE_ENABLED_BY_DEFAULT
	The privilege is enabled by default.
SE_PRIVILEGE_ENABLED
	The privilege is enabled.
SE_PRIVILEGE_USED_FOR_ACCESS
	The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.
See Also

»AdjustTokenPrivileges«, »GetTokenInformation«, »PrivilegeCheck«, »PrivilegedServiceAuditAlarm«, »SetTokenInformation«, »LUID_AND_ATTRIBUTES«, »PRIVILEGE_SET«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_SOURCE

typedef struct _TOKEN_SOURCE { /* ts */

    CHAR SourceName[8];

    LUID SourceIdentifier;

} TOKEN_SOURCE;

The TOKEN_SOURCE structure identifies the source of an access token.

Members

SourceName

Specifies an eight-byte character string used to identify the source of an access token. This is used to distinguish between such sources as Session Manager, LAN Manager, and RPC Server. A string, rather than a constant, is used to identify the source so users and developers can make extensions to the system, such as by adding other networks, that act as the source of access tokens.

SourceIdentifier

Specifies a locally unique identifier (LUID) provided by the source component named by the SourceName member. This value aids the source component in relating context blocks, such as session-control structures, to the token. This value is typically, but not necessarily, an LUID.

See Also

»GetTokenInformation«, »LUID«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_STATISTICS«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_STATISTICS

typedef struct _TOKEN_STATISTICS { /* tst */

    LUID  TokenId;

    LUID  AuthenticationId;

    LARGE_INTEGER ExpirationTime;

    TOKEN_TYPE    TokenType;

    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;

    DWORD DynamicCharged;

    DWORD DynamicAvailable;

    DWORD GroupCount;

    DWORD PrivilegeCount;

    LUID  ModifiedId;

} TOKEN_STATISTICS;

The TOKEN_STATISTICS structure contains information about an access token. An application can retrieve this information by calling the GetTokenInformation function.

Members

TokenId

Specifies a locally unique identifier (LUID) that identifies this instance of the token object.

AuthenticationId

Specifies an LUID assigned to the session this token represents. There can may be many tokens representing a single logon session.

ExpirationTime

Specifies the time at which this token expires. Expiration times for access tokens are not supported in the current version of Windows NT.

TokenType

Specifies a TOKEN_TYPE enumerated type indicating whether the token is a primary or impersonation token.

ImpersonationLevel

Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type indicating the impersonation level of the token. This member is valid only if the TokenType is TokenImpersonation.

DynamicCharged

Specifies the amount, in bytes, of memory allocated for storing default protection and a primary group identifier.

DynamicAvailable

Specifies the portion of memory allocated for storing default protection and a primary group identifier not already in use. This value is returned as a count of free bytes.

GroupCount

Specifies the number of supplemental group security identifiers (SIDs) included in the token.

PrivilegeCount

Specifies the number of privileges included in the token.

ModifiedId

Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a security context has changed since it was last used.

See Also

»GetTokenInformation«, »LUID«, »SECURITY_IMPERSONATION_LEVEL«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_TYPE«, »TOKEN_USER«


  TOKEN_TYPE

typedef enum tagTOKEN_TYPE { /* tt */

    TokenPrimary = 1,

    TokenImpersonation

} TOKEN_TYPE;

The TOKEN_TYPE enumerated type differentiates between a primary and impersonation token.

See Also

»GetTokenInformation«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_USER«


  TOKEN_USER

typedef struct _TOKEN_USER { /* tu */

    SID_AND_ATTRIBUTES User;

} TOKEN_USER;

The TOKEN_USER structure identifies the user associated with an access token.

Members

User

Specifies an SID_AND_ATTRIBUTES structure representing the user associated with the access token. There are currently no attributes defined for user security identifiers (SIDs).

See Also

»GetTokenInformation«, »SID_AND_ATTRIBUTES«, »TOKEN_CONTROL«, »TOKEN_DEFAULT_DACL«, »TOKEN_GROUPS«, »TOKEN_INFORMATION_CLASS«, »TOKEN_OWNER«, »TOKEN_PRIMARY_GROUP«, »TOKEN_PRIVILEGES«, »TOKEN_SOURCE«, »TOKEN_STATISTICS«, »TOKEN_TYPE«


  TTPOLYCURVE

typedef struct tagTTPOLYCURVE { /* ttpc */

    WORD    wType;

    WORD    cpfx;

    POINTFX apfx[1];

} TTPOLYCURVE;

The TTPOLYCURVE structure contains information about a curve in the outline of a TrueType® character.

Members

wType

Specifies the type of curve described by the structure. This member can be one of the following values:

Value	Meaning
TT_PRIM_LINE	Curve is a polyline.
TT_PRIM_QSPLINE	Curve is a Bézier spline.
cpfx

Specifies the number of POINTFX structures in the array.

apfx

Specifies an array of POINTFX structures that define the polyline or Bézier spline.

Comments

When an application calls the GetGlyphOutline function, a glyph outline for a TrueType character is returned in a TTPOLYGONHEADER structure, followed by as many TTPOLYCURVE structures as are required to describe the glyph. All points are returned as POINTFX structures and represent absolute positions, not relative moves. The starting point given by the pfxStart member of the TTPOLYGONHEADER structure is the point at which the outline for a contour begins. The TTPOLYCURVE structures that follow can be either polyline records or spline records.

Polyline records are a series of points; lines drawn between the points describe the outline of the character. Spline records represent the quadratic curves (that is, quadratic b-splines) used by TrueType.

See Also

»POINTFX«, »TTPOLYGONHEADER«


  TTPOLYGONHEADER

typedef struct tagTTPOLYGONHEADER { /* ttph */

    DWORD   cb;

    DWORD   dwType;

    POINTFX pfxStart;

} TTPOLYGONHEADER;

The TTPOLYGONHEADER structure specifies the starting position and type of a contour in a TrueType® character outline.

Members

cb

Specifies the number of bytes required by the TTPOLYGONHEADER structure and TTPOLYCURVE structure or structures required to describe the contour of the character.

dwType

Specifies the type of character outline returned. Currently, this value must be TT_POLYGON_TYPE.

pfxStart

Specifies the starting point of the contour in the character outline.

Comments

Each TTPOLYGONHEADER structure is followed by one or more TTPOLYCURVE structures.

See Also

»POINTFX«, »TTPOLYCURVE«


  ULARGE_INTEGER

typedef struct _ULARGE_INTEGER { /* uli */

    DWORD LowPart;

    DWORD HighPart;

} ULARGE_INTEGER;

The ULARGE_INTEGER structure is used to specify a 64-bit unsigned integer value.

Members

LowPart

Specifies the low-order 32 bits.

HighPart

Specifies the high-order 32 bits.

See Also

»LARGE_INTEGER«


  UNLOAD_DLL_DEBUG_INFO

typedef struct _UNLOAD_DLL_DEBUG_INFO { /* uddi */

    LPVOID lpBaseOfDll;

} UNLOAD_DLL_DEBUG_INFO;

The UNLOAD_DLL_DEBUG_INFO structure contains information about a dynamic-link library (DLL) that has just been unloaded.

Members

lpBaseOfDll

Points to the base address of the DLL in the address space of the process unloading the DLL.

See Also

»DEBUG_EVENT«


  Var

Var {

    WCHAR szKey[];

    BYTE  Padding[];

    Var   Value[];

};

The Var structure depicts the organization of data in a file-version resource. This structure is not a true C data structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft® Win32™ Software Development Kit (SDK).

The Var structure contains version information not dependent on a particular language and code page.

Members

szKey

Specifies an arbitrary 7-bit ASCII English string. The szKey member can be the following value:

Value	Meaning
Translation	Value contains an array of doubleword values indicating the language and code-page combinations supported by this file. The high-order word of each doubleword contains a Microsoft language identifier and the low-order word contains the IBM® code-page number. Either high-order or low-order word may be zero, indicating that the file is language or code-page independent. If this block is omitted, the file will be interpreted as language and code-page independent.
Padding

Contains as many zero bytes as necessary to align the Value member on a 32-bit boundary.

Value

Specifies a list of zero or more Var structures.

Comments

The Children member of the VS_VERSION_INFO structure may contain zero or more Var structures.

See Also

»VarFileInfo«, »VS_VERSION_INFO«


  VarFileInfo

VarFileInfo {

    WCHAR szKey[];

    BYTE  Padding[];

    Var   Children[];

};

The VarFileInfo structure depicts the organization of data in a file-version resource. This structure is not a true C data structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft Win32 Software Development Kit (SDK).

The VarFileInfo structure contains version information not dependent on a particular language and code page.

Members

szKey

Contains "VarFileInfo".

Padding

Contains as many zero bytes as necessary to align the Children member on a 32-bit boundary.

Children

Specifies a list of zero or more Var structures.

Comments

The Children member of the VS_VERSION_INFO structure may contain zero or more VarFileInfo structures.

See Also

»Var«, »VS_VERSION_INFO«


  VERIFY_INFORMATION

typedef struct _VERIFY_INFORMATION {

   LARGE_INTEGER  StartingOffset;

   DWORD  Length;

} VERIFY_INFORMATION ;

The VERIFY_INFORMATION structure provides information used to logically format a disk extent.

Members

StartingOffset

Specifies the starting offset of the disk extent.

Length

Length, in bytes, of the disk extent.

Comments

The DeviceIoControl function  uses a VERIFY_INFORMATION structure as input to an IOCTL_DISK_VERIFY device i/o operation.

See Also

»DeviceIoControl«, »IOCTL_DISK_VERIFY«


  VS_FIXEDFILEINFO

typedef struct tagVS_FIXEDFILEINFO {  /* vsffi */

    DWORD dwSignature;

    DWORD dwStrucVersion;

    DWORD dwFileVersionMS;

    DWORD dwFileVersionLS;

    DWORD dwProductVersionMS;

    DWORD dwProductVersionLS;

    DWORD dwFileFlagsMask;

    DWORD dwFileFlags;

    DWORD dwFileOS;

    DWORD dwFileType;

    DWORD dwFileSubtype;

    DWORD dwFileDateMS;

    DWORD dwFileDateLS;

} VS_FIXEDFILEINFO;

The VS_FIXEDFILEINFO structure contains version information about a file. This information is language and code-page independent.

Members

dwSignature

Contains the value 0xFEEFO4BD. This is used with the szKey member of VS_VERSION_INFO data when searching a file for the VS_FIXEDFILEINFO structure.

dwStrucVersion

Specifies the binary version number of this structure. The high-order word of this member contains the major version number, and the low-order word contains the minor version number. This value must be greater than 0x00000029.

dwFileVersionMS

Specifies the most significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.

dwFileVersionLS

Specifies the least significant 32 bits of the file's binary version number. This member is used with dwFileVersionMS to form a 64-bit value used for numeric comparisons.

dwProductVersionMS

Specifies the most significant 32 bits of the binary version number of the product with which this file was distributed. This member is used with dwProductVersionLS to form a 64-bit value used for numeric comparisons.

dwProductVersionLS

Specifies the least significant 32 bits of the binary version number of the product with which this file was distributed. This member is used with dwProductVersionMS to form a 64-bit value used for numeric comparisons.

dwFileFlagsMask

Contains a bitmask that specifies the valid bits in dwFileFlags. A bit is valid only if it was defined when the file was created.

dwFileFlags

Contains a bitmask that specifies the Boolean attributes of the file. This member can include one or more of the following values:

Flag	Description
VS_FF_DEBUG	The file contains debugging information or is compiled with debugging features enabled.
VS_FF_INFOINFERRED	The file's version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSION_INFO data.
VS_FF_PATCHED	The file has been modified and is not identical to the original shipping file of the same version number.
VS_FF_PRERELEASE	The file is a development version, not a commercially released product.
VS_FF_PRIVATEBUILD	The file was not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry.
VS_FF_SPECIALBUILD	The file was built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry.
dwFileOS

Specifies the operating system for which this file was designed. This member can be one of the following values:

Flag	Description
VOS_UNKNOWN	The operating system for which the file was designed is unknown to Windows.
VOS_DOS	The file was designed for MS-DOS.
VOS_OS216	The file was designed for 16-bit OS/2.
VOS_OS232	The file was designed for 32-bit OS/2.
VOS_NT	The file was designed for Windows NT.
VOS_WINDOWS16	The file was designed for 16-bit Windows.
VOS_PM16	The file was designed for 16-bit Presentation Manager.
VOS_PM32	The file was designed for 32-bit Presentation Manager.
VOS_WINDOWS32	The file was designed for the Win32 API.
An application can combine these values to indicate that the file was designed for one operating system running on another. The following dwFileOS values are examples of this, but are not a complete list:

Flag	Description
VOS_DOS_WINDOWS16	The file was designed for 16-bit Windows running on MS-DOS.
VOS_DOS_WINDOWS32	The file was designed for the Win32 API running on MS-DOS.
VOS_OS216_PM16	The file was designed for 16-bit Presentation Manager running on 16-bit OS/2.
VOS_OS232_PM32	The file was designed for 32-bit Presentation Manager running on 32-bit OS/2.
VOS_NT_WINDOWS32	The file was designed for the Win32 API running on Windows NT.
dwFileType

Specifies the general type of file. This member can be one of the following values:

Flag	Description
VFT_UNKNOWN	The file type is unknown to Windows.
VFT_APP	The file contains an application.
VFT_DLL	The file contains a dynamic-link library (DLL).
VFT_DRV	The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver.
VFT_FONT	The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file.
VFT_VXD	The file contains a virtual device.
VFT_STATIC_LIB	The file contains a static-link library.
All other values are reserved for future use by Microsoft.

dwFileSubtype

Specifies the function of the file. The possible values depend on the value of dwFileType. For all values of dwFileType not described in the following list, dwFileSubtype is zero.

If dwFileType is VFT_DRV, dwFileSubtype can be one of the following values:

Flag	Description
VFT2_UNKNOWN	The driver type is unknown by Windows.
VFT2_DRV_PRINTER	The file contains a printer driver.
VFT2_DRV_KEYBOARD	The file contains a keyboard driver.
VFT2_DRV_LANGUAGE	The file contains a language driver.
VFT2_DRV_DISPLAY	The file contains a display driver.
VFT2_DRV_MOUSE	The file contains a mouse driver.
VFT2_DRV_NETWORK	The file contains a network driver.
VFT2_DRV_SYSTEM	The file contains a system driver.
VFT2_DRV_INSTALLABLE	The file contains an installable driver.
VFT2_DRV_SOUND	The file contains a sound driver.
If dwFileType is VFT_FONT, dwFileSubtype can be one of the following values:

Flag	Description
VFT2_UNKNOWN	The font type is unknown by Windows.
VFT2_FONT_RASTER	The file contains a raster font.
VFT2_FONT_VECTOR	The file contains a vector font.
VFT2_FONT_TRUETYPE	The file contains a TrueType font.
If dwFileType is VFT_VXD, dwFileSubtype contains the virtual device identifier included in the virtual device control block.

All dwFileSubtype values not listed here are reserved for future use by Microsoft.

dwFileDateMS

Specifies the most significant 32 bits of the file's 64-bit binary creation date and time stamp.

dwFileDateLS

Specifies the least significant 32 bits of the file's 64-bit binary creation date and time stamp.

Comments

The Value member of the VS_VERSION_INFO data is a VS_FIXEDFILEINFO structure.

See Also

»StringFileInfo«, »VS_VERSION_INFO«


  VS_VERSION_INFO

VS_VERSION_INFO {

    WORD  wLength;

    WORD  wValueLength;

    WORD  bText;

    WCHAR szKey[];

    BYTE  Padding1[];

    VS_FIXEDFILEINFO Value;

    BYTE  Padding2[];

    BYTE  Children[];

};

The VS_VERSION_INFO structure depicts the organization of data in a file-version resource. This structure is not a true C data structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft® Win32™ Software Development Kit (SDK).

Members

wLength

Specifies the length of the VS_VERSION_INFO structure. This length does not include any padding that aligns the subsequent version structure on a 32-bit boundary.

wValueLength

Specifies the length of the Value member. This value is zero if there is no Value member associated with the current version structure.

bText

Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.

szKey

Contains "VS_VERSION_INFO".

Padding1

Contains as many zero bytes as necessary to align the Value member on a 32-bit boundary.

Value

Contains a VS_FIXEDFILEINFO structure that specifies arbitrary data associated with this structure. The wValueLength member specifies the length of this member; if wValueLength is zero, this member does not exist.

Padding2

Contains as many zero bytes as necessary to align the Children member on a 32-bit boundary. These bytes are not included in wValueLength.

Children

Specifies a list of zero or more StringFileInfo or VarFileInfo structures (or both) that are children of the current version structure.

Comments

The VS_VERSION_INFO structure is the root structure that contains all other file information structures.

See Also

»StringFileInfo«, »VarFileInfo«, »VS_FIXEDFILEINFO«


  WAVEFORMAT

typedef struct waveformat_tag {

    WORD  wFormatTag;

    WORD  nChannels;

    DWORD  nSamplesPerSec;

    DWORD  nAvgBytesPerSec;

    WORD  nBlockAlign;

} WAVEFORMAT;

The WAVEFORMAT structure describes the format of waveform data. Only format information common to all waveform data formats is included in this structure. For formats that require additional information, this structure is included as a member in another structure, along with the additional information.

Members

wFormatTag

Specifies the format type. The currently defined waveform format type is WAVE_FORMAT_PCM, which specifies that the waveform data is pulse code modulated (PCM).

nChannels

Specifies the number of channels in the waveform data. Monaural data uses one channel and stereo data uses two channels.

nSamplesPerSec

Specifies the sample rate, in samples per second.

nAvgBytesPerSec

Specifies the required average data-transfer rate, in bytes per second.

nBlockAlign

Specifies the block alignment, in bytes. The block alignment is the minimum atomic unit of data.

Comments

For PCM data, the block alignment is the number of bytes used by a single sample, including data for both channels, if the data is stereo. For example, the block alignment for 16-bit stereo PCM is 4 bytes (2 channels, 2 bytes per sample).

See Also

»PCMWAVEFORMAT«


  WAVEHDR

typedef struct wavehdr_tag {

    LPSTR  lpData;

    DWORD  dwBufferLength;

    DWORD  dwBytesRecorded;

    DWORD  dwUser;

    DWORD  dwFlags;

    DWORD  dwLoops;

    struct wavehdr_tag *lpNext;

    DWORD  reserved;

} WAVEHDR;

The WAVEHDR structure defines the header used to identify a waveform data buffer.

Members

lpData

Points to the waveform data buffer.

dwBufferLength

Specifies the length of the data buffer.

dwBytesRecorded

Specifies the amount of data in the buffer, if the header is used in input.

dwUser

Specifies 32 bits of user data.

dwFlags

Specifies flags that provide information about the data buffer. This member can be one or more of the following values:

Value	Meaning
WHDR_DONE	Device driver is finished with the data buffer and is returning it to the application. This flag is set by the device driver.
WHDR_BEGINLOOP	Buffer is the first buffer in a loop. This flag is used only with output data buffers.
WHDR_ENDLOOP	Buffer is the last buffer in a loop. This flag is used only with output data buffers.
WHDR_PREPARED	Data buffer has been prepared by using the waveInPrepareHeader or waveOutPrepareHeader function. This flag is set by Windows.
dwLoops

Specifies the number of times to play the loop. This parameter is used only with output data buffers.

lpNext

Reserved; do not use.

reserved

Reserved; do not use.

Comments

Use the WHDR_BEGINLOOP and WHDR_ENDLOOP flags in the dwFlags member to specify the beginning and ending data blocks for looping. To loop on a single block, specify both flags for the same block. Use the dwLoops member in the WAVEHDR structure of the first block in the loop to specify the number of times to play the loop.


  WAVEINCAPS

typedef struct waveincaps_tag {

    WORD  wMid;

    WORD  wPid;

    VERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    DWORD  dwFormats;

    WORD  wChannels;

} WAVEINCAPS;

The WAVEINCAPS structure describes the capabilities of a waveform input device.

Members

wMid

Specifies a manufacturer identifier for the device driver for the waveform input device. Manufacturer identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

wPid

Specifies a product identifier for the waveform input device. Product identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

vDriverVersion

Specifies the version number of the device driver for the waveform input device. The high-order byte is the major version number, and the low-order byte is the minor version number.

szPname

Specifies the product name in a null-terminated string.

dwFormats

Specifies the standard formats supported. This member can be a combination of the following values:

Value	Meaning
WAVE_FORMAT_1M08	11.025 kHz, monaural, 8-bit
WAVE_FORMAT_1S08	11.025 kHz, stereo, 8-bit
WAVE_FORMAT_1M16	11.025 kHz, monaural, 16-bit
WAVE_FORMAT_1S16	11.025 kHz, stereo, 16-bit
WAVE_FORMAT_2M08	22.05 kHz, monaural, 8-bit
WAVE_FORMAT_2S08	22.05 kHz, stereo, 8-bit
WAVE_FORMAT_2M16	22.05 kHz, monaural, 16-bit
WAVE_FORMAT_2S16	22.05 kHz, stereo, 16-bit
WAVE_FORMAT_4M08	44.1 kHz, monaural, 8-bit
WAVE_FORMAT_4S08	44.1 kHz, stereo, 8-bit
WAVE_FORMAT_4M16	44.1 kHz, monaural, 16-bit
WAVE_FORMAT_4S16	44.1 kHz, stereo, 16-bit
wChannels

Specifies whether the device supports monaural (1) or stereo (2) input.

See Also

»waveInGetDevCaps«


  WAVEOUTCAPS

typedef struct waveoutcaps_tag {

    WORD  wMid;

    WORD  wPid;

    MMVERSION  vDriverVersion;

    TCHAR  szPname[MAXPNAMELEN];

    DWORD  dwFormats;

    WORD  wChannels;

    DWORD  dwSupport;

} WAVEOUTCAPS;

The WAVEOUTCAPS structure describes the capabilities of a waveform output device.

Members

wMid

Specifies a manufacturer identifier for the device driver for the waveform output device. Manufacturer identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

wPid

Specifies a product identifier for the waveform output device. Product identifiers are defined in Appendix D, "Manufacturer and Product Identifiers" in the Microsoft Win32 Programmer's Reference, Volume 2.

vDriverVersion

Specifies the version number of the device driver for the waveform output device. The high-order byte is the major version number, and the low-order byte is the minor version number.

szPname

Specifies the product name in a null-terminated string.

dwFormats

Specifies the standard formats supported. This member can be a combination of the following values:

Value	Meaning
WAVE_FORMAT_1M08	11.025 kHz, monaural, 8-bit
WAVE_FORMAT_1S08	11.025 kHz, stereo, 8-bit
WAVE_FORMAT_1M16	11.025 kHz, monaural, 16-bit
WAVE_FORMAT_1S16	11.025 kHz, stereo, 16-bit
WAVE_FORMAT_2M08	22.05 kHz, monaural, 8-bit
WAVE_FORMAT_2S08	22.05 kHz, stereo, 8-bit
WAVE_FORMAT_2M16	22.05 kHz, monaural, 16-bit
WAVE_FORMAT_2S16	22.05 kHz, stereo, 16-bit
WAVE_FORMAT_4M08	44.1 kHz, monaural, 8-bit
WAVE_FORMAT_4S08	44.1 kHz, stereo, 8-bit
WAVE_FORMAT_4M16	44.1 kHz, monaural, 16-bit
WAVE_FORMAT_4S16	44.1 kHz, stereo, 16-bit
wChannels

Specifies whether the device supports monaural (1) or stereo (2) output.

dwSupport

Specifies optional functionality supported by the device. This member can be one or more of the following values:

Value	Meaning
WAVECAPS_PITCH	Supports pitch control.
WAVECAPS_PLAYBACKRATE	Supports playback rate control.
WAVECAPS_VOLUME	Supports volume control.
WAVECAPS_LRVOLUME	Supports separate left and right volume control.
Comments

If a device supports volume changes, the WAVECAPS_VOLUME flag is set for the dwSupport member. If a device supports separate volume changes on the left and right channels, both the WAVECAPS_VOLUME and the WAVECAPS_LRVOLUME flags are set for this member.

See Also

»waveOutGetDevCaps«


  WIN32_FIND_DATA

typedef struct _WIN32_FIND_DATA { /* wfd */

    DWORD dwFileAttributes;

    FILETIME ftCreationTime;

    FILETIME ftLastAccessTime;

    FILETIME ftLastWriteTime;

    DWORD    nFileSizeHigh;

    DWORD    nFileSizeLow;

    DWORD    dwReserved0;

    DWORD    dwReserved1;

    CHAR     cFileName[ MAX_PATH ];

    CHAR     cAlternateFileName[ 14 ];

} WIN32_FIND_DATA;

The WIN32_FIND_DATA structure describes a file found by the FindFirstFile or FindNextFile function.

Members

dwFileAttributes

Specifies the file attributes of the file found.

This flag can be one or more of the following values:

Value	Meaning
FILE_ATTRIBUTE_ARCHIVE
	The file is an archive file. Applications use this flag to mark files for backup or removal.
FILE_ATTRIBUTE_DIRECTORY
	The file is a directory.
FILE_ATTRIBUTE_HIDDEN
	The file is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL
	The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_READONLY
	The file is a read-only file. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM
	The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY
	The file is a temporary file. Applications can write to the file only if absolutely necessary. Most of the file's data remains in memory without being flushed to the media because the file will soon be deleted.
FILE_ATTRIBUTE_ATOMIC_WRITE
	The file is an atomic write file. Applications write to the file using atomic write semantics. If any write operation flushes data to the medium, all write operations up to that point are also flushed, as well as any file system structures. This ensures that the data is retrievable at a later time.
FILE_ATTRIBUTE_XACTION_WRITE
	Reserved for future use. Do not specify.
ftCreationTime

Specifies the time the file was created. A value of 0,0 indicates that the file system containing the file does not support this time field.

ftLastAccessTime

Specifies the time that the file was last accessed. A value of 0,0 indicates that the file system containing the file does not support this time field.

ftLastWriteTime

Specifies the time that the file was last written to. All file systems support this time field.

nFileSizeHigh

Specifies the high-order word of the file size, in bytes.

nFileSizeLow

Specifies the low-order word of the file size, in bytes.

cFileName

Specifies a null-terminated string that is the name of the file.

cAlternateFileName

Specifies a null-terminated string that is an alternative name of the file, in the 8.3 (filename.ext) format.


  WINDOW_BUFFER_SIZE_RECORD

typedef struct _WINDOW_BUFFER_SIZE_RECORD { /* wbsr */

    COORD dwSize;

} WINDOW_BUFFER_SIZE_RECORD;

The WINDOW_BUFFER_SIZE_RECORD structure is used in a console INPUT_RECORD structure to report changes in the size of the screen buffer.

Members

dwSize

Specifies the new size of the screen buffer, in character cell columns and rows.

Comments

Buffer size events are placed in the input buffer when the console is in window-aware mode (ENABLE_WINDOW_INPUT).

See Also

»INPUT_RECORD«, »ReadConsoleInput«


  WINDOWPLACEMENT

typedef struct tagWINDOWPLACEMENT {     /* wndpl */

    UINT  length;

    UINT  flags;

    UINT  showCmd;

    POINT ptMinPosition;

    POINT ptMaxPosition;

    RECT  rcNormalPosition;

} WINDOWPLACEMENT;

The WINDOWPLACEMENT structure contains information about the placement of a window on the screen.

Members

length

Specifies the length, in bytes, of the structure.

flags

Specifies flags that control the position of the minimized window and the method by which the window is restored. This member can be one or both of the following values:

Value	Meaning
WPF_SETMINPOSITION
	Specifies that the coordinates of the minimized window may be specified. This flag must be specified if the coordinates are set in the ptMinPosition member.
WPF_RESTORETOMAXIMIZED
	Specifies that the restored window will be maximized, regardless of whether it was maximized before it was minimized. This setting is only valid the next time the window is restored. It does not change the default restoration behavior. This flag is only valid when the SW_SHOWMINIMIZED value is specified for the showCmd member.
showCmd

Specifies the current show state of the window. This member can be one of the following values:

Value	Meaning
SW_HIDE	Hides the window and activates another window.
SW_MINIMIZE	Minimizes the specified window and activates the top-level window in the system's list.
SW_RESTORE	Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position (same as SW_SHOWNORMAL).
SW_SHOW	Activates a window and displays it in its current size and position.
SW_SHOWMAXIMIZED	Activates a window and displays it as a maximized window.
SW_SHOWMINIMIZED	Activates a window and displays it as an icon.
SW_SHOWMINNOACTIVE	Displays a window as an icon. The active window remains active.
SW_SHOWNA	Displays a window in its current state. The active window remains active.
SW_SHOWNOACTIVATE	Displays a window in its most recent size and position. The active window remains active.
SW_SHOWNORMAL	Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position (same as SW_RESTORE).
ptMinPosition

Specifies the coordinates of the window's top-left corner when the window is minimized.

ptMaxPosition

Specifies the coordinates of the window's top-left corner when the window is maximized.

rcNormalPosition

Specifies the window's coordinates when the window is in the restored position.

See Also

»ShowWindow«, »POINT«, »RECT«


  WINDOWPOS

typedef struct tagWINDOWPOS { /* wp */

    HWND hwnd;

    HWND hwndInsertAfter;

    int  x;

    int  y;

    int  cx;

    int  cy;

    UINT flags;

} WINDOWPOS;

The WINDOWPOS structure contains information about the size and position of a window.

Members

hwnd

Identifies the window.

hwndInsertAfter

Identifies the window behind which this window is placed.

x

Specifies the position of the left edge of the window.

y

Specifies the position of the right edge of the window.

cx

Specifies the window width, in pixels.

cy

Specifies the window height, in pixels.

flags

Specifies the window position. This member can be one of the following values:

Value	Meaning
SWP_DRAWFRAME	Draws a frame (defined in the window's class description) around the window. The window receives a WM_NCCALCSIZE message.
SWP_HIDEWINDOW	Hides the window.
SWP_NOACTIVATE	Does not activate the window.
SWP_NOCOPYBITS	Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window has been sized or repositioned.
SWP_NOMOVE	Retains the current position (ignores the x and y parameters).
SWP_NOOWNERZORDER	Does not change the owner window's position in the Z order.
SWP_NOSIZE	Retains the current size (ignores the cx and cy parameters).
SWP_NOREDRAW	Does not redraw changes.
SWP_NOREPOSITION	Same as the SWP_NOOWNERZORDER flag.
SWP_NOZORDER	Retains the current Z order (ignores the hwndInsertAfter member).
SWP_SHOWWINDOW	Displays the window.
See Also

»EndDeferWindowPos«, »SetWindowPos«


  WNDCLASS

typedef struct tagWNDCLASS {    /* wc */

    UINT    style;

    WNDPROC lpfnWndProc;

    int     cbClsExtra;

    int     cbWndExtra;

    HANDLE  hInstance;

    HICON   hIcon;

    HCURSOR hCursor;

    HBRUSH  hbrBackground;

    LPCTSTR lpszMenuName;

    LPCTSTR lpszClassName;

} WNDCLASS;

The WNDCLASS structure contains the window class attributes that are registered by the RegisterClass function.

Members

style

Specifies the class style. These styles can be combined by using the bitwise OR (|) operator. This member can be any combination of the following values:

Value	Action
CS_BYTEALIGNCLIENT	Aligns the window's client area on the byte boundary (in the x direction) to enhance performance during drawing operations. This style affects the width of the window and its horizontal position on the display.
CS_BYTEALIGNWINDOW	Aligns a window on a byte boundary (in the x direction) to enhance performance during operations that involve moving or sizing the window. This style affects the width of the window and its horizontal position on the display.
CS_CLASSDC	Allocates one device context (DC) to be shared by all windows in the class. Because window classes are process specific, it is possible for multiple threads of a multithreaded application to create a window of the same class. It is also possible for the threads to attempt to use the DC simultaneously. When this happens, the operating system allows only one of the threads to successfully finish its drawing operation.
CS_DBLCLKS	Sends double-click messages to the window procedure when the user double-clicks the mouse while the cursor is within a window belonging to the class.
CS_GLOBALCLASS	Allows an application to create a window of the class regardless of the value of the hInstance parameter passed to the CreateWindow or CreateWindowEx function. If you do not specify this style, the hInstance parameter passed to the CreateWindow (or CreateWindowEx) function must be the same as the hInstance parameter passed to the RegisterClass function.
	You can create a global class by creating the window class in a dynamic-link library (DLL) and listing the name of the DLL in the registration database under the following keys:
	HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\ CurrentVersion\Windows\APPINIT_DLLS
	Whenever a process starts, the operating system loads the specified DLLs in the context of the newly started process before calling the main function in that process. The DLL must register the class during its initialization procedure and must specify the CS_GLOBALCLASS style.
CS_HREDRAW	Redraws the entire window if a movement or size adjustment changes the width of the client area.
CS_NOCLOSE	Disables the Close command on the System menu.
CS_OWNDC	Allocates a unique device context for each window in the class.
CS_PARENTDC	Gives the parent window's device context to the child windows. Specifying CS_PARENTDC enhances an application's performance. When an application calls the GetDC function, passing the handle of a window that belongs to a class with the CS_PARENTDC style, the operating system searches for a device context that has been precalculated for the window's parent window. If all child windows of a particular parent window specify this style, the system need not recalculate a device context for any of the child windows.
CS_SAVEBITS	Saves, as a bitmap, the portion of the screen image obscured by a window. Windows uses the saved bitmap to re-create the screen image when the window is removed. Windows displays the bitmap at its original location and does not send WM_PAINT messages to windows obscured by the window if the memory used by the bitmap has not been discarded and if other screen actions have not invalidated the stored image. This style is useful for small windows that are displayed briefly and then removed before other screen activity takes place (for example, menus or dialog boxes). This style increases the time required to display the window, because the operating system must first allocate memory to store the bitmap.
CS_VREDRAW	Redraws the entire window if a movement or size adjustment changes the height of the client area.
lpfnWndProc

Points to the window procedure. For more information, see the description of the WindowProc callback function.

cbClsExtra

Specifies the number of extra bytes to allocate following the window-class structure. The operating system initializes the bytes to zero.

cbWndExtra

Specifies the number of extra bytes to allocate following the window instance. The operating system initializes the bytes to zero. If an application uses the WNDCLASS structure to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA.

hInstance

Identifies the instance that the window procedure of this class is within.

hIcon

Identifies the class icon. This member must be a handle of an icon resource. If this member is NULL, an application must draw an icon whenever the user minimizes the application's window.

hCursor

Identifies the class cursor. This member must be a handle of a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window.

hbrBackground

Identifies the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the standard system colors listed below, and the value 1 must be added to the chosen color; for example, COLOR_BACKGROUND + 1 specifies the system background color. If a color value is given, you must convert it to one of the following HBRUSH types:

COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT

The operating system automatically deletes class background brushes when the class is freed. An application should not delete these brushes, because a class may be used by multiple instances of an application.

When this member is NULL, an application must paint its own background whenever it is requested to paint in its client area. To determine whether the background must be painted, an application can either process the WM_ERASEBKGND message or test the fErase member of the PAINTSTRUCT structure filled by the BeginPaint function.

lpszMenuName

Points to a null-terminated character string that specifies the resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu.

lpszClassName

Points to a null-terminated string or is an atom that identifies a string. If this parameter is an atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value, must be in the low-order word of lpszClassName; the high-order word must be zero.

The lpszClassName string or atom specifies the window class name.

See Also

»GlobalAddAtom«, »PAINTSTRUCT«, »WindowProc«


  XFORM

typedef struct  tagXFORM {  /* xfrm */

    FLOAT eM11;

    FLOAT eM12;

    FLOAT eM21;

    FLOAT eM22;

    FLOAT eDx;

    FLOAT eDy;

} XFORM;

The XFORM structure specifies a world-space to page-space transformation.

Members

eM11

Specifies the following:

Operation	Meaning
Scaling	Horizontal scaling component
Rotation	Cosine of rotation angle
Reflection	Horizontal component
eM12

Specifies the following:

Operation	Meaning
Shear	Horizontal proportionality constant
Rotation	Sine of the rotation angle
eM21

Specifies the following:

Operation	Meaning
Shear	Vertical proportionality constant
Rotation	Negative sine of the rotation angle
eM22

Specifies the following:

Operation	Meaning
Scaling	Vertical scaling component
Rotation	Cosine of rotation angle
Reflection	Vertical reflection component
eDx

Specifies the horizontal translation component.

eDy

Specifies the vertical translation component.

The following list describes how the members are used for each operation:

Operation	eM11	eM12	eM21	eM22
Rotation	Cosine	Sine	Negative sine	Cosine
Scaling	Horizontal scaling component	Nothing	Nothing	Vertical Scaling Component
Shear	Nothing	Horizontal Proportionality Constant	Vertical Proportionality Constant	Nothing
Reflection	Horizontal Reflection Component	Nothing	Nothing	Vertical Reflection Component
See Also

»ExtCreateRegion«, »GetWorldTransform«, »ModifyWorldTransform«, »PlayEnhMetaFile«, »SetWorldTransform«


Macros
  Chapter 4  Macros


  GetBValue

BYTE GetBValue(rgb)
DWORD  rgb;   /* 32-bit RGB value  */

The GetBValue macro retrieves an intensity value for the blue component of a 32-bit red, green, blue (RGB) value.

Parameters

rgb

Specifies an RGB color value.

Return Value

The return value is the intensity of the blue component of the specified RGB color.

Comments

The intensity value is in the range 0 through 255.

The GetBValue macro is defined as follows:

#define GetBValue(rgb)      ((BYTE)((rgb)>>16))

See Also

»GetGValue«, »GetRValue«, »PALETTEINDEX«, »PALETTERGB«, »RGB«


  GetGValue

BYTE GetGValue(rgb)
DWORD  rgb;   /* 32-bit RGB value  */

The GetGValue macro retrieves an intensity value for the green component of a 32-bit red, green, blue (RGB) value.

Parameters

rgb

Specifies an RGB color value.

Return Value

The return value is the intensity of the green component of the specified RGB color.

Comments

The intensity value is in the range 0 through 255.

The GetGValue macro is defined as follows:

#define GetGValue(rgb)      ((BYTE)(((WORD)(rgb)) >> 8))

See Also

»GetBValue«, »GetRValue«, »PALETTEINDEX«, »PALETTERGB«, »RGB«


  GetRValue

BYTE GetRValue(rgb)
DWORD  rgb;   /* 32-bit RGB value  */

The GetRValue macro retrieves an intensity value for the red component of a 32-bit red, green, blue (RGB) value.

Parameters

rgb

Specifies an RGB color value.

Return Value

The return value is the intensity of the red component of the specified RGB color.

Comments

The intensity value is in the range 0 through 255.

The GetRValue macro is defined as follows:

#define GetRValue(rgb)      ((BYTE)(rgb))

See Also

»GetBValue«, »GetGValue«, »PALETTEINDEX«, »PALETTERGB«, »RGB«


  HIBYTE

BYTE HIBYTE(wValue)
WORD  wValue;   /* value from which high-order byte is retrieved */

The HIBYTE macro retrieves the high-order byte from the given 16-bit value.

Parameters

wValue

Specifies the value to be converted.

Return Value

The return value is the high-order byte of the specified value.

Comments

The HIBYTE macro is defined as follows:

#define HIBYTE(w)  ((BYTE)(((WORD)(w) >> 8) & 0xFF))

See Also

»HIWORD«, »LOBYTE«


  HIWORD

WORD HIWORD(dwValue)
DWORD  dwValue;   /* value from which high-order word is retrieved */

The HIWORD macro retrieves the high-order word from the given 32-bit value.

Parameters

dwValue

Specifies the value to be converted.

Return Value

The return value is the high-order word of the specified value.

Comments

The HIWORD macro is defined as follows:

#define HIWORD(l)  ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))

See Also

»HIBYTE«, »LOWORD«


  LANGIDFROMLCID

WORD LANGIDFROMLCID(lcid)
LCID  lcid;   /* locale identifier  */

The LANGIDFROMLCID macro retrieves a language identifier from a locale identifier.

Parameters

lcid

Specifies the locale identifier. This parameter may have been created by using the MAKELCID macro.

Return Value

The return value is a language identifier.

Comments

The LANGIDFROMLCID macro is defined as follows:

#define LANGIDFROMLCID(lcid)  ((WORD) (lcid))

See Also

»MAKELANGID«, »MAKELCID«, »PRIMARYLANGID«, »SUBLANGID«


  LOBYTE

BYTE LOBYTE(wValue)
WORD  wValue;   /* value from which low-order byte is retrieved */

The LOBYTE macro retrieves the low-order byte from the given 16-bit value.

Parameters

wValue

Specifies the value to be converted.

Return Value

The return value is the low-order byte of the specified value.

Comments

The LOBYTE macro is defined as follows:

#define LOBYTE(w)  ((BYTE)(w))

See Also

»HIBYTE«, »LOWORD«


  LOWORD

WORD LOWORD(dwValue)
DWORD  dwValue;   /* value from which low-order word is retrieved */

The LOWORD macro retrieves the low-order word from the given 32-bit value.

Parameters

dwValue

Specifies the value to be converted.

Return Value

The return value is the low-order word of the specified value.

Comments

The LOWORD macro is defined as follows:

#define LOWORD(l)  ((WORD)(l))

See Also

»HIWORD«, »LOBYTE«


  MAKEINTATOM

LPTSTR MAKEINTATOM(wInteger)
WORD  wInteger;   /* integer to make into atom */

The MAKEINTATOM macro creates an integer atom that represents a character string of decimal digits.

Integer atoms created by this macro can be added to an atom table by using the AddAtom or GlobalAddAtom function.

Parameters

wInteger

Specifies the numeric value to be made into an integer atom.

Return Value

The return value is a pointer to the atom created for the given integer.

Comments

Although the return value of the MAKEINTATOM macro is cast as an LPTSTR value, it cannot be used as a string pointer except when it is passed to atom-management functions that require an LPTSTR argument.

The DeleteAtom and GlobalDeleteAtom functions always succeed for integer atoms, even though they do nothing. The string returned by the GetAtomName and GlobalGetAtomName functions for an integer atom is a null-terminated string in which the first character is a pound sign (#) and the remaining characters are the decimal digits used in the MAKEINTATOM macro.

The MAKEINTATOM macro is defined as follows:

#define MAKEINTATOM(i)  (LPTSTR)((DWORD)((WORD)(i)))

See Also

»AddAtom«, »DeleteAtom«, »GetAtomName«, »GlobalAddAtom«, »GlobalDeleteAtom«, »GlobalGetAtomName«


  MAKEINTRESOURCE

LPTSTR MAKEINTRESOURCE(wInteger)
WORD  wInteger;   /* integer to convert */

The MAKEINTRESOURCE macro converts an integer value to a resource type compatible with Windows resource-management functions. This macro is used in place of a string containing the name of the resource.

Parameters

wInteger

Specifies the integer value to be converted.

Return Value

The return value is the specified value in the low-order word and zero in the high-order word.

Comments

The return value should be passed only to the Windows resource-management functions, as the lpType parameter.

The MAKEINTRESOURCE macro is defined as follows:

#define MAKEINTRESOURCE(i)  (LPTSTR)((DWORD)((WORD)(i)))


  MAKELANGID

WORD MAKELANGID(usPrimaryLanguage, usSubLanguage)
USHORT  usPrimaryLanguage;   /* primary language identifier */
USHORT  usSubLanguage;   /* sublanguage identifier */

The MAKELANGID macro creates a language identifier from a primary language identifier and a sublanguage identifier.

Parameters

usPrimaryLanguage

Specifies the primary language identifier. This parameter can be one of the following values:

LANG_ALBANIAN	LANG_ITALIAN
LANG_ARABIC	LANG_JAPANESE
LANG_BAHASA	LANG_KOREAN
LANG_BULGARIAN	LANG_NEUTRAL
LANG_CATALAN	LANG_NORWEGIAN
LANG_CHINESE	LANG_POLISH
LANG_CZECH	LANG_PORTUGUESE
LANG_DANISH	LANG_RHAETO_ROMAN
LANG_DUTCH	LANG_ROMANIAN
LANG_ENGLISH	LANG_RUSSIAN
LANG_FINNISH	LANG_SERBO_CROATIAN
LANG_FRENCH	LANG_SLOVAK
LANG_GERMAN	LANG_SPANISH
LANG_GREEK	LANG_SWEDISH
LANG_HEBREW	LANG_THAI
LANG_HUNGARIAN	LANG_TURKISH
LANG_ICELANDIC	LANG_URDU
usSubLanguage

Specifies the sublanguage identifier. This parameter can be one of the following values:

SUBLANG_CHINESE_SIMPLIFIED	SUBLANG_GERMAN_SWISS
SUBLANG_CHINESE_TRADITIONAL	SUBLANG_ITALIAN
SUBLANG_DEFAULT	SUBLANG_ITALIAN_SWISS
SUBLANG_DUTCH	SUBLANG_NEUTRAL
SUBLANG_DUTCH_BELGIAN	SUBLANG_NORWEGIAN_BOKMÅL
SUBLANG_ENGLISH_AUS	SUBLANG_NORWEGIAN_NYNORSK
SUBLANG_ENGLISH_CAN	SUBLANG_PORTUGUESE
SUBLANG_ENGLISH_UK	SUBLANG_PORTUGUESE_BRAZILIAN
SUBLANG_ENGLISH_US	SUBLANG_SERBO_CROATIAN_CYRILLIC
SUBLANG_FRENCH	SUBLANG_SERBO_CROATIAN_LATIN
SUBLANG_FRENCH_BELGIAN	SUBLANG_SPANISH
SUBLANG_FRENCH_CANADIAN	SUBLANG_SPANISH_MEXICAN
SUBLANG_FRENCH_SWISS	SUBLANG_SPANISH_MODERN
SUBLANG_GERMAN
Return Value

The return value is a language identifier that can be used with the FindResourceEx and EnumResLangProc functions.

Comments

The following two combinations of usPrimaryLanguage and usSubLanguage have special meaning:

Primary language ID	Sublanguage ID	Meaning
LANG_NEUTRAL	SUBLANG_NEUTRAL	Language neutral
LANG_NEUTRAL	SUBLANG_DEFAULT	Process default language
The MAKELANGID macro is defined as follows:

#define MAKELANGID(p, s) ((((USHORT)(s)) << 10) | (USHORT)(p))

See Also

»LANGIDFROMLCID«, »MAKELCID«, »PRIMARYLANGID«, »SUBLANGID«


  MAKELCID

DWORD MAKELCID(wLanguageID)
WORD  wLanguageID;   /* language identifier  */

The MAKELCID macro creates a locale identifier from a language identifier.

Parameters

wLanguageID

Specifies the language identifier. This parameter is a combination of a primary language identifier and a sublanguage identifier and is usually created by using the MAKELANGID macro.

Return Value

The return value is a locale identifier.

Comments

The MAKELCID macro is defined as follows:

#define MAKELCID(lgid) \

    ((DWORD) (((WORD) (lgid)) | (((DWORD) ((WORD) (0))) << 16)))

See Also

»LANGIDFROMLCID«, »MAKELANGID«


  MAKELONG

DWORD MAKELONG(wLow, wHigh)
WORD  wLow;   /* low-order word of long value */
WORD  wHigh;   /* high-order word of long value */

The MAKELONG macro creates an unsigned 32-bit value by concatenating two given 16-bit values.

Parameters

wLow

Specifies the low-order word of the new long value.

wHigh

Specifies the high-order word of the new long value.

Return Value

The return value is an unsigned 32-bit value.

Comments

The MAKELONG macro is defined as follows:

#define MAKELONG(a, b) \

    ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))


  MAKELPARAM

LPARAM MAKELPARAM(wLow, wHigh)
WORD  wLow;   /* low-order word */
WORD  wHigh;   /* high-order word */

The MAKELPARAM macro creates an unsigned 32-bit value for use as an lParam parameter in a message. The macro concatenates two given 16-bit values.

Parameters

wLow

Specifies the low-order word of the new long value.

wHigh

Specifies the high-order word of the new long value.

Return Value

The return value is an unsigned 32-bit value.

Comments

The MAKELPARAM macro is defined as follows:

#define MAKELPARAM(l, h)   ((LPARAM)MAKELONG(l, h))

See Also

»MAKELONG«, »MAKELRESULT«, »MAKEWPARAM«


  MAKELRESULT

LRESULT MAKELRESULT(wLow, wHigh)
WORD  wLow;   /* low-order word */
WORD  wHigh;   /* high-order word */

The MAKELRESULT macro creates an unsigned 32-bit value for use as a return value from a window procedure. The macro concatenates two given 16-bit values.

Parameters

wLow

Specifies the low-order word of the new long value.

wHigh

Specifies the high-order word of the new long value.

Return Value

The return value is an unsigned 32-bit value.

Comments

The MAKELRESULT macro is defined as follows:

#define MAKELRESULT(l, h)  ((LRESULT)MAKELONG(l, h))

See Also

»MAKELONG«, »MAKELPARAM«, »MAKEWPARAM«


  MAKEPOINTS

POINTS MAKEPOINTS(dwValue)
DWORD  dwValue;   /* coordinates of a point */

The MAKEPOINTS macro converts a value that contains the x- and y-coordinates of a point into a POINTS structure.

Parameters

dwValue

Specifies the coordinates of a point. The x-coordinate is in the low-order word, and the y-coordinate is in the high-order word.

Return Value

The return value is a pointer to a POINTS structure.

Comments

The MAKEPOINTS macro is defined as follows:

#define MAKEPOINTS(l)  (*((POINTS FAR *)&(l)))

The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For a full description of this structure, see Chapter 3, »Structures«.

See Also

»GetMessagePos«


  MAKEWORD

WORD MAKEWORD(bLow, bHigh)
BYTE  bLow;   /* low-order byte of short value */
BYTE  bHigh;   /* high-order byte of short value */

The MAKEWORD macro creates an unsigned 16-bit integer by concatenating two given unsigned character values.

Parameters

bLow

Specifies the low-order byte of the new short value.

bHigh

Specifies the high-order byte of the new short value.

Return Value

The return value is an unsigned 16-bit integer value.

Comments

The MAKEWORD macro is defined as follows:

#define MAKEWORD(a, b) \

    ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8))


  MAKEWPARAM

LPARAM MAKEWPARAM(wLow, wHigh)
WORD  wLow;   /* low-order word */
WORD  wHigh;   /* high-order word */

The MAKEWPARAM macro creates an unsigned 32-bit value for use as a wParam parameter in a message. The macro concatenates two given 16-bit values.

Parameters

wLow

Specifies the low-order word of the new long value.

wHigh

Specifies the high-order word of the new long value.

Return Value

The return value is an unsigned 32-bit value.

Comments

The MAKEWPARAM macro is defined as follows:

#define MAKEWPARAM(l, h)   ((LPARAM)MAKELONG(l, h))

See Also

»MAKELONG«, »MAKELPARAM«, »MAKELRESULT«


  max

max(value1, value2)

The max macro compares two values and returns the larger one. The data type can be any numeric data type, signed or unsigned. The data type of the arguments and the return value is the same.

Parameters

value1

Specifies the first of two values.

value2

Specifies the second of two values.

Return Value

The return value is the greater of the two specified values.

Comments

The max macro is defined as follows:

#define max(a, b)  (((a) > (b)) ? (a) : (b))

See Also

»min«


  min

min(value1, value2)

The min macro compares two values and returns the smaller one. The data type can be any numeric data type, signed or unsigned. The data type of the arguments and the return value is the same.

Parameters

value1

Specifies the first of two values.

value2

Specifies the second of two values.

Return Value

The return value is the smaller of the two specified values.

Comments

The min macro is defined as follows:

#define min(a, b)  (((a) < (b)) ? (a) : (b))

See Also

»max«


  PALETTEINDEX

COLORREF PALETTEINDEX(wPaletteIndex)
WORD  wPaletteIndex;   /* index to palette entry  */

The PALETTEINDEX macro accepts an index to a logical-color palette entry and returns a palette-entry specifier consisting of a 32-bit COLORREF value that specifies the color associated with the given index. An application using a logical color palette can pass this specifier, instead of an explicit red, green, blue (RGB) value, to graphics device interface (GDI) functions that expect a color. This allows the function to use the color in the specified palette entry.

Parameters

wPaletteIndex

Specifies an index to the palette entry containing the color to be used for a graphics operation.

Return Value

The return value is a logical-palette index specifier.

Comments

The PALETTEINDEX macro is defined as follows:

#define PALETTEINDEX(i) /

    ((COLORREF)(0x01000000 | (DWORD)(WORD)(i)))

See Also

»PALETTERGB«, »RGB«


  PALETTERGB

COLORREF PALETTERGB(bRed, bGreen, bBlue)
BYTE  bRed;   /* red component of palette-relative RGB */
BYTE  bGreen;   /* green component of palette-relative RGB  */
BYTE  bBlue;   /* blue component of palette-relative RGB  */

The PALETTERGB macro accepts three values that represent the relative intensities of red, green, and blue and returns a palette-relative red, green, blue (RGB) specifier consisting of 2 in the high-order byte and an RGB value in the three low-order bytes. An application using a color palette can pass this specifier, instead of an explicit RGB value, to functions that expect a color.

Parameters

bRed

Specifies the intensity of the red color field.

bGreen

Specifies the intensity of the green color field.

bBlue

Specifies the intensity of the blue color field.

Return Value

The return value is a palette-relative RGB specifier. For output devices that support logical palettes, Windows matches a palette-relative RGB value to the nearest color in the logical palette of the device context as though the application had specified an index to that palette entry. If an output device does not support a system palette, Windows uses the palette-relative RGB as though it were a conventional RGB doubleword returned by the RGB macro.

Comments

The PALETTERGB macro is defined as follows:

#define PALETTERGB(r, g, b)  (0x02000000 | RGB(r,g,b))

See Also

»PALETTEINDEX«, »RGB«


  POINTSTOPOINT

POINTSTOPOINT(pt, pts)
POINT  pt;   /* POINT structure */
POINTS  pts;   /* POINTS structure */

The POINTSTOPOINT macro copies the contents of a POINTS structure into a POINT structure.

Parameters

pt

Specifies the POINT structure to receive the contents of the POINTS structure. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For more information about this structure, see Chapter 3, »Structures«.

pts

Specifies the POINTS structure to copy. The POINTS structure has the following form:

typedef struct tagPOINTS { /* pts */

    SHORT x;

    SHORT y;

} POINTS;

For more information about this structure, see Chapter 3, »Structures«.

Comments

The POINTSTOPOINT macro is defined as follows:

#define POINTSTOPOINT(pt,pts) {(pt).x = (SHORT)LOWORD(pts); \

                               (pt).y = (SHORT)HIWORD(pts);}

See Also

»MAKEPOINTS«, »POINTTOPOINTS«


  POINTTOPOINTS

POINTS POINTTOPOINTS(pt)
POINT  pt;   /* coordinates of a point  */

The POINTTOPOINTS macro converts a POINT structure to a POINTS structure.

Parameters

pt

Specifies the POINT structure to convert. The POINT structure has the following form:

typedef struct tagPOINT { /* pt */

    LONG x;

    LONG y;

} POINT;

For more information about this structure, see Chapter 3, »Structures«.

Return Value

The return value is a POINTS structure.

Comments

The POINTTOPOINTS macro is defined as follows:

#define POINTTOPOINTS(pt) \

    (MAKELONG((short)((pt).x), (short)((pt).y)))

See Also

»MAKEPOINTS«, »POINTSTOPOINT«


  PRIMARYLANGID

BYTE PRIMARYLANGID (usLanguageID)
USHORT  usLanguageID;   /* language identifier */

The PRIMARYLANGID macro extracts a primary language identifier from a language identifier.

Parameters

wLanguageID

Specifies the language identifier. This value is a combination of a primary language identifier and a sublanguage identifier and is usually created by using the MAKELANGID macro.

Return Value

The return value is one of the following primary language identifiers:

LANG_ALBANIAN	LANG_ITALIAN
LANG_ARABIC	LANG_JAPANESE
LANG_BAHASA	LANG_KOREAN
LANG_BULGARIAN	LANG_NEUTRAL
LANG_CATALAN	LANG_NORWEGIAN
LANG_CHINESE	LANG_POLISH
LANG_CZECH	LANG_PORTUGUESE
LANG_DANISH	LANG_RHAETO_ROMAN
LANG_DUTCH	LANG_ROMANIAN
LANG_ENGLISH	LANG_RUSSIAN
LANG_FINNISH	LANG_SERBO_CROATIAN
LANG_FRENCH	LANG_SLOVAK
LANG_GERMAN	LANG_SPANISH
LANG_GREEK	LANG_SWEDISH
LANG_HEBREW	LANG_THAI
LANG_HUNGARIAN	LANG_TURKISH
LANG_ICELANDIC	LANG_URDU
Comments

The PRIMARYLANGID macro is defined as follows:

#define PRIMARYLANGID(lgid)  ((USHORT)(lgid) & 0x3FF)

See Also

»LANGIDFROMLCID«, »MAKELANGID«, »SUBLANGID«


  RGB

COLORREF RGB(bRed, bGreen, bBlue)
BYTE  bRed;   /* red component of color */
BYTE  bGreen;   /* green component of color  */
BYTE  bBlue;   /* blue component of color  */

The RGB macro selects a red, green, blue (RGB) color based on the arguments supplied and the color capabilities of the output device.

Parameters

cRed

Specifies the intensity of the red color.

cGreen

Specifies the intensity of the green color.

cBlue

Specifies the intensity of the blue color.

Return Value

The return value is the resultant RGB color.

Comments

The intensity for each argument is in the range 0 through 255. If all three intensities are zero, the result is black. If all three intensities are 255, the result is white.

For information about using color values in a color palette, see the descriptions of the »PALETTEINDEX« and »PALETTERGB« macros.

The RGB macro is defined as follows:

#define RGB(r, g ,b)  ((DWORD)(((BYTE)(r) | \

    ((WORD)(g) << 8)) | \

    (((DWORD)(BYTE)(b)) << 16)))

See Also

»PALETTEINDEX«, »PALETTERGB«


  SUBLANGID

BYTE SUBLANGID(usLanguageID)
USHORT  usLanguageID;   /* language identifier */

The SUBLANGID macro extracts a sublanguage identifier from a language identifier.

Parameters

usLanguageID

Specifies the language identifier. This value is a combination of a primary language identifier and a sublanguage identifier and is usually created by using the MAKELANGID macro.

Return Value

The return value is one of the following sublanguage identifiers:

SUBLANG_CHINESE_SIMPLIFIED	SUBLANG_GERMAN_SWISS
SUBLANG_CHINESE_TRADITIONAL	SUBLANG_ITALIAN
SUBLANG_DEFAULT	SUBLANG_ITALIAN_SWISS
SUBLANG_DUTCH	SUBLANG_NEUTRAL
SUBLANG_DUTCH_BELGIAN	SUBLANG_NORWEGIAN_BOKMÅL
SUBLANG_ENGLISH_AUS	SUBLANG_NORWEGIAN_NYNORSK
SUBLANG_ENGLISH_CAN	SUBLANG_PORTUGUESE
SUBLANG_ENGLISH_UK	SUBLANG_PORTUGUESE_BRAZILIAN
SUBLANG_ENGLISH_US	SUBLANG_SERBO_CROATIAN_CYRILLIC
SUBLANG_FRENCH	SUBLANG_SERBO_CROATIAN_LATIN
SUBLANG_FRENCH_BELGIAN	SUBLANG_SPANISH
SUBLANG_FRENCH_CANADIAN	SUBLANG_SPANISH_MEXICAN
SUBLANG_FRENCH_SWISS	SUBLANG_SPANISH_MODERN
SUBLANG_GERMAN
Comments

The SUBLANGID macro is defined as follows:

#define SUBLANGID(lgid) ((USHORT)(lgid) >> 10)

See Also

»LANGIDFROMLCID«, »MAKELANGID«, »PRIMARYLANGID«


  TEXT

TEXT(string)
LPTSTR  string;   /* address of ANSI or Unicode string  */

The TEXT macro identifies a string as Unicode™ when the UNICODE compile flag is used or as an ANSI string when UNICODE is not defined.

Parameters

string

Specifies the string to be interpreted as either Unicode or ANSI.

Comments

The TEXT macro is defined as follows:

#define TEXT(quote) L##quote


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!


Dynamic Data Exchange Transactions
  Chapter 5  Dynamic Data Exchange Transactions


  XTYP_ADVDATA

XTYP_ADVDATA

A dynamic data exchange (DDE) client callback function receives the XTYP_ADVDATA transaction after establishing an advise loop with a server. This transaction informs the client that the value of the data item has changed.

Parameters

uFmt

Specifies the format atom of the data sent from the server.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Identifies the item name.

hdata

Identifies the data associated with the topic name and item name pair. This parameter is NULL if the client specified the XTYPF_NODATA flag when it requested the advise loop.

dwData1

Not used.

dwData2

Not used.

Return Value

A DDE callback function should return DDE_FACK if it processes this transaction, DDE_FBUSY if it is too busy to process this transaction, or DDE_FNOTPROCESSED if it rejects this transaction.

Comments

An application must not free the data handle obtained during this transaction. An application must, however, copy the data associated with the data handle if the application must process the data after the callback function returns. An application can use the DdeGetData function to copy the data.

See Also

»DdeClientTransaction«, »DdePostAdvise«


  XTYP_ADVREQ

XTYP_ADVREQ

The system sends the XTYP_ADVREQ transaction to a server after the server calls the DdePostAdvise function. This transaction informs the server that an advise transaction is outstanding on the specified topic name and item name pair and that data corresponding to the topic name and item name pair has changed.

Parameters

uFmt

Specifies the format in which the data should be submitted to the client.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Identifies the item name that has changed.

hdata

Not used.

dwData1

Specifies the count, in the low-order word, of XTYP_ADVREQ transactions that remain to be processed, on the same topic, item, and format name set, within the context of the current call to the DdePostAdvise function. The count is zero if the current XTYP_ADVREQ transaction is the last one. A server can use this count to determine whether to create an HDATA_APPOWNED data handle for the advise data.

The low-order word is set to CADV_LATEACK if the Dynamic Data Exchange Management Library (DDEML) issued the XTYP_ADVREQ transaction because of a late-arriving DDE_ACK message from a client being outrun by the server.

The high-order word is not used.

dwData2

Not used.

Return Value

The server should first call the DdeCreateDataHandle function to create a data handle that identifies the changed data and then return the handle. The server should return NULL if it is unable to complete the transaction.

Comments

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

See Also

»DdeCreateDataHandle«, »DdeInitialize«, »DdePostAdvise«


  XTYP_ADVSTOP

XTYP_ADVSTOP

A dynamic data exchange (DDE) server callback function receives the XTYP_ADVSTOP transaction when a client specifies XTYP_ADVSTOP as the uType parameter of the DdeClientTransaction function. A client uses this transaction to end an advise loop with a server.

Parameters

uFmt

Specifies the data format associated with the advise loop being ended.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Identifies the item name.

hdata

Not used.

dwData1

Not used.

dwData2

Not used.

Comments

This transaction is filtered if the server application specified the CBF_FAIL_ADVISES flag in the DdeInitialize function.

See Also

»DdeClientTransaction«, »DdeInitialize«, »DdePostAdvise«


  XTYP_ADVSTART

XTYP_ADVSTART

A dynamic data exchange (DDE) server callback function receives the XTYP_ADVSTART transaction when a client specifies XTYP_ADVSTART as the uType parameter of the DdeClientTransaction function. A client uses this transaction to establish an advise loop with a server.

Parameters

uFmt

Specifies the data format requested by the client.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Identifies the item name.

hdata

Not used.

dwData1

Not used.

dwData2

Not used.

Return Value

A server callback function should return TRUE to allow an advise loop on the specified topic name and item name pair, or FALSE to deny the advise loop. If the callback function returns TRUE, any subsequent calls to the DdePostAdvise function by the server on the same topic name and item name pair causes the system to send XTYP_ADVREQ transactions to the server.

Comments

If a client requests an advise loop on a topic, item, and format name set for an advise loop that is already established, the Dynamic Data Exchange Management Library (DDEML) does not create a duplicate advise loop but instead alters the advise loop flags (XTYPF_ACKREQ and XTYPF_NODATA) to match the latest request.

This transaction is filtered if the server application specified the CBF_FAIL_ADVISES flag in the DdeInitialize function.

See Also

»DdeClientTransaction«, »DdeInitialize«, »DdePostAdvise«,


  XTYP_CONNECT

XTYP_CONNECT

A dynamic data exchange (DDE) server callback function receives the XTYP_CONNECT transaction when a client specifies a service name that the server supports, and a topic name that is not NULL, in a call to the DdeConnect function.

Parameters

uFmt

Not used.

hconv

Not used.

hsz1

Identifies the topic name.

hsz2

Identifies the service name.

hdata

Not used.

dwData1

Points to a CONVCONTEXT data structure that contains context information for the conversation. If the client is not a Dynamic Data Exchange Management Library (DDEML) application, this parameter is set to 0.

dwData2

Specifies whether the client is the same application instance as the server. If the parameter is 1, the client is the same instance. If the parameter is 0, the client is a different instance.

Return Value

A server callback function should return TRUE to allow the client to establish a conversation on the specified service name and topic name pair, or FALSE to deny the conversation. If the callback function returns TRUE and a conversation is successfully established, the system passes the conversation handle to the server by issuing an XTYP_CONNECT_CONFIRM transaction to the server's callback function (unless the server specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function).

Comments

This transaction is filtered if the server application specified the CBF_FAIL_CONNECTIONS flag in the DdeInitialize function.

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

See Also

»DdeConnect«, »DdeInitialize«


  XTYP_CONNECT_CONFIRM

XTYP_CONNECT_CONFIRM

A dynamic data exchange (DDE) server callback function receives the XTYP_CONNECT_CONFIRM transaction to confirm that a conversation has been established with a client and to provide the server with the conversation handle. The system sends this transaction as a result of a previous XTYP_CONNECT or XTYP_WILDCONNECT transaction.

Parameters

uFmt

Not used.

hconv

Identifies the new conversation.

hsz1

Identifies the topic name on which the conversation has been established.

hsz2

Identifies the service name on which the conversation has been established.

hdata

Not used.

dwData1

Not used.

dwData2

Specifies whether the client is the same application instance as the server. If the parameter is 1, the client is the same instance. If the parameter is 0, the client is a different instance.

Comments

This transaction is filtered if the server application specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function.

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

See Also

»DdeConnect«, »DdeConnectList«, »DdeInitialize«


  XTYP_DISCONNECT

XTYP_DISCONNECT

An application's dynamic data exchange (DDE) callback function receives the XTYP_DISCONNECT transaction when the application's partner in a conversation uses the DdeDisconnect function to terminate the conversation.

Parameters

uFmt

Not used.

hconv

Identifies that the conversation was terminated.

hsz1

Not used.

hsz2

Not used.

hdata

Not used.

dwData1

Not used.

dwData2

Specifies whether the partners in the conversation are the same application instance. If the parameter is 1, the partners are the same instance. If the parameter is 0, the partners are different instances.

Comments

This transaction is filtered if the application specified the CBF_SKIP_DISCONNECTS flag in the DdeInitialize function.

The application can obtain the status of the terminated conversation by calling the DdeQueryConvInfo function while processing this transaction. The conversation handle becomes invalid after the callback function returns.

An application cannot block this transaction type; the CBR_BLOCK return code is ignored.

See Also

»DdeDisconnect«, »DdeQueryConvInfo«


  XTYP_ERROR

XTYP_ERROR

A dynamic data exchange (DDE) callback function receives the XTYP_ERROR transaction when a critical error occurs.

Parameters

uFmt

Not used.

hconv

Identifies the conversation associated with the error. This parameter is NULL if the error is not associated with a conversation.

hsz1

Not used.

hsz2

Not used.

hdata

Not used.

dwData1

Specifies the error code in the low-order word. Currently, only the following error code is supported:

Error Code	Description
DMLERR_LOW_MEMORY	Memory is low — advise, poke, or execute data may be lost, or the system may fail.
dwData2

Not used.

Comments

An application cannot block this transaction type; the CBR_BLOCK return code is ignored. The DDEML attempts to free memory by removing noncritical resources. An application that has blocked conversations should unblock them.


  XTYP_EXECUTE

XTYP_EXECUTE

A dynamic data exchange (DDE) server callback function receives the XTYP_EXECUTE transaction when a client specifies XTYP_EXECUTE as the uType parameter of the DdeClientTransaction function. A client uses this transaction to send a command string to the server.

Parameters

uFmt

Not used.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Not used.

hdata

Identifies the command string.

dwData1

Not used.

dwData2

Not used.

Return Value

A server callback function should return DDE_FACK if it processes this transaction, DDE_FBUSY if it is too busy to process this transaction, or DDE_FNOTPROCESSED if it rejects this transaction.

Comments

This transaction is filtered if the server application specified the CBF_FAIL_EXECUTES flag in the DdeInitialize function.

An application must free the data handle obtained during this transaction. An application must, however, copy the command string associated with the data handle if the application must process the string after the callback function returns. An application can use the DdeGetData function to copy the data.

Because most client applications expect a server application to perform an XTYP_EXECUTE transaction synchonrously, a server should attempt to perform all processing of the XTYP_EXECUTE transaction either from within the DDE callback function or by returning CBR_BLOCK. If the hdata parameter is a command that instructs the server to terminate, the server should do so after processing the XTYP_EXECUTE transaction.

See Also

»DdeClientTransaction«, »DdeInitialize«


  XTYP_MONITOR

XTYP_MONITOR

The dynamic data exchange (DDE) callback function of a DDE debugging application receives the XTYP_MONITOR transaction whenever a DDE event occurs in the system. To receive this transaction, an application must specify the APPCLASS_MONITOR flag when it calls the DdeInitialize function.

Parameters

uFmt

Not used.

hconv

Not used.

hsz1

Not used.

hsz2

Not used.

hdata

Identifies a DDE object that contains information about the DDE event. The application should use the DdeAccessData function to obtain a pointer to the object.

dwData1

Not used.

dwData2

Identifies the DDE event. This parameter may be one of the following values:

Value	Meaning
MF_CALLBACKS	The system sent a transaction to a DDE callback function. The DDE object contains a MONCBSTRUCT structure that provides information about the transaction.
MF_CONV	A DDE conversation was established or terminated. The DDE object contains a MONCONVSTRUCT structure that provides information about the conversation.
MF_ERRORS	A DDE error occurred. The DDE object contains a MONERRSTRUCT structure that provides information about the error.
MF_HSZ_INFO	A DDE application created, freed, or incremented the usage count of a string handle; or a string handle was freed as a result of a call to the DdeUninitialize function. The DDE object contains a MONHSZSTRUCT structure that provides information about the string handle.
MF_LINKS	A DDE application started or stopped an advise loop. The DDE object contains a MONLINKSTRUCT structure that provides information about the advise loop.
MF_POSTMSGS	The system or an application posted a DDE message. The DDE object contains a MONMSGSTRUCT structure that provides information about the message.
MF_SENDMSGS	The system or an application sent a DDE message. The DDE object contains a MONMSGSTRUCT structure that provides information about the message.
Return Value

The callback function should return 0 if it processes this transaction.

See Also

»DdeAccessData«, »DdeInitialize«


  XTYP_POKE

XTYP_POKE

A dynamic data exchange (DDE) server callback function receives the XTYP_POKE transaction when a client specifies XTYP_POKE as the uType parameter of the DdeClientTransaction function. A client uses this transaction to send unsolicited data to the server.

Parameters

uFmt

Specifies the format of the data sent from the server.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Identifies the item name.

hdata

Identifies the data that the client is sending to the server.

dwData1

Not used.

dwData2

Not used.

Return Value

A server callback function should return DDE_FACK if it processes this transaction, DDE_FBUSY if it is too busy to process this transaction, or DDE_FNOTPROCESSED if it rejects this transaction.

Comments

This transaction is filtered if the server application specified the CBF_FAIL_POKES flag in the DdeInitialize function.

See Also

»DdeClientTransaction«, »DdeInitialize«


  XTYP_REGISTER

XTYP_REGISTER

A dynamic data exchange (DDE) callback function receives the XTYP_REGISTER transaction type whenever a Dynamic Data Exchange Library (DDEML) server application uses the DdeNameService function to register a service name, or whenever a non-DDEML application that supports the System topic is started.

Parameters

uFmt

Not used.

hconv

Not used.

hsz1

Identifies the base service name being registered.

hsz2

Identifies the instance-specific service name being registered.

hdata

Not used.

dwData1

Not used.

dwData2

Not used.

Comments

This transaction is filtered if the application specified the CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

A application cannot block this transaction type; the CBR_BLOCK return code is ignored.

An application should use the hsz1 parameter to add the service name to the list of servers available to the user. An application should use the hsz2 parameter to identify which application instance has started.

See Also

»DdeInitialize«, »DdeNameService«


  XTYP_REQUEST

XTYP_REQUEST

A dynamic data exchange (DDE) server callback function receives the XTYP_REQUEST transaction when a client specifies XTYP_REQUEST as the uType parameter of the DdeClientTransaction function. A client uses this transaction to request data from a server.

Parameters

uFmt

Specifies the format in which the server should submit data to the client.

hconv

Identifies the conversation.

hsz1

Identifies the topic name.

hsz2

Identifies the item name.

hdata

Not used.

dwData1

Not used.

dwData2

Not used.

Return Value

The server should call the DdeCreateDataHandle function to create a data handle that identifies the data and then return the handle. The server should return NULL if it is unable to complete the transaction. If the server returns NULL, the client will receive a DDE_FNOTPROCESSED acknowledgment flag.

Comments

This transaction is filtered if the server application specified the CBF_FAIL_REQUESTS flag in the DdeInitialize function.

If responding to this transaction requires lengthy processing, the server can return CBR_BLOCK to suspend future transactions on the current conversation and then process the transaction asynchronously. When the server has finished and the data is ready to pass to the client, the server can call the DdeEnableCallback function to resume the conversation.

See Also

»DdeClientTransaction«, »DdeCreateDataHandle«, »DdeEnableCallback«, »DdeInitialize«


  XTYP_UNREGISTER

XTYP_UNREGISTER

A dynamic data exchange (DDE) callback function receives the XTYP_UNREGISTER transaction whenever a Dynamic Data Exchange Management Library (DDEML) server application uses the DdeNameService function to unregister a service name, or whenever a non-DDEML application that supports the System topic is terminated.

Parameters

uFmt

Not used.

hconv

Not used.

hsz1

Identifies the base service name being unregistered.

hsz2

Identifies the instance-specific service name being unregistered.

hdata

Not used.

dwData1

Not used.

dwData2

Not used.

Comments

This transaction is filtered if the application specified the CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

A application cannot block this transaction type; the CBR_BLOCK return code is ignored.

An application should use the hsz1 parameter to remove the service name from the list of servers available to the user. An application should use the hsz2 parameter to identify which application instance has terminated.

See Also

»DdeInitialize«, »DdeNameService«


  XTYP_WILDCONNECT

XTYP_WILDCONNECT

A dynamic data exchange (DDE) server callback function receives the XTYP_WILDCONNECT transaction when a client specifies a NULL service name, a NULL topic name, or both, in a call to the DdeConnect or DdeWildConnect function. This transaction allows a client to establish a conversation on each of the server's service name and topic name pairs that match the specified service and topic name.

Parameters

uFmt

Not used.

hconv

Not used.

hsz1

Identifies the topic name. If this parameter is NULL, the client is requesting a conversation on all topic names that the server supports.

hsz2

Identifies the service name. If this parameter is NULL, the client is requesting a conversation on all service names that the server supports.

hdata

Not used.

dwData1

Points to a CONVCONTEXT data structure that contains context information for the conversation. If the client is not a Dynamic Data Exchange Management Library (DDEML) application, this parameter is set to 0.

dwData2

Specifies whether the client is the same application instance as the server. If the parameter is 1, the client is same instance. If the parameter is 0, the client is a different instance.

Return Value

The server should return a data handle that identifies an array of HSZPAIR structures. The array should contain one structure for each service name and topic name pair that matches the service name and topic name pair requested by the client. The array must be terminated by a NULL string handle. The system sends the XTYP_CONNECT_CONFIRM transaction to the server to confirm each conversation and to pass the conversation handles to the server. The server will not receive these confirmations if it specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function.

The server should return NULL to refuse the XTYP_WILDCONNECT transaction.

Comments

This transaction is filtered if the server application specified the CBF_FAIL_CONNECTIONS flag in the DdeInitialize function.

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

See Also

»DdeConnect«, »DdeInitialize«


  XTYP_XACT_COMPLETE

XTYP_XACT_COMPLETE

A dynamic data exchange (DDE) client callback function receives the XTYP_XACT_COMPLETE transaction when an asynchronous transaction, initiated by a call to the DdeClientTransaction function, has completed.

Parameters

uFmt

Specifies the format of the data associated with the completed transaction (if applicable), or NULL if no data was exchanged during the transaction.

hconv

Identifies the conversation.

hsz1

Identifies the topic name involved in the completed transaction.

hsz2

Identifies the item name involved in the completed transaction.

hdata

Identifies the data involved in the completed transaction, if applicable. If the transaction was successful but involved no data, this parameter will be TRUE. This parameter will be NULL if the transaction was unsuccessful.

dwData1

Contains the transaction identifier of the completed transaction.

dwData2

Contains any applicable DDE_ status flags in the low word. This provides support for applications dependent on DDE_APPSTATUS bits. It is recommended that applications no longer use these bits — future versions of the Dynamic Data Exchange Management Library (DDEML) may not support them.

Comments

An application must not free the data handle obtained during this transaction. An application must, however, copy the data associated with the data handle if the application must process the data after the callback function returns. An application can use the DdeGetData function to copy the data.

See Also

»DdeClientTransaction«


BLANK PAGE

IMPORTANT: This text will appear on screen, but will not print on a PostScript printer.

This page should be the last one in this file; it was inserted by running the InsertBlankPage macro.

Do not type any additional text on this page!